diff --git a/src/scenes/GameScene.ts b/src/scenes/GameScene.ts index 530018c..7af88ba 100644 --- a/src/scenes/GameScene.ts +++ b/src/scenes/GameScene.ts @@ -179,18 +179,19 @@ export class GameScene extends Phaser.Scene { const name = `bobj_${building.id}` if (this.children.getByName(name)) continue + const worldDepth = building.tileY + 5 if (building.kind === 'chest') { - const g = this.add.graphics().setName(name).setDepth(8) + const g = this.add.graphics().setName(name).setDepth(worldDepth) g.fillStyle(0x8B4513); g.fillRect(wx - 10, wy - 7, 20, 14) g.fillStyle(0xCD853F); g.fillRect(wx - 9, wy - 6, 18, 6) g.lineStyle(1, 0x5C3317); g.strokeRect(wx - 10, wy - 7, 20, 14) } else if (building.kind === 'bed') { - this.add.image(wx, wy, 'bed_obj').setName(name).setDepth(8) + this.add.image(wx, wy, 'bed_obj').setName(name).setDepth(worldDepth) } else if (building.kind === 'stockpile_zone') { this.add.image(wx, wy, 'stockpile_obj').setName(name).setDepth(4).setAlpha(0.8) } else if (building.kind === 'forester_hut') { // Draw a simple log-cabin silhouette for the forester hut - const g = this.add.graphics().setName(name).setDepth(8) + const g = this.add.graphics().setName(name).setDepth(worldDepth) // Body g.fillStyle(0x6B3F16); g.fillRect(wx - 12, wy - 9, 24, 18) // Roof diff --git a/src/systems/BuildingSystem.ts b/src/systems/BuildingSystem.ts index 3e52d8a..2d7d7d4 100644 --- a/src/systems/BuildingSystem.ts +++ b/src/systems/BuildingSystem.ts @@ -32,7 +32,7 @@ export class BuildingSystem { create(): void { this.ghost = this.scene.add.rectangle(0, 0, TILE_SIZE, TILE_SIZE, 0x00FF00, 0.35) - this.ghost.setDepth(20) + this.ghost.setDepth(1000) this.ghost.setVisible(false) this.ghost.setStrokeStyle(2, 0x00FF00, 0.8) @@ -40,7 +40,7 @@ export class BuildingSystem { fontSize: '10px', color: '#ffffff', fontFamily: 'monospace', backgroundColor: '#000000aa', padding: { x: 3, y: 2 } }) - this.ghostLabel.setDepth(21) + this.ghostLabel.setDepth(1001) this.ghostLabel.setVisible(false) this.ghostLabel.setOrigin(0.5, 1) diff --git a/src/systems/ResourceSystem.ts b/src/systems/ResourceSystem.ts index d490726..f2a7950 100644 --- a/src/systems/ResourceSystem.ts +++ b/src/systems/ResourceSystem.ts @@ -47,10 +47,10 @@ export class ResourceSystem { sprite.setOrigin(0.5, 0.75) } - sprite.setDepth(5) + sprite.setDepth(node.tileY + 5) const healthBar = this.scene.add.graphics() - healthBar.setDepth(6) + healthBar.setDepth(node.tileY + 6) healthBar.setVisible(false) this.sprites.set(node.id, { sprite, node, healthBar }) diff --git a/src/systems/TreeSeedlingSystem.ts b/src/systems/TreeSeedlingSystem.ts index 5167293..9c42121 100644 --- a/src/systems/TreeSeedlingSystem.ts +++ b/src/systems/TreeSeedlingSystem.ts @@ -110,7 +110,7 @@ export class TreeSeedlingSystem { const key = `seedling_${Math.min(s.stage, 2)}` const sprite = this.scene.add.image(x, y, key) .setOrigin(0.5, 0.85) - .setDepth(5) + .setDepth(s.tileY + 5) this.sprites.set(s.id, sprite) } diff --git a/src/systems/VillagerSystem.ts b/src/systems/VillagerSystem.ts index 388331d..7e21b6c 100644 --- a/src/systems/VillagerSystem.ts +++ b/src/systems/VillagerSystem.ts @@ -118,8 +118,9 @@ export class VillagerSystem { case 'sleeping':this.tickSleeping(v, rt, delta); break } - // Sync sprite to state position + // Nisse always render above world objects rt.sprite.setPosition(v.x, v.y) + rt.nameLabel.setPosition(v.x, v.y - 22) rt.energyBar.setPosition(0, 0) this.drawEnergyBar(rt.energyBar, v.x, v.y, v.energy) @@ -569,16 +570,23 @@ export class VillagerSystem { * for a newly added Nisse. * @param v - Villager state to create sprites for */ + /** + * Creates and registers all runtime objects (sprite, outline, label, energy bar, icon) + * for a newly added Nisse. + * @param v - Villager state to create sprites for + */ private spawnSprite(v: VillagerState): void { - const sprite = this.scene.add.image(v.x, v.y, 'villager').setDepth(11) + // Nisse always render above trees, buildings and other world objects. + const sprite = this.scene.add.image(v.x, v.y, 'villager') + .setDepth(900) const nameLabel = this.scene.add.text(v.x, v.y - 22, v.name, { fontSize: '8px', color: '#ffffff', fontFamily: 'monospace', backgroundColor: '#00000088', padding: { x: 2, y: 1 }, - }).setOrigin(0.5, 1).setDepth(12) + }).setOrigin(0.5, 1).setDepth(901) - const energyBar = this.scene.add.graphics().setDepth(12) - const jobIcon = this.scene.add.text(v.x, v.y - 18, '', { fontSize: '10px' }).setDepth(13) + const energyBar = this.scene.add.graphics().setDepth(901) + const jobIcon = this.scene.add.text(v.x, v.y - 18, '', { fontSize: '10px' }).setDepth(902) sprite.setInteractive() sprite.on('pointerdown', () => this.onNisseClick?.(v.id)) @@ -667,6 +675,14 @@ export class VillagerSystem { return result } + /** + * Destroys all Nisse sprites and clears the runtime map. + * Should be called when the scene shuts down. + */ + /** + * Destroys all Nisse sprites and clears the runtime map. + * Should be called when the scene shuts down. + */ /** * Destroys all Nisse sprites and clears the runtime map. * Should be called when the scene shuts down. diff --git a/src/systems/WorldSystem.ts b/src/systems/WorldSystem.ts index 6c33d1b..5de1ca6 100644 --- a/src/systems/WorldSystem.ts +++ b/src/systems/WorldSystem.ts @@ -172,6 +172,16 @@ export class WorldSystem { this.resourceTiles.delete(tileY * WORLD_TILES + tileX) } + /** + * Returns true if a resource (tree or rock) occupies the given tile. + * Uses the O(1) resourceTiles index. + * @param tileX - Tile column + * @param tileY - Tile row + */ + hasResourceAt(tileX: number, tileY: number): boolean { + return this.resourceTiles.has(tileY * WORLD_TILES + tileX) + } + /** * Converts world pixel coordinates to tile coordinates. * @param worldX - World X in pixels