Add minimap

This commit is contained in:
Peter Stockings
2026-01-04 09:53:07 +11:00
parent ad487e766c
commit ff462fb53c

View File

@@ -17,9 +17,31 @@ export class DungeonRenderer {
// State refs
private world!: World;
// Minimap
private minimapGfx!: Phaser.GameObjects.Graphics;
private minimapContainer!: Phaser.GameObjects.Container;
private minimapBg!: Phaser.GameObjects.Graphics;
private minimapScale = 2; // pixels per tile
private minimapPadding = 8;
constructor(scene: Phaser.Scene) {
this.scene = scene;
this.gfx = this.scene.add.graphics();
// Initialize minimap
this.initMinimap();
}
private initMinimap() {
this.minimapContainer = this.scene.add.container(0, 0);
this.minimapContainer.setScrollFactor(0); // Fixed to camera
this.minimapContainer.setDepth(100);
this.minimapBg = this.scene.add.graphics();
this.minimapGfx = this.scene.add.graphics();
this.minimapContainer.add(this.minimapBg);
this.minimapContainer.add(this.minimapGfx);
}
initializeLevel(world: World) {
@@ -32,6 +54,21 @@ export class DungeonRenderer {
if (!inBounds(this.world, x, y)) return false;
return !isWall(this.world, x, y);
});
// Position minimap
this.positionMinimap();
}
private positionMinimap() {
const cam = this.scene.cameras.main;
const minimapWidth = this.world.width * this.minimapScale + this.minimapPadding * 2;
const minimapHeight = this.world.height * this.minimapScale + this.minimapPadding * 2;
// Position in bottom right corner (accounting for zoom)
const x = cam.width / cam.zoom - minimapWidth - 10;
const y = cam.height / cam.zoom - minimapHeight - 10;
this.minimapContainer.setPosition(x, y);
}
computeFov(playerId: EntityId) {
@@ -135,6 +172,90 @@ export class DungeonRenderer {
this.gfx.fillStyle(color, 1);
this.gfx.fillRect(a.pos.x * TILE_SIZE + 4, a.pos.y * TILE_SIZE + 4, TILE_SIZE - 8, TILE_SIZE - 8);
}
// Render minimap
this.renderMinimap();
}
private renderMinimap() {
this.minimapBg.clear();
this.minimapGfx.clear();
if (!this.world) return;
const minimapWidth = this.world.width * this.minimapScale + this.minimapPadding * 2;
const minimapHeight = this.world.height * this.minimapScale + this.minimapPadding * 2;
// Background
this.minimapBg.fillStyle(0x000000, 0.7);
this.minimapBg.fillRect(0, 0, minimapWidth, minimapHeight);
// Border
this.minimapBg.lineStyle(1, 0x666666, 1);
this.minimapBg.strokeRect(0, 0, minimapWidth, minimapHeight);
// Draw only seen tiles
for (let y = 0; y < this.world.height; y++) {
for (let x = 0; x < this.world.width; x++) {
const i = idx(this.world, x, y);
const isSeen = this.seen[i] === 1;
if (!isSeen) continue;
const wall = isWall(this.world, x, y);
const color = wall ? 0x666666 : 0x333333;
this.minimapGfx.fillStyle(color, 1);
this.minimapGfx.fillRect(
this.minimapPadding + x * this.minimapScale,
this.minimapPadding + y * this.minimapScale,
this.minimapScale,
this.minimapScale
);
}
}
// Draw exit if seen
const ex = this.world.exit.x;
const ey = this.world.exit.y;
const exitIdx = idx(this.world, ex, ey);
if (this.seen[exitIdx] === 1) {
this.minimapGfx.fillStyle(0xffd166, 1);
this.minimapGfx.fillRect(
this.minimapPadding + ex * this.minimapScale,
this.minimapPadding + ey * this.minimapScale,
this.minimapScale,
this.minimapScale
);
}
// Draw player
const player = [...this.world.actors.values()].find(a => a.isPlayer);
if (player) {
this.minimapGfx.fillStyle(0x66ff66, 1);
this.minimapGfx.fillRect(
this.minimapPadding + player.pos.x * this.minimapScale,
this.minimapPadding + player.pos.y * this.minimapScale,
this.minimapScale,
this.minimapScale
);
}
// Draw visible enemies
for (const a of this.world.actors.values()) {
if (a.isPlayer) continue;
const i = idx(this.world, a.pos.x, a.pos.y);
const isVis = this.visible[i] === 1;
if (!isVis) continue;
this.minimapGfx.fillStyle(0xff6666, 1);
this.minimapGfx.fillRect(
this.minimapPadding + a.pos.x * this.minimapScale,
this.minimapPadding + a.pos.y * this.minimapScale,
this.minimapScale,
this.minimapScale
);
}
}
showDamage(x: number, y: number, amount: number) {