asssi / index.html
XeniusX's picture
Add 2 files
65e2d00 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>GHOSTLY KNIGHT: Cursed Crypts</title>
<link href="https://fonts.googleapis.com/css2?family=MedievalSharp&family=Cinzel+Decorative:wght@700&family=UnifrakturMaguntia&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,[email protected],100..700,0..1,-50..200" />
<!-- Google Play Games Services SDK -->
<script src="https://apis.google.com/js/api:client.js"></script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
touch-action: manipulation;
user-select: none;
-webkit-user-select: none;
}
:root {
--blood-red: #8b0000;
--dark-purple: #3d0066;
--torch-orange: #ff6b35;
--bone-white: #f8f4e3;
--rusty-metal: #8b5a2b;
}
body {
width: 100vw;
height: 100vh;
overflow: hidden;
background: #000;
font-family: 'Cinzel Decorative', cursive;
position: fixed;
color: var(--bone-white);
}
#game-container {
position: fixed;
width: 100%;
height: 100%;
}
/* Loading Screen with Animated Pentagram */
#loading-screen {
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(ellipse at center, #1a0000 0%, #000 100%);
color: var(--torch-orange);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 100;
font-size: 2rem;
text-shadow: 0 0 10px var(--blood-red);
overflow: hidden;
}
.pentagram {
position: absolute;
width: 200px;
height: 200px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><path fill="none" stroke="%23ff0000" stroke-width="2" d="M50,5 L60,40 L95,40 L65,60 L75,95 L50,75 L25,95 L35,60 L5,40 L40,40 Z"/></svg>') no-repeat center center;
background-size: contain;
animation: rotate 10s linear infinite;
filter: drop-shadow(0 0 8px var(--blood-red));
opacity: 0.7;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
#loading-bar-container {
width: 80%;
max-width: 400px;
margin-top: 30px;
background: rgba(0, 0, 0, 0.7);
border: 3px solid var(--blood-red);
border-radius: 10px;
padding: 5px;
box-shadow: 0 0 20px var(--blood-red);
position: relative;
z-index: 2;
}
#loading-bar {
height: 20px;
background: linear-gradient(90deg, #3d0066, #8b0000);
border-radius: 5px;
width: 0%;
transition: width 0.3s;
position: relative;
overflow: hidden;
}
#loading-bar::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(90deg,
rgba(255,255,255,0.1) 0%,
rgba(255,255,255,0.3) 50%,
rgba(255,255,255,0.1) 100%);
animation: shine 2s infinite;
}
@keyframes shine {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}
#loading-text {
margin-top: 20px;
font-size: 1.2rem;
text-align: center;
color: var(--torch-orange);
text-shadow: 1px 1px 3px black;
max-width: 80%;
}
/* Main Menu with Animated Background */
#title-screen {
position: absolute;
width: 100%;
height: 100%;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><pattern id="pattern" x="0" y="0" width="100" height="100" patternUnits="userSpaceOnUse"><image x="0" y="0" width="100" height="100" href="data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'100\' height=\'100\'><rect width=\'100\' height=\'100\' fill=\'%231a0000\'/><path d=\'M20,20 L80,20 L80,80 L20,80 Z\' stroke=\'%238b0000\' stroke-width=\'2\' fill=\'none\'/><circle cx=\'50\' cy=\'50\' r=\'10\' stroke=\'%233d0066\' stroke-width=\'1\' fill=\'none\'/></svg>"/></pattern><rect x="0" y="0" width="100%" height="100%" fill="url(%23pattern)"/><rect x="0" y="0" width="100%" height="100%" fill="rgba(0,0,0,0.7)"/></svg>');
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 50;
opacity: 1;
transition: opacity 1s;
overflow: hidden;
}
.menu-bg-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: radial-gradient(circle at 50% 40%, rgba(139, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.8) 60%);
z-index: 0;
}
.menu-bg-elements {
position: absolute;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
.chains {
position: absolute;
width: 100px;
height: 200px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 40"><path fill="%23663300" d="M10,0 C13,0 15,2 15,5 L15,10 C15,13 17,15 20,15 L20,25 C17,25 15,27 15,30 L15,35 C15,38 13,40 10,40 C7,40 5,38 5,35 L5,30 C5,27 3,25 0,25 L0,15 C3,15 5,13 5,10 L5,5 C5,2 7,0 10,0 Z"/></svg>') repeat-y;
background-size: contain;
opacity: 0.5;
animation: swing 5s infinite alternate;
transform-origin: top center;
}
.bones {
position: absolute;
width: 100px;
height: 50px;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 50"><path fill="%23f8f4e3" d="M10,25 C10,15 20,5 30,5 C40,5 50,15 50,25 C50,35 60,45 70,45 C80,45 90,35 90,25 C90,15 80,5 70,5 C60,5 50,15 50,25 C50,35 40,45 30,45 C20,45 10,35 10,25 Z"/></svg>');
background-size: contain;
background-repeat: no-repeat;
opacity: 0.4;
}
@keyframes swing {
0% { transform: rotate(-5deg); }
100% { transform: rotate(5deg); }
}
#title-container {
position: relative;
z-index: 2;
text-align: center;
width: 90%;
max-width: 600px;
perspective: 1000px;
}
.game-title {
font-family: 'UnifrakturMaguntia', cursive;
font-size: 4.5rem;
color: var(--torch-orange);
text-shadow: 0 0 10px var(--blood-red), 0 0 20px var(--blood-red), 0 0 30px var(--blood-red);
margin-bottom: 10px;
transform-style: preserve-3d;
animation: titleGlow 3s infinite alternate;
letter-spacing: 3px;
}
.game-subtitle {
font-family: 'MedievalSharp', cursive;
font-size: 1.5rem;
color: var(--bone-white);
text-shadow: 2px 2px 4px #000;
margin-bottom: 40px;
letter-spacing: 2px;
}
@keyframes titleGlow {
0% { text-shadow: 0 0 10px var(--blood-red), 0 0 20px var(--blood-red), 0 0 30px var(--blood-red); }
100% { text-shadow: 0 0 15px var(--blood-red), 0 0 30px var(--blood-red), 0 0 45px var(--torch-orange); }
}
.menu-container {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 15px;
z-index: 2;
position: relative;
}
.menu-btn {
background: linear-gradient(to bottom, rgba(139, 0, 0, 0.7), rgba(61, 0, 102, 0.7));
color: var(--bone-white);
border: 2px solid var(--torch-orange);
border-radius: 10px;
padding: 15px 30px;
font-size: 1.3rem;
font-family: 'Cinzel Decorative', cursive;
cursor: pointer;
transition: all 0.3s ease;
width: 80%;
max-width: 300px;
position: relative;
overflow: hidden;
text-shadow: 1px 1px 2px #000;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5), inset 0 1px 1px rgba(255, 255, 255, 0.2);
}
.menu-btn:hover {
background: linear-gradient(to bottom, rgba(139, 0, 0, 0.9), rgba(61, 0, 102, 0.9));
transform: translateY(-3px) scale(1.05);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.6), inset 0 1px 1px rgba(255, 255, 255, 0.2);
color: #fff;
}
.menu-btn:active {
transform: translateY(1px);
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4), inset 0 1px 1px rgba(255, 255, 255, 0.2);
}
.menu-btn::before {
content: '';
position: absolute;
top: 0;
left: -100%;
width: 100%;
height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
transition: 0.5s;
}
.menu-btn:hover::before {
left: 100%;
}
/* Game Screen */
#canvas {
display: block;
width: 100%;
height: 100%;
background: #111;
}
#game-ui {
position: absolute;
top: 10px;
left: 10px;
right: 10px;
display: flex;
justify-content: space-between;
z-index: 10;
color: white;
font-size: 1.2rem;
text-shadow: 2px 2px 4px black;
font-family: 'MedievalSharp', cursive;
}
#controls {
position: absolute;
bottom: 20px;
right: 20px;
display: flex;
flex-direction: column;
gap: 15px;
z-index: 10;
}
.control-btn {
width: 70px;
height: 70px;
background: radial-gradient(circle at center, rgba(139, 0, 0, 0.7) 0%, rgba(61, 0, 102, 0.7) 100%);
border: 2px solid var(--torch-orange);
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
color: var(--bone-white);
font-size: 1.8rem;
cursor: pointer;
user-select: none;
touch-action: manipulation;
position: relative;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5), inset 0 1px 1px rgba(255, 255, 255, 0.2);
transition: all 0.2s;
}
.control-btn:active {
transform: scale(0.95);
background: radial-gradient(circle at center, rgba(139, 0, 0, 0.9) 0%, rgba(61, 0, 102, 0.9) 100%);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3), inset 0 1px 1px rgba(255, 255, 255, 0.1);
}
#joystick-area {
position: absolute;
bottom: 25px;
left: 25px;
width: 150px;
height: 150px;
border-radius: 50%;
background: rgba(0, 0, 0, 0.3);
border: 2px solid var(--rusty-metal);
display: flex;
justify-content: center;
align-items: center;
box-shadow: inset 0 0 15px rgba(0, 0, 0, 0.5);
}
#joystick {
width: 60px;
height: 60px;
background: radial-gradient(circle at center, rgba(139, 0, 0, 0.7) 0%, rgba(61, 0, 102, 0.7) 100%);
border-radius: 50%;
position: relative;
transition: transform 0.1s;
border: 1px solid var(--torch-orange);
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
}
/* Shop UI */
#shop-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.85);
z-index: 30;
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
color: var(--bone-white);
font-family: 'Cinzel Decorative', cursive;
}
#shop-container {
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%"><pattern id="shopPattern" x="0" y="0" width="50" height="50" patternUnits="userSpaceOnUse"><path fill="%231a0000" d="M0,0 L50,0 L50,50 L0,50 Z"/><path stroke="%23440033" stroke-width="1" d="M0,0 L50,50 M50,0 L0,50"/></pattern><rect x="0" y="0" width="100%" height="100%" fill="url(%23shopPattern)"/></svg>');
border: 3px solid var(--rusty-metal);
border-radius: 15px;
padding: 30px;
width: 90%;
max-width: 500px;
max-height: 80vh;
overflow-y: auto;
box-shadow: 0 0 30px var(--blood-red);
position: relative;
}
.shop-header {
text-align: center;
margin-bottom: 30px;
color: var(--torch-orange);
text-shadow: 0 0 5px var(--blood-red);
}
.shop-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
margin-bottom: 15px;
background: linear-gradient(to right, rgba(61, 0, 66, 0.5), rgba(139, 0, 0, 0.5));
border: 1px solid var(--rusty-metal);
border-radius: 8px;
transition: all 0.3s;
}
.shop-item:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
}
.shop-item-info {
flex: 1;
}
.shop-item-name {
font-weight: bold;
font-size: 1.2rem;
margin-bottom: 5px;
color: var(--torch-orange);
}
.shop-item-desc {
font-size: 0.9rem;
color: var(--bone-white);
opacity: 0.8;
font-family: 'MedievalSharp', cursive;
}
.shop-item-price {
font-family: 'MedievalSharp', cursive;
color: gold;
margin-left: 20px;
white-space: nowrap;
}
.buy-btn {
background: linear-gradient(to bottom, #4CAF50, #2E7D32);
border: 1px solid #81C784;
color: white;
padding: 8px 15px;
border-radius: 5px;
cursor: pointer;
font-family: 'Cinzel Decorative', cursive;
transition: all 0.2s;
}
.buy-btn:hover {
background: linear-gradient(to bottom, #66BB6A, #388E3C);
}
.buy-btn:active {
transform: scale(0.95);
}
.material-symbols-outlined {
font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
margin-right: 10px;
color: var(--torch-orange);
}
#close-shop {
position: absolute;
top: 10px;
right: 10px;
background: none;
border: none;
color: var(--torch-orange);
font-size: 1.5rem;
cursor: pointer;
}
/* Pause Menu */
#pause-menu {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.85);
display: none;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 20;
color: white;
}
.pause-title {
font-size: 3.5rem;
color: var(--torch-orange);
text-shadow: 0 0 10px var(--blood-red);
margin-bottom: 40px;
font-family: 'UnifrakturMaguntia', cursive;
}
/* Level Select Screen */
#level-select {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 60;
color: var(--bone-white);
}
.level-select-title {
font-size: 2.5rem;
margin-bottom: 30px;
color: var(--torch-orange);
text-shadow: 0 0 10px var(--blood-red);
}
.levels-container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 15px;
width: 90%;
max-width: 500px;
}
.level-btn {
aspect-ratio: 1;
display: flex;
justify-content: center;
align-items: center;
background: linear-gradient(135deg, rgba(61, 0, 102, 0.7), rgba(139, 0, 0, 0.7));
border: 2px solid var(--rusty-metal);
border-radius: 10px;
color: var(--bone-white);
font-size: 1.5rem;
font-weight: bold;
cursor: pointer;
transition: all 0.3s;
position: relative;
overflow: hidden;
}
.level-btn:hover {
transform: scale(1.05);
box-shadow: 0 0 15px var(--torch-orange);
}
.level-btn.completed {
border: 2px solid gold;
color: gold;
}
.level-btn.locked {
opacity: 0.5;
pointer-events: none;
}
/* Controls Info Screen */
#controls-info {
position: absolute;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
display: none;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 60;
color: var(--bone-white);
text-align: center;
padding: 20px;
}
.controls-info-content {
max-width: 500px;
background: rgba(139, 0, 0, 0.2);
border: 2px solid var(--rusty-metal);
border-radius: 15px;
padding: 30px;
}
/* Responsive Adjustments */
@media (max-width: 768px) {
.game-title {
font-size: 3rem;
}
.game-subtitle {
font-size: 1.2rem;
}
.menu-btn {
font-size: 1.1rem;
padding: 12px 20px;
}
.control-btn {
width: 60px;
height: 60px;
font-size: 1.5rem;
}
#joystick-area {
width: 130px;
height: 130px;
}
#joystick {
width: 55px;
height: 55px;
}
}
@media (min-width: 1200px) {
.game-title {
font-size: 5rem;
}
}
</style>
</head>
<body>
<div id="game-container">
<!-- Loading Screen -->
<div id="loading-screen">
<div class="pentagram"></div>
<h1>GHOSTLY KNIGHT</h1>
<div id="loading-bar-container">
<div id="loading-bar"></div>
</div>
<p id="loading-text">Unraveling the cursed scrolls...</p>
</div>
<!-- Main Menu -->
<div id="title-screen">
<div class="menu-bg-overlay"></div>
<div class="menu-bg-elements">
<div class="chains" style="left: 10%; top: -50px; width: 80px;"></div>
<div class="chains" style="right: 15%; top: -30px; width: 60px; animation-delay: 0.5s;"></div>
<div class="bones" style="left: 5%; bottom: 20%; transform: rotate(-30deg);"></div>
<div class="bones" style="right: 10%; bottom: 15%; transform: rotate(20deg); width: 80px; height: 40px;"></div>
<div class="bones" style="left: 15%; top: 25%; transform: rotate(45deg); width: 70px;"></div>
</div>
<div id="title-container">
<h1 class="game-title">GHOSTLY KNIGHT</h1>
<p class="game-subtitle">Cursed Crypts</p>
<div class="menu-container">
<button class="menu-btn" id="start-btn">BEGIN YOUR QUEST</button>
<button class="menu-btn" id="level-select-btn">ABYSS SELECTION</button>
<button class="menu-btn" id="controls-btn">FORBIDDEN KNOWLEDGE</button>
<button class="menu-btn" id="shop-btn">DEMONIC MARKET</button>
</div>
</div>
</div>
<!-- Game Canvas -->
<canvas id="canvas"></canvas>
<!-- Game UI -->
<div id="game-ui">
<div id="health">
<span class="material-symbols-outlined">favorite</span>
<span id="health-value">5</span>
</div>
<div id="score">
<span class="material-symbols-outlined">stars</span>
<span id="score-value">0</span>
</div>
<div id="level">
<span class="material-symbols-outlined">levels</span>
<span id="level-value">1-1</span>
</div>
</div>
<!-- Controls -->
<div id="joystick-area">
<div id="joystick"></div>
</div>
<div id="controls">
<div class="control-btn" id="jump-btn">
<span class="material-symbols-outlined">arrow_upward</span>
</div>
<div class="control-btn" id="attack-btn">
<span class="material-symbols-outlined">bolt</span>
</div>
</div>
<!-- Boss UI -->
<div id="boss-health" style="display: none;">
<div id="boss-health-fill"></div>
</div>
<div id="boss-name" style="display: none;"></div>
<!-- Pause Menu -->
<div id="pause-menu">
<h1 class="pause-title">PAUSED</h1>
<button class="menu-btn" id="resume-btn">RESUME</button>
<button class="menu-btn" id="restart-btn">RESTART LEVEL</button>
<button class="menu-btn" id="quit-btn">RETURN TO SANCTUARY</button>
</div>
<!-- Level Complete Screen -->
<div id="level-complete" style="display: none;">
<h1>LEVEL COMPLETE!</h1>
<p id="level-score">REAPED SOULS: 0</p>
<p id="level-time">TIME: 0:00</p>
<div id="next-level-container" style="margin-top: 30px;">
<button class="menu-btn" id="next-level-btn">DESCEND DEEPER</button>
<button class="menu-btn" id="return-btn">RETURN TO SANCTUARY</button>
</div>
</div>
<!-- Shop Overlay -->
<div id="shop-overlay">
<div id="shop-container">
<button id="close-shop">
<span class="material-symbols-outlined">close</span>
</button>
<h2 class="shop-header">DEMONIC MARKET</h2>
<div id="shop-items">
<div class="shop-item" data-id="health_potion">
<div class="shop-item-info">
<div class="shop-item-name">Elixir of Vitality</div>
<div class="shop-item-desc">Restores health when consumed</div>
</div>
<div class="shop-item-price">$1.99</div>
<button class="buy-btn">Purchase</button>
</div>
<div class="shop-item" data-id="damage_boost">
<div class="shop-item-info">
<div class="shop-item-name">Potion of Wrath</div>
<div class="shop-item-desc">50% damage boost for 5 minutes</div>
</div>
<div class="shop-item-price">$2.99</div>
<button class="buy-btn">Purchase</button>
</div>
<div class="shop-item" data-id="gold_pack">
<div class="shop-item-info">
<div class="shop-item-name">Soul Gold Cache</div>
<div class="shop-item-desc">5,000 gold pieces to trade</div>
</div>
<div class="shop-item-price">$4.99</div>
<button class="buy-btn">Purchase</button>
</div>
<div class="shop-item" data-id="cosmetic_armor">
<div class="shop-item-info">
<div class="shop-item-name">Phantom Armor Set</div>
<div class="shop-item-desc">Ghostly cosmetic appearance</div>
</div>
<div class="shop-item-price">$3.99</div>
<button class="buy-btn">Purchase</button>
</div>
<div class="shop-item" data-id="premium_bundle">
<div class="shop-item-info">
<div class="shop-item-name">Dark Lord's Bundle</div>
<div class="shop-item-desc">All items + 10,000 gold</div>
</div>
<div class="shop-item-price">$9.99</div>
<button class="buy-btn">Purchase</button>
</div>
</div>
</div>
</div>
<!-- Level Select Screen -->
<div id="level-select">
<h2 class="level-select-title">CHOOSE YOUR DAMNATION</h2>
<div class="levels-container">
<button class="level-btn" data-level="1-1">1-1</button>
<button class="level-btn locked" data-level="1-2">1-2</button>
<button class="level-btn locked" data-level="1-3">1-3</button>
<button class="level-btn locked" data-level="1-4">1-4</button>
<button class="level-btn locked" data-level="1-5">1-5</button>
</div>
<button class="menu-btn" id="back-to-menu" style="margin-top: 30px;">BACK</button>
</div>
<!-- Controls Info Screen -->
<div id="controls-info">
<div class="controls-info-content">
<h2>ARCANE CONTROLS</h2>
<p style="margin: 20px 0;">
<span style="display: inline-block; width: 60px;">LEFT:</span> Move the joystick left
</p>
<p style="margin: 20px 0;">
<span style="display: inline-block; width: 60px;">RIGHT:</span> Move the joystick right
</p>
<p style="margin: 20px 0;">
<span class="material-symbols-outlined" style="display: inline-block; width: 60px; text-align: center;">arrow_upward</span> Jump
</p>
<p style="margin: 20px 0;">
<span class="material-symbols-outlined" style="display: inline-block; width: 60px; text-align: center;">bolt</span> Attack
</p>
<button class="menu-btn" id="back-from-controls" style="margin-top: 30px;">I UNDERSTAND</button>
</div>
</div>
</div>
<script>
// Game State
const gameState = {
currentLevel: '1-1',
score: 0,
completedLevels: ['1-1'],
purchasedItems: [],
coins: 0,
highScores: {},
playerInventory: {
healthPotions: 0,
damageBoosts: 0,
cosmeticArmor: false
}
};
// Initialize Google Play Games Services
function initGooglePlayGames() {
gapi.load('auth2', function() {
gapi.auth2.init({
client_id: 'YOUR_CLIENT_ID.apps.googleusercontent.com'
}).then(() => {
console.log('Google Play Games initialized');
setupInAppPurchases();
});
});
}
// Set up in-app purchases
function setupInAppPurchases() {
const purchases = window.cordova.plugins.billing;
purchases.initialize("YOUR_PLAY_STORE_KEY")
.then(() => {
console.log("Billing initialized");
return purchases.getProducts([
'health_potion',
'damage_boost',
'gold_pack',
'cosmetic_armor',
'premium_bundle'
]);
})
.then(products => {
console.log("Products loaded:", products);
// Update shop with real product info
products.forEach(product => {
const item = document.querySelector(`.shop-item[data-id="${product.id}"]`);
if (item) {
const priceElement = item.querySelector('.shop-item-price');
priceElement.textContent = product.price;
}
});
// Set up purchase handlers
document.querySelectorAll('.buy-btn').forEach(button => {
button.addEventListener('click', () => {
const itemId = button.parentElement.dataset.id;
purchases.purchase(itemId)
.then(purchase => {
console.log("Purchase successful:", purchase);
processPurchase(itemId);
})
.catch(error => {
console.log("Purchase failed:", error);
});
});
});
})
.catch(error => {
console.log("Error initializing billing:", error);
});
}
// Process successful purchases
function processPurchase(itemId) {
switch(itemId) {
case 'health_potion':
gameState.playerInventory.healthPotions += 1;
showToast('Elixir of Vitality added to your inventory');
break;
case 'damage_boost':
gameState.playerInventory.damageBoosts += 1;
showToast('Potion of Wrath added to your inventory');
break;
case 'gold_pack':
gameState.coins += 5000;
showToast('5,000 gold pieces added to your treasury');
break;
case 'cosmetic_armor':
gameState.playerInventory.cosmeticArmor = true;
showToast('Phantom Armor Set equipped');
break;
case 'premium_bundle':
gameState.playerInventory.healthPotions += 1;
gameState.playerInventory.damageBoosts += 1;
gameState.playerInventory.cosmeticArmor = true;
gameState.coins += 10000;
showToast('Dark Lord\'s Bundle contents awarded');
break;
}
// Add to purchased items
if (!gameState.purchasedItems.includes(itemId)) {
gameState.purchasedItems.push(itemId);
}
// Update UI if needed
updateGameUI();
}
// Show toast notification
function showToast(message) {
const toast = document.createElement('div');
toast.textContent = message;
toast.style.position = 'fixed';
toast.style.bottom = '20%';
toast.style.left = '50%';
toast.style.transform = 'translateX(-50%)';
toast.style.backgroundColor = 'rgba(0,0,0,0.7)';
toast.style.color = 'white';
toast.style.padding = '10px 20px';
toast.style.borderRadius = '5px';
toast.style.zIndex = '1000';
document.body.appendChild(toast);
setTimeout(() => {
toast.style.transition = 'opacity 1s';
toast.style.opacity = '0';
setTimeout(() => toast.remove(), 1000);
}, 3000);
}
// Initialize game controls and UI
function initControls() {
// Joystick controls
const joystickArea = document.getElementById('joystick-area');
const joystick = document.getElementById('joystick');
let joystickActive = false;
let joystickStartX, joystickStartY;
let joystickMoveX, joystickMoveY;
const maxDistance = 50;
joystickArea.addEventListener('touchstart', (e) => {
e.preventDefault();
const touch = e.touches[0];
const rect = joystickArea.getBoundingClientRect();
joystickActive = true;
joystickStartX = rect.left + rect.width / 2;
joystickStartY = rect.top + rect.height / 2;
updateJoystickPosition(touch);
});
document.addEventListener('touchmove', (e) => {
if (joystickActive) {
e.preventDefault();
updateJoystickPosition(e.touches[0]);
}
}, { passive: false });
document.addEventListener('touchend', () => {
joystickActive = false;
joystick.style.transform = 'translate(0, 0)';
// Reset movement when joystick is released
// (you'll need to integrate this with your game state)
});
function updateJoystickPosition(touch) {
const moveX = touch.clientX - joystickStartX;
const moveY = touch.clientY - joystickStartY;
const distance = Math.sqrt(moveX * moveX + moveY * moveY);
let angle = Math.atan2(moveY, moveX);
let limitedDistance = Math.min(distance, maxDistance);
let finalX = Math.cos(angle) * limitedDistance;
let finalY = Math.sin(angle) * limitedDistance;
// Update joystick position
joystick.style.transform = `translate(${finalX}px, ${finalY}px)`;
// Determine movement direction (you'll need to integrate this with your game state)
const deadzone = 10;
if (finalX < -deadzone) {
// Moving left
} else if (finalX > deadzone) {
// Moving right
} else {
// Not moving horizontally
}
}
// Jump and attack buttons
document.getElementById('jump-btn').addEventListener('touchstart', () => {
// Set jump state (integrate with your game state)
});
document.getElementById('jump-btn').addEventListener('touchend', () => {
// Reset jump state if needed
});
document.getElementById('attack-btn').addEventListener('touchstart', () => {
// Set attack state (integrate with your game state)
});
}
// Initialize game menu navigation
function initMenuNavigation() {
document.getElementById('start-btn').addEventListener('click', startGame);
document.getElementById('level-select-btn').addEventListener('click', showLevelSelect);
document.getElementById('controls-btn').addEventListener('click', showControlsInfo);
document.getElementById('shop-btn').addEventListener('click', showShop);
document.getElementById('back-to-menu').addEventListener('click', hideLevelSelect);
document.getElementById('back-from-controls').addEventListener('click', hideControlsInfo);
document.getElementById('close-shop').addEventListener('click', hideShop);
// Set up level buttons
document.querySelectorAll('.level-btn').forEach(btn => {
if (!btn.classList.contains('locked')) {
btn.addEventListener('click', () => {
const level = btn.dataset.level;
startGame(level);
});
}
});
}
// Show/hide menu screens
function showLevelSelect() {
document.getElementById('level-select').style.display = 'flex';
document.getElementById('title-screen').style.display = 'none';
// Update level completion status
document.querySelectorAll('.level-btn').forEach(btn => {
if (gameState.completedLevels.includes(btn.dataset.level)) {
btn.classList.add('completed');
}
});
}
function hideLevelSelect() {
document.getElementById('level-select').style.display = 'none';
document.getElementById('title-screen').style.display = 'flex';
}
function showControlsInfo() {
document.getElementById('controls-info').style.display = 'flex';
document.getElementById('title-screen').style.display = 'none';
}
function hideControlsInfo() {
document.getElementById('controls-info').style.display = 'none';
document.getElementById('title-screen').style.display = 'flex';
}
function showShop() {
document.getElementById('shop-overlay').style.display = 'flex';
document.getElementById('title-screen').style.display = 'none';
}
function hideShop() {
document.getElementById('shop-overlay').style.display = 'none';
document.getElementById('title-screen').style.display = 'flex';
}
// Start game
function startGame(level = '1-1') {
// Initialize game state for the level
gameState.currentLevel = level;
// Hide menus and show game
document.getElementById('title-screen').style.display = 'none';
document.getElementById('level-select').style.display = 'none';
// Start game loop (you'll need to implement this)
// gameLoop();
console.log(`Starting level ${level}`);
}
// Initialize everything when DOM is loaded
document.addEventListener('DOMContentLoaded', () => {
// Simulate loading
simulateLoading();
// Initialize controls and menu
initControls();
initMenuNavigation();
// Initialize Google Play Games (you'll need your client ID)
// initGooglePlayGames();
});
// Simulate loading progress
function simulateLoading() {
const loadingBar = document.getElementById('loading-bar');
const loadingText = document.getElementById('loading-text');
const texts = [
"Unraveling the cursed scrolls...",
"Summoning ancient spirits...",
"Lighting torches in the dungeon...",
"Preparing the undead army...",
"Forging demonic armor...",
"Charging magical weapons...",
"Awakening the dark lords...",
"Drawing pentagrams...",
"Reciting forbidden chants..."
];
let progress = 0;
const interval = setInterval(() => {
progress += Math.random() * 10;
if (progress >= 100) {
progress = 100;
clearInterval(interval);
setTimeout(() => {
document.getElementById('loading-screen').style.opacity = '0';
setTimeout(() => {
document.getElementById('loading-screen').style.display = 'none';
document.getElementById('title-screen').style.display = 'flex';
}, 500);
}, 300);
}
loadingBar.style.width = `${progress}%`;
loadingText.textContent = texts[Math.floor(Math.random() * texts.length)];
}, 300);
}
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <a href="https://enzostvs-deepsite.hf.space" style="color: #fff;" target="_blank" >DeepSite</a> <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;"></p></body>
</html>