Use Arrow Keys or WASD to move. Collect all treasures!
(() => { // ... keep all previous constants and variables same ... // New helper to check if diagonal move is permitted without clipping walls function canMoveTo(x, y, fromX, fromY) { if (x < 0 || x >= mapWidth || y < 0 || y >= mapHeight) return false; if (map[y * mapWidth + x] === TILE_WALL) return false; // Prevent diagonal clipping: if moving diagonally, both adjacent tiles must be free if(x !== fromX && y !== fromY){ if(map[fromY * mapWidth + x] === TILE_WALL) return false; if(map[y * mapWidth + fromX] === TILE_WALL) return false; } return true; } // ... keep drawTile, drawMap, drawPlayer and collectTreasure functions same ... function gameLoop() { ctx.clearRect(0, 0, canvas.width, canvas.height); drawMap(); drawPlayer(); if(!player.moving) { let dirX = 0; let dirY = 0; if(keys['arrowup'] || keys['w']) dirY = -1; else if(keys['arrowdown'] || keys['s']) dirY = 1; if(keys['arrowleft'] || keys['a']) dirX = -1; else if(keys['arrowright'] || keys['d']) dirX = 1; const newX = player.x + dirX; const newY = player.y + dirY; // Only attempt move if we have input (including diagonals) if(dirX !== 0 || dirY !== 0) { if(canMoveTo(newX, newY, player.x, player.y)) { player.targetX = newX; player.targetY = newY; player.moving = true; player.moveProgress = 0; } } } else { player.moveProgress += 0.15; if(player.moveProgress >= 1) { player.x = player.targetX; player.y = player.targetY; player.moveProgress = 0; player.moving = false; collectTreasure(player.x, player.y); } } if(treasuresCollected === totalTreasures) { ctx.fillStyle = 'rgba(0,0,0,0.7)'; ctx.fillRect(0, canvas.height/2 - 40, canvas.width, 80); ctx.fillStyle = '#fff'; ctx.font = '36px monospace'; ctx.textAlign = 'center'; ctx.fillText("You collected all treasures!", canvas.width/2, canvas.height/2); } else { ctx.fillStyle = '#eee'; ctx.font = '20px monospace'; ctx.textAlign = 'left'; ctx.fillText(`Treasures: ${treasuresCollected} / ${totalTreasures}`, 10, canvas.height - 10); } requestAnimationFrame(gameLoop); } gameLoop(); })();