refactor: remove unused state and widget files in sts-like-viewer
This commit is contained in:
parent
033a8e4a40
commit
85bc4f5400
|
|
@ -1,34 +0,0 @@
|
|||
import { MutableSignal, mutableSignal, createRNG } from 'boardgame-core';
|
||||
import { createRunState, generatePointCrawlMap, data, type RunState, type ItemData } from 'boardgame-core/samples/slay-the-spire-like';
|
||||
|
||||
/**
|
||||
* 全局游戏运行状态 Signal
|
||||
*
|
||||
* 在 App.tsx 中创建为单例,所有场景共享。
|
||||
* 遭遇场景通过读取此 signal 的当前遭遇状态来构建 UI。
|
||||
*/
|
||||
export function createGameState(seed?: number): MutableSignal<RunState> {
|
||||
const actualSeed = seed ?? Date.now();
|
||||
const rng = createRNG(actualSeed);
|
||||
const encounters = data.desert.encounters;
|
||||
const map = generatePointCrawlMap(rng, encounters);
|
||||
const starterItems: ItemData[] = data.desert.items.slice(0, 3);
|
||||
return mutableSignal<RunState>(createRunState(map, starterItems));
|
||||
}
|
||||
|
||||
/** 获取当前遭遇数据(computed getter) */
|
||||
export function currentEncounter(
|
||||
gameState: MutableSignal<RunState>
|
||||
): { nodeId: string; encounter: { name: string; description: string; type: string } } | null {
|
||||
const state = gameState.value;
|
||||
const node = state.map.nodes.get(state.currentNodeId);
|
||||
if (!node || !node.encounter) return null;
|
||||
return {
|
||||
nodeId: node.id,
|
||||
encounter: {
|
||||
type: node.type,
|
||||
name: node.encounter.name,
|
||||
description: node.encounter.description,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
import Phaser from "phaser";
|
||||
|
||||
export interface GridBackgroundRendererOptions {
|
||||
scene: Phaser.Scene;
|
||||
parentContainer: Phaser.GameObjects.Container;
|
||||
cellSize: number;
|
||||
gridGap: number;
|
||||
gridX: number;
|
||||
gridY: number;
|
||||
/** Background fill color for each cell */
|
||||
cellBgColor?: number;
|
||||
/** Border/stroke color for each cell */
|
||||
cellBorderColor?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the static grid background (empty cells with borders).
|
||||
* Separated from item rendering so it can be drawn once and left alone.
|
||||
*/
|
||||
export class GridBackgroundRenderer {
|
||||
private scene: Phaser.Scene;
|
||||
private parentContainer: Phaser.GameObjects.Container;
|
||||
private cellSize: number;
|
||||
private gridGap: number;
|
||||
private gridX: number;
|
||||
private gridY: number;
|
||||
private cellBgColor: number;
|
||||
private cellBorderColor: number;
|
||||
|
||||
private graphics!: Phaser.GameObjects.Graphics;
|
||||
|
||||
constructor(options: GridBackgroundRendererOptions) {
|
||||
this.scene = options.scene;
|
||||
this.parentContainer = options.parentContainer;
|
||||
this.cellSize = options.cellSize;
|
||||
this.gridGap = options.gridGap;
|
||||
this.gridX = options.gridX;
|
||||
this.gridY = options.gridY;
|
||||
this.cellBgColor = options.cellBgColor ?? 0x1a1a2e;
|
||||
this.cellBorderColor = options.cellBorderColor ?? 0x444477;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the grid background for the given dimensions.
|
||||
* Should be called once during initialization.
|
||||
*/
|
||||
draw(width: number, height: number): void {
|
||||
this.graphics = this.scene.add.graphics();
|
||||
|
||||
for (let y = 0; y < height; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
const px = this.gridX + x * (this.cellSize + this.gridGap);
|
||||
const py = this.gridY + y * (this.cellSize + this.gridGap);
|
||||
|
||||
this.graphics.fillStyle(this.cellBgColor);
|
||||
this.graphics.fillRect(px, py, this.cellSize, this.cellSize);
|
||||
this.graphics.lineStyle(2, this.cellBorderColor);
|
||||
this.graphics.strokeRect(px, py, this.cellSize, this.cellSize);
|
||||
}
|
||||
}
|
||||
|
||||
this.parentContainer.add(this.graphics);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the graphics object.
|
||||
*/
|
||||
destroy(): void {
|
||||
this.graphics?.destroy();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
import Phaser from "phaser";
|
||||
import {
|
||||
type InventoryItem,
|
||||
type GameItemMeta,
|
||||
} from "boardgame-core/samples/slay-the-spire-like";
|
||||
|
||||
export interface LostItem {
|
||||
id: string;
|
||||
container: Phaser.GameObjects.Container;
|
||||
shape: InventoryItem<GameItemMeta>["shape"];
|
||||
transform: InventoryItem<GameItemMeta>["transform"];
|
||||
meta: InventoryItem<GameItemMeta>["meta"];
|
||||
}
|
||||
|
||||
export interface LostItemManagerOptions {
|
||||
scene: Phaser.Scene;
|
||||
cellSize: number;
|
||||
gridGap: number;
|
||||
getItemColor: (itemId: string) => number;
|
||||
onLostItemDragStart: (
|
||||
itemId: string,
|
||||
container: Phaser.GameObjects.Container,
|
||||
) => void;
|
||||
isDragging: () => boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Manages "lost" items — items that were dropped outside valid grid placement.
|
||||
* Renders them as semi-transparent red-bordered containers that can be re-dragged.
|
||||
*/
|
||||
export class LostItemManager {
|
||||
private scene: Phaser.Scene;
|
||||
private cellSize: number;
|
||||
private gridGap: number;
|
||||
private getItemColor: (itemId: string) => number;
|
||||
private onLostItemDragStart: (
|
||||
itemId: string,
|
||||
container: Phaser.GameObjects.Container,
|
||||
) => void;
|
||||
private isDragging: () => boolean;
|
||||
|
||||
private lostItems = new Map<string, LostItem>();
|
||||
|
||||
constructor(options: LostItemManagerOptions) {
|
||||
this.scene = options.scene;
|
||||
this.cellSize = options.cellSize;
|
||||
this.gridGap = options.gridGap;
|
||||
this.getItemColor = options.getItemColor;
|
||||
this.onLostItemDragStart = options.onLostItemDragStart;
|
||||
this.isDragging = options.isDragging;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a visual representation of a lost item at the given position.
|
||||
*/
|
||||
createLostItem(
|
||||
itemId: string,
|
||||
shape: InventoryItem<GameItemMeta>["shape"],
|
||||
transform: InventoryItem<GameItemMeta>["transform"],
|
||||
meta: InventoryItem<GameItemMeta>["meta"],
|
||||
x: number,
|
||||
y: number,
|
||||
): void {
|
||||
const container = this.scene.add.container(x, y).setDepth(500);
|
||||
|
||||
const graphics = this.scene.add.graphics();
|
||||
const color = this.getItemColor(itemId);
|
||||
|
||||
for (let gy = 0; gy < shape.height; gy++) {
|
||||
for (let gx = 0; gx < shape.width; gx++) {
|
||||
if (shape.grid[gy]?.[gx]) {
|
||||
graphics.fillStyle(color, 0.5);
|
||||
graphics.fillRect(
|
||||
gx * (this.cellSize + this.gridGap),
|
||||
gy * (this.cellSize + this.gridGap),
|
||||
this.cellSize - 2,
|
||||
this.cellSize - 2,
|
||||
);
|
||||
graphics.lineStyle(2, 0xff4444);
|
||||
graphics.strokeRect(
|
||||
gx * (this.cellSize + this.gridGap),
|
||||
gy * (this.cellSize + this.gridGap),
|
||||
this.cellSize,
|
||||
this.cellSize,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
container.add(graphics);
|
||||
|
||||
const name = meta?.itemData.name ?? itemId;
|
||||
const text = this.scene.add
|
||||
.text(0, -20, `${name} (lost)`, {
|
||||
fontSize: "12px",
|
||||
color: "#ff4444",
|
||||
fontStyle: "italic",
|
||||
})
|
||||
.setOrigin(0.5);
|
||||
container.add(text);
|
||||
|
||||
const hitRect = new Phaser.Geom.Rectangle(
|
||||
0,
|
||||
0,
|
||||
this.cellSize,
|
||||
this.cellSize,
|
||||
);
|
||||
container.setInteractive(hitRect, Phaser.Geom.Rectangle.Contains);
|
||||
|
||||
container.on("pointerdown", (pointer: Phaser.Input.Pointer) => {
|
||||
// Guard against stale events firing on destroyed containers
|
||||
if (!container.scene || !container.active) return;
|
||||
if (this.isDragging()) return;
|
||||
if (pointer.button === 0) {
|
||||
this.onLostItemDragStart(itemId, container);
|
||||
}
|
||||
});
|
||||
|
||||
this.lostItems.set(itemId, {
|
||||
id: itemId,
|
||||
container,
|
||||
shape,
|
||||
transform: { ...transform },
|
||||
meta,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all lost item IDs.
|
||||
*/
|
||||
getLostItemIds(): string[] {
|
||||
return Array.from(this.lostItems.keys());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a lost item by ID, or undefined if not found.
|
||||
*/
|
||||
getLostItem(itemId: string): LostItem | undefined {
|
||||
return this.lostItems.get(itemId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy and clear all lost items.
|
||||
*/
|
||||
clear(): void {
|
||||
for (const lost of this.lostItems.values()) {
|
||||
lost.container.destroy();
|
||||
}
|
||||
this.lostItems.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy all managed visuals.
|
||||
*/
|
||||
destroy(): void {
|
||||
this.clear();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue