Merge pull request 'Fix Y-based depth sorting for world objects' (#32) from feature/depth-sorting into master
Reviewed-on: #32 Reviewed-by: tekki <tekki.mariani@googlemail.com>
This commit is contained in:
@@ -179,18 +179,19 @@ export class GameScene extends Phaser.Scene {
|
|||||||
const name = `bobj_${building.id}`
|
const name = `bobj_${building.id}`
|
||||||
if (this.children.getByName(name)) continue
|
if (this.children.getByName(name)) continue
|
||||||
|
|
||||||
|
const worldDepth = building.tileY + 5
|
||||||
if (building.kind === 'chest') {
|
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(0x8B4513); g.fillRect(wx - 10, wy - 7, 20, 14)
|
||||||
g.fillStyle(0xCD853F); g.fillRect(wx - 9, wy - 6, 18, 6)
|
g.fillStyle(0xCD853F); g.fillRect(wx - 9, wy - 6, 18, 6)
|
||||||
g.lineStyle(1, 0x5C3317); g.strokeRect(wx - 10, wy - 7, 20, 14)
|
g.lineStyle(1, 0x5C3317); g.strokeRect(wx - 10, wy - 7, 20, 14)
|
||||||
} else if (building.kind === 'bed') {
|
} 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') {
|
} else if (building.kind === 'stockpile_zone') {
|
||||||
this.add.image(wx, wy, 'stockpile_obj').setName(name).setDepth(4).setAlpha(0.8)
|
this.add.image(wx, wy, 'stockpile_obj').setName(name).setDepth(4).setAlpha(0.8)
|
||||||
} else if (building.kind === 'forester_hut') {
|
} else if (building.kind === 'forester_hut') {
|
||||||
// Draw a simple log-cabin silhouette for the 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
|
// Body
|
||||||
g.fillStyle(0x6B3F16); g.fillRect(wx - 12, wy - 9, 24, 18)
|
g.fillStyle(0x6B3F16); g.fillRect(wx - 12, wy - 9, 24, 18)
|
||||||
// Roof
|
// Roof
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ export class BuildingSystem {
|
|||||||
|
|
||||||
create(): void {
|
create(): void {
|
||||||
this.ghost = this.scene.add.rectangle(0, 0, TILE_SIZE, TILE_SIZE, 0x00FF00, 0.35)
|
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.setVisible(false)
|
||||||
this.ghost.setStrokeStyle(2, 0x00FF00, 0.8)
|
this.ghost.setStrokeStyle(2, 0x00FF00, 0.8)
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ export class BuildingSystem {
|
|||||||
fontSize: '10px', color: '#ffffff', fontFamily: 'monospace',
|
fontSize: '10px', color: '#ffffff', fontFamily: 'monospace',
|
||||||
backgroundColor: '#000000aa', padding: { x: 3, y: 2 }
|
backgroundColor: '#000000aa', padding: { x: 3, y: 2 }
|
||||||
})
|
})
|
||||||
this.ghostLabel.setDepth(21)
|
this.ghostLabel.setDepth(1001)
|
||||||
this.ghostLabel.setVisible(false)
|
this.ghostLabel.setVisible(false)
|
||||||
this.ghostLabel.setOrigin(0.5, 1)
|
this.ghostLabel.setOrigin(0.5, 1)
|
||||||
|
|
||||||
|
|||||||
@@ -47,10 +47,10 @@ export class ResourceSystem {
|
|||||||
sprite.setOrigin(0.5, 0.75)
|
sprite.setOrigin(0.5, 0.75)
|
||||||
}
|
}
|
||||||
|
|
||||||
sprite.setDepth(5)
|
sprite.setDepth(node.tileY + 5)
|
||||||
|
|
||||||
const healthBar = this.scene.add.graphics()
|
const healthBar = this.scene.add.graphics()
|
||||||
healthBar.setDepth(6)
|
healthBar.setDepth(node.tileY + 6)
|
||||||
healthBar.setVisible(false)
|
healthBar.setVisible(false)
|
||||||
|
|
||||||
this.sprites.set(node.id, { sprite, node, healthBar })
|
this.sprites.set(node.id, { sprite, node, healthBar })
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ export class TreeSeedlingSystem {
|
|||||||
const key = `seedling_${Math.min(s.stage, 2)}`
|
const key = `seedling_${Math.min(s.stage, 2)}`
|
||||||
const sprite = this.scene.add.image(x, y, key)
|
const sprite = this.scene.add.image(x, y, key)
|
||||||
.setOrigin(0.5, 0.85)
|
.setOrigin(0.5, 0.85)
|
||||||
.setDepth(5)
|
.setDepth(s.tileY + 5)
|
||||||
this.sprites.set(s.id, sprite)
|
this.sprites.set(s.id, sprite)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,8 +118,9 @@ export class VillagerSystem {
|
|||||||
case 'sleeping':this.tickSleeping(v, rt, delta); break
|
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.sprite.setPosition(v.x, v.y)
|
||||||
|
|
||||||
rt.nameLabel.setPosition(v.x, v.y - 22)
|
rt.nameLabel.setPosition(v.x, v.y - 22)
|
||||||
rt.energyBar.setPosition(0, 0)
|
rt.energyBar.setPosition(0, 0)
|
||||||
this.drawEnergyBar(rt.energyBar, v.x, v.y, v.energy)
|
this.drawEnergyBar(rt.energyBar, v.x, v.y, v.energy)
|
||||||
@@ -569,16 +570,23 @@ export class VillagerSystem {
|
|||||||
* for a newly added Nisse.
|
* for a newly added Nisse.
|
||||||
* @param v - Villager state to create sprites for
|
* @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 {
|
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, {
|
const nameLabel = this.scene.add.text(v.x, v.y - 22, v.name, {
|
||||||
fontSize: '8px', color: '#ffffff', fontFamily: 'monospace',
|
fontSize: '8px', color: '#ffffff', fontFamily: 'monospace',
|
||||||
backgroundColor: '#00000088', padding: { x: 2, y: 1 },
|
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 energyBar = this.scene.add.graphics().setDepth(901)
|
||||||
const jobIcon = this.scene.add.text(v.x, v.y - 18, '', { fontSize: '10px' }).setDepth(13)
|
const jobIcon = this.scene.add.text(v.x, v.y - 18, '', { fontSize: '10px' }).setDepth(902)
|
||||||
|
|
||||||
sprite.setInteractive()
|
sprite.setInteractive()
|
||||||
sprite.on('pointerdown', () => this.onNisseClick?.(v.id))
|
sprite.on('pointerdown', () => this.onNisseClick?.(v.id))
|
||||||
@@ -667,6 +675,14 @@ export class VillagerSystem {
|
|||||||
return result
|
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.
|
* Destroys all Nisse sprites and clears the runtime map.
|
||||||
* Should be called when the scene shuts down.
|
* Should be called when the scene shuts down.
|
||||||
|
|||||||
@@ -172,6 +172,16 @@ export class WorldSystem {
|
|||||||
this.resourceTiles.delete(tileY * WORLD_TILES + tileX)
|
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.
|
* Converts world pixel coordinates to tile coordinates.
|
||||||
* @param worldX - World X in pixels
|
* @param worldX - World X in pixels
|
||||||
|
|||||||
Reference in New Issue
Block a user