✨ implement unified tile system (Issue #14)
- Tree seedlings: plant tree_seed on grass via farming tool; two-stage growth (sprout → sapling → young tree, ~1 min/stage); matures into a harvestable FOREST resource tile - Tile recovery: Nisse chops start a 5-min DARK_GRASS→GRASS timer; terrain canvas updated live via WorldSystem.refreshTerrainTile() - New TreeSeedlingSystem manages sprites, growth ticking, maturation - BootScene generates seedling_0/1/2 textures procedurally - FarmingSystem adds tree_seed to tool cycle (F key) - Stockpile panel shows tree_seed (default: 5); panel height adjusted - StateManager v5: treeSeedlings + tileRecovery in WorldState - WorldSystem uses CanvasTexture for live single-pixel updates Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,7 @@ export class WorldSystem {
|
||||
private tileset!: Phaser.Tilemaps.Tileset
|
||||
private bgImage!: Phaser.GameObjects.Image
|
||||
private builtLayer!: Phaser.Tilemaps.TilemapLayer
|
||||
private bgCanvasTexture!: Phaser.Textures.CanvasTexture
|
||||
|
||||
/** @param scene - The Phaser scene this system belongs to */
|
||||
constructor(scene: Phaser.Scene) {
|
||||
@@ -35,10 +36,8 @@ export class WorldSystem {
|
||||
const state = stateManager.getState()
|
||||
|
||||
// --- Canvas background (1px per tile, scaled up, LINEAR filtered) ---
|
||||
const canvas = document.createElement('canvas')
|
||||
canvas.width = WORLD_TILES
|
||||
canvas.height = WORLD_TILES
|
||||
const ctx = canvas.getContext('2d')!
|
||||
const canvasTexture = this.scene.textures.createCanvas('terrain_bg', WORLD_TILES, WORLD_TILES) as Phaser.Textures.CanvasTexture
|
||||
const ctx = canvasTexture.context
|
||||
|
||||
for (let y = 0; y < WORLD_TILES; y++) {
|
||||
for (let x = 0; x < WORLD_TILES; x++) {
|
||||
@@ -48,12 +47,14 @@ export class WorldSystem {
|
||||
}
|
||||
}
|
||||
|
||||
this.scene.textures.addCanvas('terrain_bg', canvas)
|
||||
canvasTexture.refresh()
|
||||
this.bgCanvasTexture = canvasTexture
|
||||
|
||||
this.bgImage = this.scene.add.image(0, 0, 'terrain_bg')
|
||||
.setOrigin(0, 0)
|
||||
.setScale(TILE_SIZE)
|
||||
.setDepth(0)
|
||||
this.scene.textures.get('terrain_bg').setFilter(Phaser.Textures.FilterMode.LINEAR)
|
||||
canvasTexture.setFilter(Phaser.Textures.FilterMode.LINEAR)
|
||||
|
||||
// --- Built tile layer (sparse — only FLOOR, WALL, TILLED_SOIL, WATERED_SOIL) ---
|
||||
this.map = this.scene.make.tilemap({
|
||||
@@ -157,6 +158,21 @@ export class WorldSystem {
|
||||
return state.world.tiles[tileY * WORLD_TILES + tileX] as TileType
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates a single tile's pixel on the background canvas and refreshes the GPU texture.
|
||||
* Used when a natural tile changes at runtime (e.g. DARK_GRASS → GRASS after recovery,
|
||||
* or GRASS → FOREST when a seedling matures).
|
||||
* @param tileX - Tile column
|
||||
* @param tileY - Tile row
|
||||
* @param type - New tile type to reflect visually
|
||||
*/
|
||||
refreshTerrainTile(tileX: number, tileY: number, type: TileType): void {
|
||||
const color = BIOME_COLORS[type] ?? '#0a2210'
|
||||
this.bgCanvasTexture.context.fillStyle = color
|
||||
this.bgCanvasTexture.context.fillRect(tileX, tileY, 1, 1)
|
||||
this.bgCanvasTexture.refresh()
|
||||
}
|
||||
|
||||
/** Destroys the tilemap and background image. */
|
||||
destroy(): void {
|
||||
this.map.destroy()
|
||||
|
||||
Reference in New Issue
Block a user