document.addEventListener('DOMContentLoaded', () => { // Game state const gameState = { playerTurn: true, playerPosition: { x: 100, y: 100 }, selectedMove: null, enemies: [ { x: 300, y: 100, speed: 2, direction: 'right' }, { x: 200, y: 200, speed: 1, direction: 'down' } ], swordAngle: 0, swordSpinning: false, swordSpeed: 0, gameLog: [], moveConfirmed: false }; // DOM elements const gameCanvas = document.getElementById('gameCanvas'); const gameLog = document.getElementById('gameLog'); const turnIndicator = document.getElementById('turnIndicator'); // Movement buttons const moveUp = document.getElementById('moveUp'); const moveDown = document.getElementById('moveDown'); const moveLeft = document.getElementById('moveLeft'); const moveRight = document.getElementById('moveRight'); const spinBlade = document.getElementById('spinBlade'); // Initialize game initGame(); function initGame() { renderGame(); setupControls(); logMessage("Game started! Your turn to move."); } function renderGame() { // Clear canvas gameCanvas.innerHTML = ''; // Render player const player = document.createElement('div'); player.className = 'character'; player.style.left = `${gameState.playerPosition.x}px`; player.style.top = `${gameState.playerPosition.y}px`; gameCanvas.appendChild(player); // Render sword const sword = document.createElement('div'); sword.className = 'sword'; sword.style.left = `${gameState.playerPosition.x}px`; sword.style.top = `${gameState.playerPosition.y + 15}px`; sword.style.transform = `rotate(${gameState.swordAngle}deg)`; gameCanvas.appendChild(sword); // Render enemies gameState.enemies.forEach(enemy => { const enemyElement = document.createElement('div'); enemyElement.className = 'enemy'; enemyElement.style.left = `${enemy.x}px`; enemyElement.style.top = `${enemy.y}px`; gameCanvas.appendChild(enemyElement); }); } function setupControls() { moveUp.addEventListener('click', () => selectMove(0, -30)); moveDown.addEventListener('click', () => selectMove(0, 30)); moveLeft.addEventListener('click', () => selectMove(-30, 0)); moveRight.addEventListener('click', () => selectMove(30, 0)); spinBlade.addEventListener('click', () => { if (!gameState.moveConfirmed) { selectMove(0, 0, true); } }); // Add confirm button const confirmButton = document.createElement('button'); confirmButton.id = 'confirmMove'; confirmButton.className = 'btn-action bg-green-600 hover:bg-green-700 col-span-3'; confirmButton.innerHTML = ' Confirm Move'; document.querySelector('.grid.grid-cols-3').appendChild(confirmButton); confirmButton.addEventListener('click', confirmMove); feather.replace(); } function selectMove(dx, dy, isSpin = false) { if (!gameState.playerTurn || gameState.moveConfirmed) return; const newX = gameState.playerPosition.x + dx; const newY = gameState.playerPosition.y + dy; // Boundary check for moves (not needed for spin) if (!isSpin && (newX < 0 || newX > gameCanvas.offsetWidth - 30 || newY < 0 || newY > gameCanvas.offsetHeight - 30)) { logMessage("Can't move there - out of bounds!"); return; } gameState.selectedMove = { dx, dy, isSpin }; logMessage(isSpin ? "Spin blade selected!" : `Move to (${newX}, ${newY}) selected`); } function confirmMove() { if (!gameState.playerTurn || !gameState.selectedMove || gameState.moveConfirmed) return; gameState.moveConfirmed = true; if (gameState.selectedMove.isSpin) { startSpin(); } else { gameState.playerPosition.x += gameState.selectedMove.dx; gameState.playerPosition.y += gameState.selectedMove.dy; renderGame(); endTurn(); } } function movePlayer(dx, dy) { if (!gameState.playerTurn) return; const newX = gameState.playerPosition.x + dx; const newY = gameState.playerPosition.y + dy; // Boundary check if (newX >= 0 && newX <= gameCanvas.offsetWidth - 30 && newY >= 0 && newY <= gameCanvas.offsetHeight - 30) { gameState.playerPosition.x = newX; gameState.playerPosition.y = newY; logMessage(`Moved to (${newX}, ${newY})`); renderGame(); endTurn(); } else { logMessage("Can't move there - out of bounds!"); } } function startSpin() { if (!gameState.playerTurn) return; gameState.swordSpinning = true; gameState.swordSpeed = 10; logMessage("Spinning blade! Enemies beware!"); endTurn(); } function updateSpinning() { if (gameState.swordSpinning) { gameState.swordAngle += gameState.swordSpeed; // Slow down over time gameState.swordSpeed *= 0.98; if (gameState.swordSpeed < 0.5) { gameState.swordSpinning = false; gameState.swordSpeed = 0; } // Check for collisions with enemies checkBladeCollisions(); renderGame(); } } function checkBladeCollisions() { const bladeLength = 40; const bladeX = gameState.playerPosition.x + Math.cos(gameState.swordAngle * Math.PI / 180) * bladeLength; const bladeY = gameState.playerPosition.y + 15 + Math.sin(gameState.swordAngle * Math.PI / 180) * bladeLength; gameState.enemies.forEach((enemy, index) => { const distance = Math.sqrt( Math.pow(bladeX - (enemy.x + 15), 2) + Math.pow(bladeY - (enemy.y + 15), 2) ); if (distance < 20) { // Enemy hit! gameState.enemies.splice(index, 1); logMessage("Enemy defeated by spinning blade!"); } }); } function moveEnemies() { gameState.enemies.forEach(enemy => { switch (enemy.direction) { case 'up': enemy.y = Math.max(0, enemy.y - enemy.speed); if (enemy.y === 0) enemy.direction = 'down'; break; case 'down': enemy.y = Math.min(gameCanvas.offsetHeight - 30, enemy.y + enemy.speed); if (enemy.y === gameCanvas.offsetHeight - 30) enemy.direction = 'up'; break; case 'left': enemy.x = Math.max(0, enemy.x - enemy.speed); if (enemy.x === 0) enemy.direction = 'right'; break; case 'right': enemy.x = Math.min(gameCanvas.offsetWidth - 30, enemy.x + enemy.speed); if (enemy.x === gameCanvas.offsetWidth - 30) enemy.direction = 'left'; break; } }); } function endTurn() { gameState.playerTurn = false; gameState.selectedMove = null; gameState.moveConfirmed = false; turnIndicator.textContent = "Enemy Turn"; turnIndicator.className = "px-3 py-1 bg-red-600 rounded-full"; setTimeout(() => { // Enemy moves moveEnemies(); renderGame(); // Blade keeps spinning if it was activated updateSpinning(); // Return to player turn setTimeout(() => { if (!gameState.swordSpinning) { gameState.playerTurn = true; turnIndicator.textContent = "Player Turn"; turnIndicator.className = "px-3 py-1 bg-blue-600 rounded-full"; logMessage("Your turn! Select a move."); } else { // If blade is still spinning, enemies get another turn endTurn(); } }, 500); }, 1000); } function logMessage(message) { gameState.gameLog.push(message); if (gameState.gameLog.length > 10) gameState.gameLog.shift(); gameLog.innerHTML = gameState.gameLog.map(msg => `
${msg}
` ).join(''); gameLog.scrollTop = gameLog.scrollHeight; } // Game loop for spinning blade setInterval(() => { if (gameState.swordSpinning && !gameState.playerTurn) { updateSpinning(); } }, 16); });