diff options
author | elioat <{ID}+{username}@users.noreply.github.com> | 2024-11-01 15:49:20 -0400 |
---|---|---|
committer | elioat <{ID}+{username}@users.noreply.github.com> | 2024-11-01 15:49:20 -0400 |
commit | 3b607e7e3c2364613f6d1f1b41ad4ca16d0c98fb (patch) | |
tree | 5311d0a4c8060c41267495859948ceb850785879 /html/broughlike | |
parent | 32f23188b63c8995f1a5aa6efbc62e5e616250fa (diff) | |
download | tour-3b607e7e3c2364613f6d1f1b41ad4ca16d0c98fb.tar.gz |
*
Diffstat (limited to 'html/broughlike')
-rw-r--r-- | html/broughlike/broughlike.js | 79 | ||||
-rw-r--r-- | html/broughlike/config.js | 2 |
2 files changed, 52 insertions, 29 deletions
diff --git a/html/broughlike/broughlike.js b/html/broughlike/broughlike.js index 2960c95..8933e31 100644 --- a/html/broughlike/broughlike.js +++ b/html/broughlike/broughlike.js @@ -50,7 +50,7 @@ function generateEnemies() { const numEnemies = player.score > 4 ? Math.floor(Math.random() * (CONFIG.MAX_ENEMIES_ON_LEVEL - CONFIG.MIN_ENEMIES_ON_LEVEL + 1)) + CONFIG.MIN_ENEMIES_ON_LEVEL : Math.floor(Math.random() * (CONFIG.MAX_ENEMIES_ON_LEVEL + 1)); - for (let i = 0; i < numEnemies; i++) { + for (let i = 0; i < numEnemies;) { let enemyX, enemyY; do { enemyX = Math.floor(Math.random() * CONFIG.GRID_SIZE); @@ -61,12 +61,15 @@ function generateEnemies() { walls.some(wall => wall.x === enemyX && wall.y === enemyY) || (Math.abs(enemyX - player.x) + Math.abs(enemyY - player.y) < 2) // Ensure enemy is at least 2 spaces away from player ); - enemies.push({ - color: COLORS.enemy, - x: enemyX, - y: enemyY, - health: Math.floor(Math.random() * (CONFIG.MAX_ENEMY_HEALTH - CONFIG.MIN_ENEMY_HEALTH + 1)) + CONFIG.MIN_ENEMY_HEALTH - }); + if (isReachable(player.x, player.y, enemyX, enemyY)) { + enemies.push({ + color: COLORS.enemy, + x: enemyX, + y: enemyY, + health: Math.floor(Math.random() * (CONFIG.MAX_ENEMY_HEALTH - CONFIG.MIN_ENEMY_HEALTH + 1)) + CONFIG.MIN_ENEMY_HEALTH + }); + i++; // Only increment i if the enemy is reachable and actually placed on the board, this avoids levels with fewer enemies than MIN_ENEMIES_ON_LEVEL + } } // Generate a boss enemy every ENEMY_BOSS_OCCURRENCE levels @@ -78,13 +81,15 @@ function generateEnemies() { } while ( (Math.abs(bossX - player.x) + Math.abs(bossY - player.y) < 2) // Ensure boss is at least 2 spaces away from player ); - enemies.push({ - isBoss: true, - color: COLORS.boss, - x: bossX, - y: bossY, - health: CONFIG.MAX_ENEMY_HEALTH + 2 - }); + if (isReachable(player.x, player.y, bossX, bossY)) { + enemies.push({ + isBoss: true, + color: COLORS.boss, + x: bossX, + y: bossY, + health: CONFIG.MAX_ENEMY_HEALTH + 2 + }); + } } } @@ -299,27 +304,43 @@ function generateItems() { 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 }); + if (isReachable(player.x, player.y, itemX, itemY)) + items.push({ x: itemX, y: itemY, type: itemType }); } } -function isPassable() { - const visited = Array(CONFIG.GRID_SIZE).fill().map(() => Array(CONFIG.GRID_SIZE).fill(false)); - +function isReachable(startX, startY, targetX, targetY) { + const visited = Array(CONFIG.GRID_SIZE).fill().map(() => Array(CONFIG.GRID_SIZE).fill(false)); // Initialize a 2D array of false values function dfs(x, y) { if (x < 0 || x >= CONFIG.GRID_SIZE || y < 0 || y >= CONFIG.GRID_SIZE) return false; // Are the coordinates in bounds? - if (visited[x][y]) return false; - if (walls.some(wall => wall.x === x && wall.y === y)) return false; - visited[x][y] = true; - if (x === exit.x && y === exit.y) return true; - return dfs(x + 1, y) || dfs(x - 1, y) || dfs(x, y + 1) || dfs(x, y - 1); + if (visited[x][y]) return false; // Have we already visited this cell? + if (walls.some(wall => wall.x === x && wall.y === y)) return false; // Is there a wall here? + visited[x][y] = true; // Mark this cell as visited + if (x === targetX && y === targetY) return true; // Have we reached the target? + return dfs(x + 1, y) || dfs(x - 1, y) || dfs(x, y + 1) || dfs(x, y - 1); // Recursively check neighbors } + return dfs(startX, startY); +} +// This function is used to check if the player can reach the exit after generating the level +// It is almost the same as isReachable, but it checks for the exit instead of an arbitrary target +// I could defo use isReachable for this, but I...am not doing that right now. +function isPassable() { + const visited = Array(CONFIG.GRID_SIZE).fill().map(() => Array(CONFIG.GRID_SIZE).fill(false)); // Initialize a 2D array of false values + function dfs(x, y) { + if (x < 0 || x >= CONFIG.GRID_SIZE || y < 0 || y >= CONFIG.GRID_SIZE) return false; // Are the coordinates in bounds? + if (visited[x][y]) return false; // Have we already visited this cell? + if (walls.some(wall => wall.x === x && wall.y === y)) return false; // Is there a wall here? + visited[x][y] = true; // Mark this cell as visited + if (x === exit.x && y === exit.y) return true; // Have we reached the exit? + return dfs(x + 1, y) || dfs(x - 1, y) || dfs(x, y + 1) || dfs(x, y - 1); // Recursively check neighbors + } return dfs(player.x, player.y); } function drawGrid() { ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.lineWidth = 2; ctx.strokeStyle = COLORS.grid; for (let row = 0; row < CONFIG.GRID_SIZE; row++) { for (let col = 0; col < CONFIG.GRID_SIZE; col++) { @@ -628,11 +649,13 @@ function handleDamage(player, enemy) { if (enemy.health <= 0) { player.killCount++; - enemies = enemies.filter(e => e !== enemy); + enemies = enemies.filter(e => e !== enemy); if (enemy.isBoss) { // Defeating a boss restores 3 player health player.health = Math.min(player.health + 3, CONFIG.PLAYER_MAX_HEALTH); - console.log("Defeated a boss! Healed " + 3 + " health."); + console.log("Defeated a boss! Healed " + 3 + " health. Player health " + player.health); + } else if (Math.random() < 0.25) { + player.health = Math.min(player.health + 1, CONFIG.PLAYER_MAX_HEALTH); } } @@ -664,9 +687,9 @@ function resetGame() { player.y = 0; combatDots = {}; generateExit(); + generateWalls(); generateEnemies(); generateItems(); - generateWalls(); render(); } @@ -686,9 +709,9 @@ function checkPlayerAtExit() { console.groupEnd(); combatDots = {}; generateExit(); + generateWalls(); generateEnemies(); generateItems(); - generateWalls(); render(); } } @@ -775,7 +798,7 @@ resizeCanvas(); // Initial level setup generateExit(); +generateWalls(); generateEnemies(); generateItems(); -generateWalls(); render(); \ No newline at end of file diff --git a/html/broughlike/config.js b/html/broughlike/config.js index 5897c27..5cf77f4 100644 --- a/html/broughlike/config.js +++ b/html/broughlike/config.js @@ -21,8 +21,8 @@ export const CONFIG = { ENEMY_BOSS_OCCURRENCE: 10, MIN_ENEMIES_ON_LEVEL: 1, MAX_ENEMIES_ON_LEVEL: 4, - MAX_ENEMY_HEALTH: 7, MIN_ENEMY_HEALTH: 2, + MAX_ENEMY_HEALTH: 7, MIN_ROOM_SIZE: 4, WALLS_MIN: 7, WALLS_MAX: 20, |