export let grid = createGrid(10, 10); // Example grid size export let player = { position: { x: 0, y: 0 }, inventory: [], health: 10, power: 10, score: 0, steps: 0, flashing: false }; let targetPosition = { x: 0, y: 0 }; function createGrid(rows, cols) { let grid = []; for (let i = 0; i < rows; i++) { let row = []; for (let j = 0; j < cols; j++) { row.push(null); } grid.push(row); } return grid; } function generateCollectables(grid, numCollectables) { const collectableTypes = ['potion', 'shield', 'battery']; const collectableColors = { 'potion': 'peachpuff', 'shield': 'cornflowerBlue', 'battery': 'gold' }; for (let i = 0; i < numCollectables; i++) { let x, y; do { x = Math.floor(Math.random() * grid.length); y = Math.floor(Math.random() * grid[0].length); } while (x === 0 && y === 0); // Ensure no items at (0,0) const type = collectableTypes[Math.floor(Math.random() * collectableTypes.length)]; grid[x][y] = { type, color: collectableColors[type] }; } } function generateDamagingSpaces(grid, numSpaces) { for (let i = 0; i < numSpaces; i++) { let x, y; do { x = Math.floor(Math.random() * grid.length); y = Math.floor(Math.random() * grid[0].length); } while (x === 0 && y === 0); // Ensure no damaging spaces at (0,0) grid[x][y] = { type: 'damage', color: 'tomato' }; } } function generateTargetBlock(grid) { let x, y; do { x = Math.floor(Math.random() * grid.length); y = Math.floor(Math.random() * grid[0].length); } while (x === 0 && y === 0); // Ensure no target block at (0,0) grid[x][y] = { type: 'target', color: 'lightgreen' }; // Target block represented by 'X' targetPosition = { x, y }; // Store the target block position } export function drawGrid(grid) { const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const cellSize = Math.min(canvas.width / grid.length, canvas.height / grid[0].length); ctx.clearRect(0, 0, canvas.width, canvas.height); grid.forEach((row, x) => { row.forEach((cell, y) => { ctx.strokeStyle = '#2d2d2d'; ctx.strokeRect(x * cellSize, y * cellSize, cellSize, cellSize); if (cell && cell.color) { ctx.fillStyle = cell.color; ctx.fillRect(x * cellSize, y * cellSize, cellSize, cellSize); ctx.fillStyle = '#2d2d2d'; ctx.font = `${cellSize / 2}px Arial`; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; let char = ''; if (cell.type === 'potion') char = 'p'; if (cell.type === 'shield') char = 's'; if (cell.type === 'battery') char = 'b'; if (cell.type === 'damage') char = '!'; if (cell.type === 'target') char = '#'; ctx.fillText(char, x * cellSize + cellSize / 2, y * cellSize + cellSize / 2); } }); }); // Draw player ctx.fillStyle = player.flashing ? 'white' : 'thistle'; ctx.fillRect(player.position.x * cellSize, player.position.y * cellSize, cellSize, cellSize); ctx.fillStyle = '#2d2d2d'; ctx.font = `${cellSize / 2}px Arial`; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillText('@', player.position.x * cellSize + cellSize / 2, player.position.y * cellSize + cellSize / 2); } export function initializeGame() { grid = createGrid(10, 10); // Reset grid generateCollectables(grid, 10); // Adjust the number as needed generateDamagingSpaces(grid, Math.floor(Math.random() * 7) + 1); // Random number of damaging spaces, no more than 7 generateTargetBlock(grid); // Add target block player.position = { x: 0, y: 0 }; // Reset player position player.inventory = []; // Clear inventory player.health = 10; // Reset health player.endurance = 10; // Reset endurance player.steps = 0; // Reset steps resizeCanvas(); drawGrid(grid); updatePlayerStatus(); } export function resizeCanvas() { const canvas = document.getElementById('gameCanvas'); const width = Math.min(window.innerWidth, window.innerHeight) * 0.5; canvas.width = width; canvas.height = width; drawGrid(grid); } export function updatePlayerPosition(newX, newY) { player.position.x = newX; player.position.y = newY; checkForDamageOrTarget(); drawGrid(grid); updatePlayerStatus(); } export function updatePlayerStatus() { document.getElementById('playerPosition').textContent = `Position: (${player.position.x}, ${player.position.y})`; document.getElementById('playerHealth').textContent = `Health: ${player.health}`; document.getElementById('playerPower').textContent = `Power: ${player.power}`; document.getElementById('playerInventory').textContent = `Inventory: [${player.inventory.join(', ')}]`; document.getElementById('playerScore').textContent = `Score: ${player.score}`; } function checkForDamageOrTarget() { const { x, y } = player.position; const cell = grid[x][y]; if (cell && cell.type === 'damage') { const shieldIndex = player.inventory.indexOf('shield'); if (shieldIndex > -1) { player.inventory.splice(shieldIndex, 1); // Use one shield console.log('Used shield to avoid damage'); } else { player.health -= 2; console.log(`Stepped on damaging space, health is now ${player.health}`); if (player.health <= 0) { alertGameOver(); return; } flashPlayer(); } } else if (x === targetPosition.x && y === targetPosition.y) { player.score += 1; console.log(`Reached target block, score is now ${player.score}`); initializeGame(); // Generate new level and reset player position } } export function alertGameOver() { alert('You have lost the game!'); initializeGame(); } function flashPlayer(callback) { player.flashing = true; drawGrid(grid); setTimeout(() => { player.flashing = false; drawGrid(grid); updatePlayerStatus(); if (callback) callback(); }, 250); // Flash duration }