about summary refs log tree commit diff stats
path: root/html/broughlike/index.html
diff options
context:
space:
mode:
Diffstat (limited to 'html/broughlike/index.html')
-rw-r--r--html/broughlike/index.html133
1 files changed, 92 insertions, 41 deletions
diff --git a/html/broughlike/index.html b/html/broughlike/index.html
index e643527..71cd9d7 100644
--- a/html/broughlike/index.html
+++ b/html/broughlike/index.html
@@ -39,18 +39,18 @@
         };
 
         const GRID_SIZE = 6;
-        const PLAYER_HEALTH = 10;
-        const PLAYER_MAX_HEALTH = 12;
+        const PLAYER_HEALTH = 12;
+        const PLAYER_MAX_HEALTH = 16;
         const PLAYER_BASE_DAMAGE = 1;
         const ENEMY_CHASE_DISTANCE = 4;
-        const MAX_ENEMIES_ON_LEVEL = 4;
+        const MAX_ENEMIES_ON_LEVEL = 3;
         const MAX_ENEMY_HEALTH = 7;
         const MIN_ENEMY_HEALTH = 2;
         const WALLS_MIN = 5;
         const WALLS_MAX = 20;
-        const ITEMS_MIN = 0;
+        const ITEMS_MIN = 1;
         const ITEMS_MAX = 3;
-        const DOTS_PER_HIT = 5;
+        const DOTS_PER_HIT = 7;
 
         const canvas = document.getElementById('gameCanvas');
         const ctx = canvas.getContext('2d');
@@ -121,11 +121,10 @@
                 const wallY = Math.floor(Math.random() * GRID_SIZE);
 
                 if (
-                    (wallX === player.x && wallY === player.y) ||
-                    (wallX === exit.x && wallY === exit.y) ||
-                    enemies.some(enemy => enemy.x === wallX && enemy.y === wallY) ||
-                    (wallX === 0 && wallY === 0) || // Don't block the player spawn
-                    items.some(item => item.x === wallX && item.y === wallY)
+                    (wallX === player.x && wallY === player.y) ||                    // Check that a wall is not placed on the starting position
+                    (wallX === exit.x && wallY === exit.y) ||                        // Check that a wall is not placed on the exit
+                    enemies.some(enemy => enemy.x === wallX && enemy.y === wallY) || // Check that a wall is not placed on any enemies
+                    items.some(item => item.x === wallX && item.y === wallY)         // Check that a wall is not placed on any items
                 ) continue;
 
                 if (!walls.some(wall => wall.x === wallX && wall.y === wallY)) {
@@ -150,7 +149,8 @@
                     (itemX === player.x && itemY === player.y) ||
                     (itemX === exit.x && itemY === exit.y) ||
                     walls.some(wall => wall.x === itemX && wall.y === itemY) ||
-                    enemies.some(enemy => enemy.x === itemX && enemy.y === itemY)
+                    enemies.some(enemy => enemy.x === itemX && enemy.y === itemY) ||
+                    items.some(item => item.x === itemX && item.y === itemY)
                 );
                 const itemType = Math.random() < 0.5 ? 'diamond' : 'pentagon'; // 50% chance for each type
                 items.push({ x: itemX, y: itemY, type: itemType });
@@ -258,6 +258,7 @@
                 drawCharacterBorder(x, y, radius, damageTaken);
             });
         }
+        
 
         function drawPlayer() {
             const x = player.x * tileSize + tileSize / 2;
@@ -313,14 +314,13 @@
             }
         }
 
-        // Function to add dots for damage in combat (including adjacent cells)
         function addCombatDots(x, y, color) {
             const cellsToFill = [
-                [x, y],       // Center
-                [x - 1, y],   // Left
-                [x + 1, y],   // Right
-                [x, y - 1],   // Up
-                [x, y + 1],   // Down
+                [x, y],        // Center
+                [x - 1, y],    // Left
+                [x + 1, y],    // Right
+                [x, y - 1],    // Up
+                [x, y + 1],    // Down
                 [x - 1, y - 1], // Top-left
                 [x + 1, y - 1], // Top-right
                 [x - 1, y + 1], // Bottom-left
@@ -347,44 +347,95 @@
         function movePlayer(dx, dy) {
             const newX = player.x + dx;
             const newY = player.y + dy;
-            if (isValidMove(newX, newY)) {
+            if (isValidMove(newX, newY) && !enemies.some(enemy => enemy.x === newX && enemy.y === newY)) {
+                if (newX !== player.x || newY !== player.y) player.cellsTraveled++;
+                player.x = newX;
+                player.y = newY;
+                handleItemCollection(); // Did the player collect an item?
+                checkPlayerAtExit();    // Did the player get to the exit after moving?
+            } else {
+                // If an enemy is in the target cell, player stays put and does combat
                 const enemyInTargetCell = enemies.find(enemy => enemy.x === newX && enemy.y === newY);
-                if (!enemyInTargetCell) {
-                    if (newX !== player.x || newY !== player.y) player.cellsTraveled++;
-                    player.x = newX;
-                    player.y = newY;
-                    handleItemCollection(); // Check if the player collected an item
-                    checkPlayerAtExit(); // Check if player reached the exit after moving
-                } else {
-                    // Enemy in the target cell, stay in place and do combat
+                if (enemyInTargetCell) {
                     handleDamage(player, enemyInTargetCell);
                 }
             }
             moveEnemies();
             render();
         }
-
-        // Chase logic (naive)
+        
         function moveEnemies() {
             enemies.forEach(enemy => {
-                const distance = Math.abs(enemy.x - player.x) + Math.abs(enemy.y - player.y);
-                if (distance <= ENEMY_CHASE_DISTANCE) {
-                    let dx = 0, dy = 0;
-                    if (enemy.x < player.x && isValidMove(enemy.x + 1, enemy.y)) dx = 1;
-                    else if (enemy.x > player.x && isValidMove(enemy.x - 1, enemy.y)) dx = -1;
-                    else if (enemy.y < player.y && isValidMove(enemy.x, enemy.y + 1)) dy = 1;
-                    else if (enemy.y > player.x && isValidMove(enemy.x, enemy.y - 1)) dy = -1;
-
-                    if (!enemies.some(e => e.x === enemy.x + dx && e.y === enemy.y)) {
-                        enemy.x += dx;
-                        enemy.y += dy;
+                const distanceToPlayer = Math.abs(enemy.x - player.x) + Math.abs(enemy.y - player.y);
+                const distanceToExit = Math.abs(enemy.x - exit.x) + Math.abs(enemy.y - exit.y);
+        
+                const target = distanceToPlayer <= ENEMY_CHASE_DISTANCE ? player : exit;
+                const path = findPath(enemy, target);
+        
+                if (path.length > 1) {
+                    const nextStep = path[1];
+                    const enemyInNextStep = enemies.find(e => e.x === nextStep.x && e.y === nextStep.y);
+        
+                    // Is the next step occupied by an enemy?
+                    if (!enemyInNextStep && !(nextStep.x === player.x && nextStep.y === player.y)) {
+                        // Move to the next place
+                        enemy.x = nextStep.x;
+                        enemy.y = nextStep.y;
+                    } else if (nextStep.x === player.x && nextStep.y === player.y) {
+                        // If the player is in the next step, stay put and do combat
+                        handleDamage(player, enemy);
                     }
                 }
             });
         }
 
+        function findPath(start, goal) {
+            const queue = [{ x: start.x, y: start.y, path: [] }];
+            const visited = new Set();
+            visited.add(`${start.x},${start.y}`);
+
+            while (queue.length > 0) {
+                const { x, y, path } = queue.shift();
+                const newPath = [...path, { x, y }];
+
+                if (x === goal.x && y === goal.y) {
+                    return newPath;
+                }
+
+                const directions = [
+                    { dx: 1, dy: 0 },
+                    { dx: -1, dy: 0 },
+                    { dx: 0, dy: 1 },
+                    { dx: 0, dy: -1 }
+                ];
+
+                directions.forEach(({ dx, dy }) => {
+                    const newX = x + dx;
+                    const newY = y + dy;
+                    const key = `${newX},${newY}`;
+
+                    // Check if the new position is within the level and if it is passable
+                    if (
+                        newX >= 0 && newX < GRID_SIZE &&
+                        newY >= 0 && newY < GRID_SIZE &&
+                        // Have we already been here?
+                        !visited.has(key) &&
+                        // Is it a wall?
+                        !walls.some(wall => wall.x === newX && wall.y === newY) &&
+                        // Is there an enemy already there?
+                        !enemies.some(enemy => enemy.x === newX && enemy.y === newY)
+                    ) {
+                        queue.push({ x: newX, y: newY, path: newPath });
+                        visited.add(key);
+                    }
+                });
+            }
+
+            return [];
+        }
+
         function handleDamage(player, enemy) {
-            const enemyMisses = Math.random() < 0.2; // 1 in 5 chance the enemy misses you
+            const enemyMisses = Math.random() < 0.5; // 50% chance the enemy misses you
             const cellX = player.x;
             const cellY = player.y;
 
@@ -457,10 +508,10 @@
 
         function render() {
             drawGrid();
+            drawPlayer();
             drawExit();
             drawItems();
             drawEnemies();
-            drawPlayer();
             drawWalls();
             drawCombatDots();
         }