boardgame-phaser/packages/sts-like-viewer/src/gameobjects/CombatUnitSpawner.ts

76 lines
2.1 KiB
TypeScript

import Phaser from "phaser";
import type { Spawner } from "boardgame-phaser";
import { spawnEffect } from "boardgame-phaser";
import type { CombatState, CombatEntity, EnemyEntity } from "boardgame-core/samples/slay-the-spire-like";
import { CombatUnitContainer, type CombatUnitData } from "./CombatUnitContainer";
export class CombatUnitSpawner implements Spawner<CombatUnitData, CombatUnitContainer> {
constructor(private scene: Phaser.Scene) {}
*getData(): Iterable<CombatUnitData> {
const combat = this.getCombatState();
if (!combat) return;
yield {
key: "player",
entity: combat.player,
name: "Player",
isPlayer: true,
};
for (let i = 0; i < combat.enemies.length; i++) {
const enemy = combat.enemies[i];
yield {
key: `enemy-${i}`,
entity: enemy,
name: enemy.enemy.name,
isPlayer: false,
};
}
}
getKey(t: CombatUnitData): string {
return t.key;
}
onSpawn(t: CombatUnitData): CombatUnitContainer | null {
const { width, height } = this.scene.scale;
const combat = this.getCombatState();
if (!combat) return null;
const totalUnits = 1 + combat.enemies.length;
const spacing = 220;
const totalWidth = (totalUnits - 1) * spacing;
const startX = width / 2 - totalWidth / 2;
let x = startX;
if (t.key.startsWith("enemy-")) {
const index = parseInt(t.key.replace("enemy-", ""), 10);
x = startX + (index + 1) * spacing;
}
const y = height / 2;
const container = new CombatUnitContainer(this.scene, x, y, t);
container.playSpawnEffect();
return container;
}
onUpdate(t: CombatUnitData, obj: CombatUnitContainer): void {
obj.updateFromData(t);
}
onDespawn(obj: CombatUnitContainer): void {
obj.destroy();
}
private getCombatState(): CombatState | null {
const registry = this.scene.registry;
return (registry.get("combatState") as CombatState | undefined) ?? null;
}
}
export function createCombatUnitSpawner(scene: Phaser.Scene) {
return spawnEffect(new CombatUnitSpawner(scene));
}