feat: Add traps

This commit is contained in:
Peter Stockings
2026-01-25 16:37:46 +11:00
parent 18d4f0cdd4
commit 9552364a60
14 changed files with 2225 additions and 11 deletions

View File

@@ -8,6 +8,7 @@ import { FovManager } from "./FovManager";
import { MinimapRenderer } from "./MinimapRenderer";
import { FxRenderer } from "./FxRenderer";
import { ItemSpriteFactory } from "./ItemSpriteFactory";
import { type ECSWorld } from "../engine/ecs/World";
export class DungeonRenderer {
private scene: Phaser.Scene;
@@ -24,6 +25,8 @@ export class DungeonRenderer {
private fxRenderer: FxRenderer;
private world!: World;
private ecsWorld?: ECSWorld;
private trapSprites: Map<number, Phaser.GameObjects.Sprite> = new Map();
constructor(scene: Phaser.Scene) {
this.scene = scene;
@@ -32,10 +35,17 @@ export class DungeonRenderer {
this.fxRenderer = new FxRenderer(scene);
}
initializeFloor(world: World, playerId: EntityId) {
initializeFloor(world: World, playerId: EntityId, ecsWorld?: ECSWorld) {
this.world = world;
this.ecsWorld = ecsWorld;
this.fovManager.initialize(world);
// Clear old trap sprites
for (const [, sprite] of this.trapSprites) {
sprite.destroy();
}
this.trapSprites.clear();
// Setup Tilemap
if (this.map) this.map.destroy();
this.map = this.scene.make.tilemap({
@@ -80,6 +90,26 @@ export class DungeonRenderer {
);
}
}
// Create sprites for ECS trap entities
if (this.ecsWorld) {
const traps = this.ecsWorld.getEntitiesWith("trigger", "position", "sprite");
for (const trapId of traps) {
const pos = this.ecsWorld.getComponent(trapId, "position");
const spriteData = this.ecsWorld.getComponent(trapId, "sprite");
if (pos && spriteData) {
const sprite = this.scene.add.sprite(
pos.x * TILE_SIZE + TILE_SIZE / 2,
pos.y * TILE_SIZE + TILE_SIZE / 2,
spriteData.texture,
spriteData.index
);
sprite.setDepth(5); // Below actors, above floor
sprite.setVisible(false); // Hidden until FOV reveals
this.trapSprites.set(trapId, sprite);
}
}
}
}
@@ -145,6 +175,36 @@ export class DungeonRenderer {
}
});
// Update trap sprites visibility and appearance
if (this.ecsWorld) {
for (const [trapId, sprite] of this.trapSprites) {
const pos = this.ecsWorld.getComponent(trapId, "position");
const spriteData = this.ecsWorld.getComponent(trapId, "sprite");
if (pos && spriteData) {
const i = idx(this.world, pos.x, pos.y);
const isSeen = seen[i] === 1;
const isVis = visible[i] === 1;
sprite.setVisible(isSeen);
// Update sprite frame in case trap was triggered
if (sprite.frame.name !== String(spriteData.index)) {
sprite.setFrame(spriteData.index);
}
// Dim if not currently visible
if (isSeen && !isVis) {
sprite.setAlpha(0.4);
sprite.setTint(0x888888);
} else {
sprite.setAlpha(1);
sprite.clearTint();
}
}
}
}
// Actors (Combatants)
const activeEnemyIds = new Set<EntityId>();
const activeOrbIds = new Set<EntityId>();