boardgame-phaser/packages/boop-game/src/scenes/PieceSpawner.ts

82 lines
2.2 KiB
TypeScript

import Phaser from 'phaser';
import type { BoopState, BoopPart } from '@/game';
import { GameHostScene, spawnEffect, type Spawner } from 'boardgame-phaser';
import { BOARD_OFFSET, CELL_SIZE } from './BoardRenderer';
class BoopPartSpawner implements Spawner<BoopPart, Phaser.GameObjects.Container> {
constructor(public readonly scene: GameHostScene<BoopState>) {}
*getData() {
for (const part of Object.values(this.scene.state.pieces)) {
if(part.regionId === 'board')
yield part;
}
}
getKey(part: BoopPart): string {
return part.id;
}
onUpdate(part: BoopPart, obj: Phaser.GameObjects.Container): void {
const [row, col] = part.position;
const x = BOARD_OFFSET.x + col * CELL_SIZE + CELL_SIZE / 2;
const y = BOARD_OFFSET.y + row * CELL_SIZE + CELL_SIZE / 2;
this.scene.tweens.add({
targets: obj,
x: x,
y: y,
duration: 200,
ease: 'Power2',
});
}
onSpawn(part: BoopPart) {
const [row, col] = part.position;
const x = BOARD_OFFSET.x + col * CELL_SIZE + CELL_SIZE / 2;
const y = BOARD_OFFSET.y + row * CELL_SIZE + CELL_SIZE / 2;
const container = this.scene.add.container(x, y);
const isCat = part.type === 'cat';
const baseColor = part.player === 'white' ? 0xffffff : 0x333333;
const strokeColor = part.player === 'white' ? 0x000000 : 0xffffff;
const circle = this.scene.add.circle(0, 0, CELL_SIZE * 0.4, baseColor)
.setStrokeStyle(3, strokeColor);
const text = isCat ? '🐱' : '🐾';
const textObj = this.scene.add.text(0, 0, text, {
fontSize: `${isCat ? 40 : 32}px`,
fontFamily: 'Arial',
}).setOrigin(0.5);
container.add([circle, textObj]);
container.setScale(0);
this.scene.addTweenInterruption(this.scene.tweens.add({
targets: container,
scale: 1,
duration: 200,
ease: 'Back.easeOut',
}));
return container;
}
onDespawn(obj: Phaser.GameObjects.Container) {
this.scene.tweens.add({
targets: obj,
alpha: 0,
scale: 0.5,
duration: 200,
ease: 'Back.easeIn',
onComplete: () => obj.destroy(),
});
}
}
export function createPieceSpawner(scene: GameHostScene<BoopState>) {
return spawnEffect(new BoopPartSpawner(scene));
}