Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Code Battler - Defeat Bugs with Coding Knowledge!</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
@keyframes shake { | |
0%, 100% { transform: translateX(0); } | |
20%, 60% { transform: translateX(-10px); } | |
40%, 80% { transform: translateX(10px); } | |
} | |
.shake { | |
animation: shake 0.5s; | |
} | |
.damage-number { | |
position: absolute; | |
font-weight: bold; | |
color: #ef4444; | |
animation: fadeOut 1s ease-out forwards; | |
pointer-events: none; | |
font-size: 1.5rem; | |
text-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
} | |
@keyframes fadeOut { | |
to { opacity: 0; transform: translateY(-30px); } | |
} | |
.modal { | |
transition: opacity 0.3s ease; | |
} | |
.modal-content { | |
transition: all 0.3s ease; | |
transform: translateY(20px); | |
} | |
.modal.show { | |
opacity: 1; | |
pointer-events: all; | |
} | |
.modal.show .modal-content { | |
transform: translateY(0); | |
} | |
#battle-log { | |
scrollbar-width: thin; | |
scrollbar-color: #c7d2fe #f1f5f9; | |
} | |
#battle-log::-webkit-scrollbar { | |
width: 8px; | |
} | |
#battle-log::-webkit-scrollbar-track { | |
background: #f1f5f9; | |
border-radius: 4px; | |
} | |
#battle-log::-webkit-scrollbar-thumb { | |
background-color: #c7d2fe; | |
border-radius: 4px; | |
} | |
</style> | |
</head> | |
<body class="min-h-screen bg-gray-50 font-sans"> | |
<div class="container mx-auto px-4 py-6 max-w-6xl"> | |
<!-- Header --> | |
<header class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-8 gap-4"> | |
<div class="flex items-center"> | |
<div class="mr-3 bg-indigo-600 text-white p-2 rounded-lg shadow"> | |
<i class="fas fa-gamepad text-xl"></i> | |
</div> | |
<div> | |
<h1 class="text-2xl font-bold text-gray-800">Code Battler</h1> | |
<p class="text-sm text-gray-500">Defeat bugs with your coding knowledge</p> | |
</div> | |
</div> | |
<div class="flex items-center gap-3"> | |
<div class="bg-white rounded-lg px-3 py-1.5 shadow-sm flex items-center border border-gray-100"> | |
<i class="fas fa-coins text-yellow-500 mr-2 text-sm"></i> | |
<span id="coins" class="font-medium">0</span> | |
</div> | |
<div class="bg-white rounded-lg px-3 py-1.5 shadow-sm flex items-center border border-gray-100"> | |
<i class="fas fa-trophy text-indigo-500 mr-2 text-sm"></i> | |
<span id="level" class="font-medium">1</span> | |
</div> | |
</div> | |
</header> | |
<!-- Game Layout --> | |
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6"> | |
<!-- Player Area --> | |
<div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100 flex flex-col items-center"> | |
<h2 class="text-lg font-semibold text-gray-800 mb-4 flex items-center"> | |
<i class="fas fa-user-shield mr-2 text-indigo-500"></i> Your Pet | |
</h2> | |
<div class="mb-4 relative w-40 h-40 bg-indigo-50 rounded-full flex items-center justify-center shadow"> | |
<img id="player-pet-img" src="https://cdn-icons-png.flaticon.com/512/616/616408.png" alt="Pet" class="w-full h-full object-contain"> | |
</div> | |
<div class="w-full mb-4"> | |
<div class="h-2 bg-gray-200 rounded-full w-full"> | |
<div id="player-health" class="h-full rounded-full bg-gradient-to-r from-green-500 to-green-400" style="width: 100%"></div> | |
</div> | |
<div class="flex justify-between text-xs text-gray-500 mt-1"> | |
<span>HP</span> | |
<span id="player-hp-text">15/15</span> | |
</div> | |
</div> | |
<div class="text-center w-full"> | |
<h3 id="pet-name" class="font-semibold text-gray-800">Code Cat</h3> | |
<p id="pet-level" class="text-xs text-gray-500">Level <span class="font-medium">1</span></p> | |
<div class="mt-6 grid grid-cols-2 gap-2 w-full"> | |
<button id="attack-btn" class="bg-red-500 hover:bg-red-600 text-white py-2 px-3 rounded-lg text-sm transition"> | |
<i class="fas fa-bolt mr-1"></i>Attack | |
</button> | |
<button id="heal-btn" class="bg-green-500 hover:bg-green-600 text-white py-2 px-3 rounded-lg text-sm transition"> | |
<i class="fas fa-heart mr-1"></i>Heal | |
</button> | |
<button id="special-btn" class="bg-indigo-500 hover:bg-indigo-600 text-white py-2 px-3 rounded-lg text-sm transition col-span-2"> | |
<i class="fas fa-star mr-1"></i>Special (2 moves) | |
</button> | |
</div> | |
</div> | |
</div> | |
<!-- Battle Log & Question Area --> | |
<div class="flex flex-col gap-4"> | |
<div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100 flex-1"> | |
<h2 class="text-lg font-semibold text-gray-800 mb-3 flex items-center"> | |
<i class="fas fa-scroll mr-2 text-indigo-500"></i> Battle Log | |
</h2> | |
<div id="battle-log" class="h-64 overflow-y-auto bg-gray-50 rounded-lg p-3 space-y-2 text-sm"> | |
<p class="text-gray-500 italic">Welcome to Code Battler! Defeat monsters by answering coding questions correctly.</p> | |
</div> | |
</div> | |
<div id="question-area" class="bg-white p-6 rounded-xl shadow-sm border border-gray-100 hidden"> | |
<h3 class="font-semibold mb-3 text-gray-800 flex items-center"> | |
<i class="fas fa-question-circle mr-2 text-indigo-500"></i> Code Challenge | |
</h3> | |
<p id="question-text" class="mb-4 text-gray-700"></p> | |
<div id="options" class="grid grid-cols-1 gap-2"></div> | |
</div> | |
<div class="flex gap-2"> | |
<button id="learn-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 py-2 px-4 rounded-lg text-sm flex-1 transition"> | |
<i class="fas fa-book mr-1"></i> Learn | |
</button> | |
<button id="shop-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 py-2 px-4 rounded-lg text-sm flex-1 transition"> | |
<i class="fas fa-shopping-cart mr-1"></i> Shop | |
</button> | |
</div> | |
</div> | |
<!-- Enemy Area --> | |
<div class="bg-white p-6 rounded-xl shadow-sm border border-gray-100 flex flex-col items-center"> | |
<h2 class="text-lg font-semibold text-gray-800 mb-4 flex items-center"> | |
<i class="fas fa-bug mr-2 text-red-500"></i> Enemy | |
</h2> | |
<div class="mb-4 relative w-40 h-40 bg-red-50 rounded-full flex items-center justify-center shadow"> | |
<img id="enemy-img" src="https://cdn-icons-png.flaticon.com/512/740/740878.png" alt="Enemy" class="w-full h-full object-contain"> | |
</div> | |
<div class="w-full mb-4"> | |
<div class="h-2 bg-gray-200 rounded-full w-full"> | |
<div id="enemy-health" class="h-full rounded-full bg-gradient-to-r from-green-500 to-green-400" style="width: 100%"></div> | |
</div> | |
<div class="flex justify-between text-xs text-gray-500 mt-1"> | |
<span>HP</span> | |
<span id="enemy-hp-text">15/15</span> | |
</div> | |
</div> | |
<div class="text-center w-full"> | |
<h3 id="enemy-name" class="font-semibold text-gray-800">Bug Monster</h3> | |
<p id="enemy-level" class="text-xs text-gray-500">Level <span class="font-medium">1</span></p> | |
<div class="mt-4 bg-gray-50 rounded-lg p-3 shadow-sm"> | |
<h4 class="font-medium text-xs mb-1 text-gray-700 flex items-center"> | |
<i class="fas fa-eye mr-1 text-indigo-500"></i> Next Move | |
</h4> | |
<p id="enemy-next-move" class="text-xs text-gray-700">Preparing attack...</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Modals --> | |
<div id="shop-modal" class="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal"> | |
<div class="w-full max-w-2xl max-h-[90vh] overflow-auto"> | |
<div class="bg-white rounded-xl shadow-lg modal-content p-6"> | |
<div class="flex justify-between items-center mb-5 pb-3 border-b border-gray-200"> | |
<h2 class="text-xl font-semibold text-gray-800"> | |
<i class="fas fa-paw mr-2 text-indigo-500"></i> Pet Shop | |
</h2> | |
<button id="close-shop" class="text-gray-400 hover:text-gray-600"> | |
<i class="fas fa-times"></i> | |
</button> | |
</div> | |
<div class="grid grid-cols-2 md:grid-cols-3 gap-4" id="shop-pets"> | |
<!-- Pets will be added here --> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div id="game-over-modal" class="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal"> | |
<div class="w-full max-w-sm"> | |
<div class="bg-white rounded-xl shadow-lg p-6 text-center modal-content"> | |
<div class="w-16 h-16 mx-auto mb-4 rounded-full bg-red-100 flex items-center justify-center"> | |
<i class="fas fa-skull-crossbones text-2xl text-red-500"></i> | |
</div> | |
<h2 id="game-over-title" class="text-xl font-semibold text-gray-800 mb-1">Game Over</h2> | |
<p id="game-over-message" class="text-gray-600 mb-5">You were defeated!</p> | |
<button id="restart-btn" class="bg-indigo-500 hover:bg-indigo-600 text-white py-2 px-6 rounded-lg transition"> | |
<i class="fas fa-redo mr-1"></i> Play Again | |
</button> | |
</div> | |
</div> | |
</div> | |
<div id="level-up-modal" class="fixed inset-0 bg-black bg-opacity-30 flex items-center justify-center p-4 z-50 opacity-0 pointer-events-none modal"> | |
<div class="w-full max-w-sm"> | |
<div class="bg-white rounded-xl shadow-lg p-6 text-center modal-content"> | |
<div class="w-16 h-16 mx-auto mb-4 rounded-full bg-indigo-100 flex items-center justify-center"> | |
<i class="fas fa-trophy text-2xl text-indigo-500"></i> | |
</div> | |
<h2 class="text-xl font-semibold text-gray-800 mb-1">Level Up!</h2> | |
<p class="text-gray-600">You've reached level <span id="new-level" class="font-semibold text-indigo-500">2</span>!</p> | |
<div class="flex items-center justify-center my-4"> | |
<i class="fas fa-coins text-yellow-500 mr-2"></i> | |
<span class="font-medium">+50 coins bonus!</span> | |
</div> | |
<button id="continue-btn" class="bg-indigo-500 hover:bg-indigo-600 text-white py-2 px-6 rounded-lg transition"> | |
<i class="fas fa-arrow-right mr-1"></i> Continue | |
</button> | |
</div> | |
</div> | |
</div> | |
<script> | |
// Game State | |
const gameState = { | |
coins: 0, | |
level: 1, | |
currentPet: 'cat', | |
unlockedPets: ['cat'], | |
playerHealth: 15, | |
maxHealth: 15, | |
enemyHealth: 15, | |
attackCount: 0, | |
gameActive: true, | |
enemyNextMove: 'attack', | |
currentEnemy: 0, | |
totalCoinsEarned: 0, | |
pets: { | |
cat: { name: 'Code Cat', image: 'https://cdn-icons-png.flaticon.com/512/616/616408.png', cost: 0 }, | |
dog: { name: 'Debug Dog', image: 'https://cdn-icons-png.flaticon.com/512/616/616430.png', cost: 50, special: "+1 attack damage" }, | |
owl: { name: 'Syntax Owl', image: 'https://cdn-icons-png.flaticon.com/512/3281/3281289.png', cost: 150, special: "+10% heal power" } | |
}, | |
enemies: [ | |
{ name: 'Bug Monster', image: 'https://cdn-icons-png.flaticon.com/512/740/740878.png' }, | |
{ name: 'Glitch Gremlin', image: 'https://cdn-icons-png.flaticon.com/512/2491/2491902.png' }, | |
{ name: 'Error Eel', image: 'https://cdn-icons-png.flaticon.com/512/3069/3069172.png' } | |
], | |
questions: [ | |
{ | |
question: "Which HTML tag is used to link an external CSS file?", | |
options: ["<script>", "<style>", "<link>", "<css>"], | |
answer: 2 | |
}, | |
{ | |
question: "Which CSS property changes the text color?", | |
options: ["text-color", "font-color", "color", "text-style"], | |
answer: 2 | |
}, | |
{ | |
question: "How do you write 'Hello World' in an alert box?", | |
options: ["alertBox('Hello World')", "alert('Hello World')", "msg('Hello World')", "msgBox('Hello World')"], | |
answer: 1 | |
} | |
] | |
}; | |
// DOM Elements | |
const coinsDisplay = document.getElementById('coins'); | |
const levelDisplay = document.getElementById('level'); | |
const playerHealthBar = document.getElementById('player-health'); | |
const enemyHealthBar = document.getElementById('enemy-health'); | |
const playerHpText = document.getElementById('player-hp-text'); | |
const enemyHpText = document.getElementById('enemy-hp-text'); | |
const battleLog = document.getElementById('battle-log'); | |
const attackBtn = document.getElementById('attack-btn'); | |
const healBtn = document.getElementById('heal-btn'); | |
const specialBtn = document.getElementById('special-btn'); | |
const shopBtn = document.getElementById('shop-btn'); | |
const learnBtn = document.getElementById('learn-btn'); | |
const shopModal = document.getElementById('shop-modal'); | |
const closeShopBtn = document.getElementById('close-shop'); | |
const gameOverModal = document.getElementById('game-over-modal'); | |
const restartBtn = document.getElementById('restart-btn'); | |
const levelUpModal = document.getElementById('level-up-modal'); | |
const continueBtn = document.getElementById('continue-btn'); | |
const questionArea = document.getElementById('question-area'); | |
const questionText = document.getElementById('question-text'); | |
const optionsContainer = document.getElementById('options'); | |
const playerPetImg = document.getElementById('player-pet-img'); | |
const petNameDisplay = document.getElementById('pet-name'); | |
const petLevelDisplay = document.getElementById('pet-level'); | |
const enemyImage = document.getElementById('enemy-img'); | |
const enemyNameDisplay = document.getElementById('enemy-name'); | |
const enemyLevelDisplay = document.getElementById('enemy-level'); | |
const enemyNextMoveDisplay = document.getElementById('enemy-next-move'); | |
const newLevelDisplay = document.getElementById('new-level'); | |
const shopPetsContainer = document.getElementById('shop-pets'); | |
// Helper functions | |
function showModal(modal) { | |
modal.classList.add('show'); | |
} | |
function hideModal(modal) { | |
modal.classList.remove('show'); | |
} | |
function addToLog(message, type = 'info') { | |
const colors = { | |
player: 'bg-blue-50 text-blue-800', | |
enemy: 'bg-red-50 text-red-800', | |
info: 'bg-gray-50 text-gray-600' | |
}; | |
const logEntry = document.createElement('div'); | |
logEntry.className = `p-2 rounded ${colors[type]}`; | |
logEntry.textContent = message; | |
battleLog.appendChild(logEntry); | |
battleLog.scrollTop = battleLog.scrollHeight; | |
} | |
function showDamage(element, amount, isHeal = false) { | |
const damageElement = document.createElement('div'); | |
damageElement.className = isHeal ? 'heal-number' : 'damage-number'; | |
damageElement.textContent = (isHeal ? '+' : '-') + amount; | |
damageElement.style.color = isHeal ? '#10b981' : '#ef4444'; | |
element.appendChild(damageElement); | |
setTimeout(() => damageElement.remove(), 1000); | |
} | |
function updateUI() { | |
coinsDisplay.textContent = gameState.coins; | |
levelDisplay.textContent = gameState.level; | |
// Update health bars | |
const playerHealthPercent = (gameState.playerHealth / gameState.maxHealth) * 100; | |
const enemyHealthPercent = (gameState.enemyHealth / 15) * 100; | |
playerHealthBar.style.width = `${playerHealthPercent}%`; | |
enemyHealthBar.style.width = `${enemyHealthPercent}%`; | |
// Update health colors | |
playerHealthBar.className = `h-full rounded-full ${ | |
playerHealthPercent > 70 ? 'bg-gradient-to-r from-green-500 to-green-400' : | |
playerHealthPercent > 30 ? 'bg-gradient-to-r from-yellow-500 to-yellow-400' : | |
'bg-gradient-to-r from-red-500 to-red-400' | |
}`; | |
enemyHealthBar.className = `h-full rounded-full ${ | |
enemyHealthPercent > 70 ? 'bg-gradient-to-r from-green-500 to-green-400' : | |
enemyHealthPercent > 30 ? 'bg-gradient-to-r from-yellow-500 to-yellow-400' : | |
'bg-gradient-to-r from-red-500 to-red-400' | |
}`; | |
playerHpText.textContent = `${gameState.playerHealth}/${gameState.maxHealth}`; | |
enemyHpText.textContent = `${gameState.enemyHealth}/15`; | |
// Update pet info | |
playerPetImg.src = gameState.pets[gameState.currentPet].image; | |
petNameDisplay.textContent = gameState.pets[gameState.currentPet].name; | |
petLevelDisplay.innerHTML = `Level <span class="font-medium">${gameState.level}</span>`; | |
// Update enemy info | |
enemyImage.src = gameState.enemies[gameState.currentEnemy].image; | |
enemyNameDisplay.textContent = gameState.enemies[gameState.currentEnemy].name; | |
enemyLevelDisplay.innerHTML = `Level <span class="font-medium">${gameState.level}</span>`; | |
// Update button states | |
attackBtn.disabled = !gameState.gameActive; | |
healBtn.disabled = !gameState.gameActive; | |
specialBtn.disabled = !gameState.gameActive; | |
} | |
function setEnemy() { | |
const enemy = gameState.enemies[gameState.currentEnemy]; | |
enemyImage.src = enemy.image; | |
enemyNameDisplay.textContent = enemy.name; | |
enemyHealthBar.style.width = '100%'; | |
gameState.enemyHealth = 15; | |
gameState.enemyNextMove = Math.random() > 0.3 ? 'attack' : 'heal'; | |
enemyNextMoveDisplay.textContent = gameState.enemyNextMove === 'attack' ? 'Preparing attack...' : 'Preparing to heal...'; | |
} | |
// Game Actions | |
function playerAttack() { | |
if (!gameState.gameActive) return; | |
let damage = Math.floor(Math.random() * 3) + 2; // 2-4 damage | |
if (gameState.currentPet === 'dog') damage += 1; // Debug Dog bonus | |
gameState.enemyHealth -= damage; | |
if (gameState.enemyHealth < 0) gameState.enemyHealth = 0; | |
enemyImage.parentElement.classList.add('shake'); | |
showDamage(enemyImage.parentElement, damage); | |
addToLog(`Your ${gameState.pets[gameState.currentPet].name} attacks for ${damage} damage!`, 'player'); | |
updateUI(); | |
setTimeout(() => { | |
enemyImage.parentElement.classList.remove('shake'); | |
if (gameState.enemyHealth <= 0) { | |
enemyDefeated(); | |
} else { | |
gameState.attackCount++; | |
if (gameState.attackCount % 2 === 0) { | |
showQuestion(); | |
} else { | |
setTimeout(enemyTurn, 1000); | |
} | |
} | |
}, 500); | |
} | |
function playerHeal() { | |
if (!gameState.gameActive) return; | |
let healAmount = Math.floor(Math.random() * 3) + 2; // 2-4 heal | |
if (gameState.currentPet === 'owl') healAmount = Math.floor(healAmount * 1.1); // Syntax Owl bonus | |
gameState.playerHealth += healAmount; | |
if (gameState.playerHealth > gameState.maxHealth) gameState.playerHealth = gameState.maxHealth; | |
playerPetImg.parentElement.classList.add('shake'); | |
showDamage(playerPetImg.parentElement, healAmount, true); | |
addToLog(`Your ${gameState.pets[gameState.currentPet].name} heals for ${healAmount} health!`, 'player'); | |
updateUI(); | |
setTimeout(() => { | |
playerPetImg.parentElement.classList.remove('shake'); | |
gameState.attackCount++; | |
if (gameState.attackCount % 2 === 0) { | |
showQuestion(); | |
} else { | |
setTimeout(enemyTurn, 1000); | |
} | |
}, 500); | |
} | |
function playerSpecial() { | |
if (!gameState.gameActive) return; | |
let damage = Math.floor(Math.random() * 5) + 3; // 3-7 damage | |
if (gameState.currentPet === 'dog') damage += 1; // Debug Dog bonus | |
gameState.enemyHealth -= damage; | |
if (gameState.enemyHealth < 0) gameState.enemyHealth = 0; | |
enemyImage.parentElement.classList.add('shake'); | |
showDamage(enemyImage.parentElement, damage); | |
addToLog(`Your ${gameState.pets[gameState.currentPet].name} uses SPECIAL for ${damage} damage!`, 'player'); | |
updateUI(); | |
setTimeout(() => { | |
enemyImage.parentElement.classList.remove('shake'); | |
if (gameState.enemyHealth <= 0) { | |
enemyDefeated(); | |
} else { | |
gameState.attackCount += 2; | |
showQuestion(); | |
} | |
}, 500); | |
} | |
function enemyTurn() { | |
if (!gameState.gameActive) return; | |
if (gameState.enemyNextMove === 'attack') { | |
const damage = Math.floor(Math.random() * 3) + 1; // 1-3 damage | |
gameState.playerHealth -= damage; | |
if (gameState.playerHealth < 0) gameState.playerHealth = 0; | |
playerPetImg.parentElement.classList.add('shake'); | |
showDamage(playerPetImg.parentElement, damage); | |
addToLog(`${gameState.enemies[gameState.currentEnemy].name} attacks for ${damage} damage!`, 'enemy'); | |
setTimeout(() => { | |
playerPetImg.parentElement.classList.remove('shake'); | |
if (gameState.playerHealth <= 0) { | |
gameOver(false); | |
} else { | |
gameState.enemyNextMove = Math.random() > 0.3 ? 'attack' : 'heal'; | |
enemyNextMoveDisplay.textContent = gameState.enemyNextMove === 'attack' ? 'Preparing attack...' : 'Preparing to heal...'; | |
updateUI(); | |
} | |
}, 500); | |
} else { | |
const healAmount = Math.floor(Math.random() * 3) + 1; // 1-3 heal | |
gameState.enemyHealth += healAmount; | |
if (gameState.enemyHealth > 15) gameState.enemyHealth = 15; | |
showDamage(enemyImage.parentElement, healAmount, true); | |
addToLog(`${gameState.enemies[gameState.currentEnemy].name} heals for ${healAmount} health!`, 'enemy'); | |
gameState.enemyNextMove = Math.random() > 0.3 ? 'attack' : 'heal'; | |
enemyNextMoveDisplay.textContent = gameState.enemyNextMove === 'attack' ? 'Preparing attack...' : 'Preparing to heal...'; | |
updateUI(); | |
} | |
} | |
function enemyDefeated() { | |
const coinsEarned = Math.floor(Math.random() * 20) + 10 * gameState.level; | |
gameState.coins += coinsEarned; | |
gameState.totalCoinsEarned += coinsEarned; | |
gameState.currentEnemy++; | |
addToLog(`You defeated ${gameState.enemies[gameState.currentEnemy-1].name} and earned ${coinsEarned} coins!`, 'player'); | |
if (gameState.currentEnemy >= gameState.enemies.length) { | |
gameState.currentEnemy = 0; | |
levelUp(); | |
} else { | |
setTimeout(() => { | |
setEnemy(); | |
addToLog(`A wild ${gameState.enemies[gameState.currentEnemy].name} appeared!`, 'enemy'); | |
updateUI(); | |
}, 1500); | |
} | |
updateUI(); | |
} | |
function levelUp() { | |
gameState.level++; | |
const coinsBonus = 50; | |
gameState.coins += coinsBonus; | |
gameState.totalCoinsEarned += coinsBonus; | |
gameState.maxHealth += 5; | |
gameState.playerHealth = gameState.maxHealth; | |
newLevelDisplay.textContent = gameState.level; | |
showModal(levelUpModal); | |
gameState.gameActive = false; | |
updateUI(); | |
} | |
function gameOver(won) { | |
gameState.gameActive = false; | |
showModal(gameOverModal); | |
} | |
function showQuestion() { | |
const randomQuestion = gameState.questions[Math.floor(Math.random() * gameState.questions.length)]; | |
questionText.textContent = randomQuestion.question; | |
optionsContainer.innerHTML = ''; | |
randomQuestion.options.forEach((option, index) => { | |
const button = document.createElement('button'); | |
button.textContent = option; | |
button.className = 'bg-gray-100 hover:bg-gray-200 text-gray-700 py-2 px-3 rounded text-left transition question-option'; | |
button.onclick = () => checkAnswer(index, randomQuestion.answer); | |
optionsContainer.appendChild(button); | |
}); | |
questionArea.classList.remove('hidden'); | |
gameState.gameActive = false; | |
} | |
function checkAnswer(selectedIndex, correctIndex) { | |
const options = document.querySelectorAll('.question-option'); | |
options.forEach(option => option.disabled = true); | |
options[correctIndex].classList.add('bg-green-500', 'text-white', 'hover:bg-green-500'); | |
if (selectedIndex !== correctIndex) { | |
options[selectedIndex].classList.add('bg-red-500', 'text-white', 'hover:bg-red-500'); | |
} | |
if (selectedIndex === correctIndex) { | |
addToLog("Correct answer! Your knowledge strengthens your pet!", 'player'); | |
setTimeout(() => { | |
questionArea.classList.add('hidden'); | |
gameState.gameActive = true; | |
setTimeout(enemyTurn, 1000); | |
}, 1500); | |
} else { | |
addToLog("Wrong answer! The enemy gets an extra turn!", 'enemy'); | |
setTimeout(() => { | |
questionArea.classList.add('hidden'); | |
gameState.gameActive = true; | |
setTimeout(() => { | |
enemyTurn(); | |
setTimeout(enemyTurn, 1000); | |
}, 1000); | |
}, 1500); | |
} | |
} | |
function renderShop() { | |
shopPetsContainer.innerHTML = ''; | |
Object.entries(gameState.pets).forEach(([petType, pet]) => { | |
const isUnlocked = gameState.unlockedPets.includes(petType); | |
const isSelected = gameState.currentPet === petType; | |
const petCard = document.createElement('div'); | |
petCard.className = 'bg-white p-4 rounded-lg border border-gray-100 flex flex-col items-center'; | |
petCard.innerHTML = ` | |
<div class="relative w-20 h-20 mb-3"> | |
<img src="${pet.image}" alt="${pet.name}" class="w-full h-full object-contain ${isUnlocked ? '' : 'opacity-50 grayscale'}"> | |
</div> | |
<h3 class="font-semibold text-sm text-center">${pet.name}</h3> | |
${pet.special ? `<p class="text-xs text-center text-gray-600 mt-1">${pet.special}</p>` : ''} | |
<div class="mt-3 text-xs font-medium ${isUnlocked ? 'text-indigo-600' : 'text-gray-500'}"> | |
${isUnlocked ? (isSelected ? '✓ Selected' : 'Unlocked') : `${pet.cost} coins`} | |
</div> | |
<button class="mt-3 w-full py-1 rounded text-sm ${isUnlocked | |
? (isSelected ? 'bg-gray-200 text-gray-500' : 'bg-indigo-500 hover:bg-indigo-600 text-white') | |
: (gameState.coins >= pet.cost ? 'bg-indigo-500 hover:bg-indigo-600 text-white' : 'bg-gray-200 text-gray-500')}" | |
${isUnlocked ? '' : (gameState.coins >= pet.cost ? '' : 'disabled')} | |
data-pet="${petType}"> | |
${isUnlocked ? (isSelected ? 'Selected' : 'Select') : 'Buy'} | |
</button> | |
`; | |
shopPetsContainer.appendChild(petCard); | |
}); | |
} | |
function resetGame() { | |
gameState.coins = 0; | |
gameState.level = 1; | |
gameState.currentPet = 'cat'; | |
gameState.unlockedPets = ['cat']; | |
gameState.playerHealth = 15; | |
gameState.maxHealth = 15; | |
gameState.enemyHealth = 15; | |
gameState.attackCount = 0; | |
gameState.gameActive = true; | |
gameState.currentEnemy = 0; | |
gameState.totalCoinsEarned = 0; | |
questionArea.classList.add('hidden'); | |
hideModal(gameOverModal); | |
hideModal(levelUpModal); | |
hideModal(shopModal); | |
battleLog.innerHTML = '<p class="text-gray-500 italic p-2 rounded bg-gray-50">Welcome to Code Battler! Defeat monsters by answering coding questions correctly.</p>'; | |
setEnemy(); | |
updateUI(); | |
addToLog(`A wild ${gameState.enemies[gameState.currentEnemy].name} appeared!`, 'enemy'); | |
} | |
// Event Listeners | |
attackBtn.addEventListener('click', playerAttack); | |
healBtn.addEventListener('click', playerHeal); | |
specialBtn.addEventListener('click', playerSpecial); | |
shopBtn.addEventListener('click', () => { | |
renderShop(); | |
showModal(shopModal); | |
gameState.gameActive = false; | |
}); | |
learnBtn.addEventListener('click', () => { | |
// Learn mode would go here | |
alert("Learn mode would be implemented here"); | |
}); | |
closeShopBtn.addEventListener('click', () => { | |
hideModal(shopModal); | |
gameState.gameActive = true; | |
}); | |
restartBtn.addEventListener('click', resetGame); | |
continueBtn.addEventListener('click', () => { | |
hideModal(levelUpModal); | |
gameState.gameActive = true; | |
setEnemy(); | |
addToLog(`A wild ${gameState.enemies[gameState.currentEnemy].name} appeared!`, 'enemy'); | |
updateUI(); | |
}); | |
// Shop pet selection | |
shopPetsContainer.addEventListener('click', (e) => { | |
const petBtn = e.target.closest('button'); | |
if (!petBtn) return; | |
const petType = petBtn.dataset.pet; | |
const pet = gameState.pets[petType]; | |
if (!gameState.unlockedPets.includes(petType)) { | |
if (gameState.coins >= pet.cost) { | |
gameState.coins -= pet.cost; | |
gameState.unlockedPets.push(petType); | |
addToLog(`You unlocked the ${pet.name}!`, 'info'); | |
renderShop(); | |
updateUI(); | |
} | |
} else if (gameState.currentPet !== petType) { | |
gameState.currentPet = petType; | |
addToLog(`You selected the ${pet.name}!`, 'info'); | |
renderShop(); | |
updateUI(); | |
} | |
}); | |
// Initialize the game | |
setEnemy(); | |
updateUI(); | |
addToLog(`A wild ${gameState.enemies[gameState.currentEnemy].name} appeared!`, 'enemy'); | |
</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 <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - <a href="https://enzostvs-deepsite.hf.space?remix=1234techrules/a-space" style="color: #fff;text-decoration: underline;" target="_blank" >🧬 Remix</a></p></body> | |
</html> |