a-space / index.html
1234techrules's picture
Add 2 files
cadeb06 verified
<!DOCTYPE html>
<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>