Add browser debugging support
This commit is contained in:
@@ -152,6 +152,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
private bondStates = new Map<string, BondState>();
|
||||
private attackIntents: AttackIntent[] = [];
|
||||
private pendingMove?: PendingMove;
|
||||
private debugOverlay?: Phaser.GameObjects.Text;
|
||||
|
||||
constructor() {
|
||||
super('BattleScene');
|
||||
@@ -168,6 +169,7 @@ export class BattleScene extends Phaser.Scene {
|
||||
this.handleRightClick(pointer);
|
||||
}
|
||||
});
|
||||
this.installDebugHotkeys();
|
||||
|
||||
this.add.rectangle(0, 0, width, height, 0x080b0d).setOrigin(0);
|
||||
this.drawMap();
|
||||
@@ -1473,4 +1475,99 @@ export class BattleScene extends Phaser.Scene {
|
||||
|
||||
this.renderRosterPanel(this.rosterTab, text);
|
||||
}
|
||||
|
||||
getDebugState() {
|
||||
return {
|
||||
scene: this.scene.key,
|
||||
turnNumber: this.turnNumber,
|
||||
activeFaction: this.activeFaction,
|
||||
phase: this.phase,
|
||||
selectedUnitId: this.selectedUnit?.id ?? null,
|
||||
pendingMove: this.pendingMove
|
||||
? {
|
||||
unitId: this.pendingMove.unit.id,
|
||||
from: { x: this.pendingMove.fromX, y: this.pendingMove.fromY },
|
||||
to: { x: this.pendingMove.toX, y: this.pendingMove.toY }
|
||||
}
|
||||
: null,
|
||||
actedUnitIds: Array.from(this.actedUnitIds),
|
||||
attackIntents: this.attackIntents.map((intent) => ({ ...intent })),
|
||||
units: firstBattleUnits.map((unit) => ({
|
||||
id: unit.id,
|
||||
name: unit.name,
|
||||
faction: unit.faction,
|
||||
classKey: unit.classKey,
|
||||
hp: unit.hp,
|
||||
maxHp: unit.maxHp,
|
||||
x: unit.x,
|
||||
y: unit.y,
|
||||
acted: this.actedUnitIds.has(unit.id)
|
||||
})),
|
||||
bonds: Array.from(this.bondStates.values()).map((bond) => ({
|
||||
id: bond.id,
|
||||
unitIds: bond.unitIds,
|
||||
level: bond.level,
|
||||
exp: bond.exp,
|
||||
battleExp: bond.battleExp
|
||||
}))
|
||||
};
|
||||
}
|
||||
|
||||
toggleDebugOverlay() {
|
||||
if (this.debugOverlay) {
|
||||
this.debugOverlay.destroy();
|
||||
this.debugOverlay = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
this.debugOverlay = this.add.text(12, 12, '', {
|
||||
fontFamily: 'Consolas, monospace',
|
||||
fontSize: '13px',
|
||||
color: '#dff7ff',
|
||||
backgroundColor: 'rgba(0, 0, 0, 0.72)',
|
||||
padding: { x: 8, y: 6 }
|
||||
});
|
||||
this.debugOverlay.setDepth(1000);
|
||||
this.updateDebugOverlay();
|
||||
}
|
||||
|
||||
private installDebugHotkeys() {
|
||||
if (!import.meta.env.DEV) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.input.keyboard?.on('keydown-F9', () => this.toggleDebugOverlay());
|
||||
this.input.keyboard?.on('keydown-F10', () => {
|
||||
console.info('[Battle Debug]', this.getDebugState());
|
||||
this.updateDebugOverlay();
|
||||
});
|
||||
this.input.on('pointermove', () => this.updateDebugOverlay());
|
||||
this.events.once(Phaser.Scenes.Events.SHUTDOWN, () => {
|
||||
this.debugOverlay?.destroy();
|
||||
this.debugOverlay = undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private updateDebugOverlay() {
|
||||
if (!this.debugOverlay) {
|
||||
return;
|
||||
}
|
||||
|
||||
const pointerTile = this.pointerToTile(this.input.activePointer);
|
||||
const selected = this.selectedUnit ? `${this.selectedUnit.name} (${this.selectedUnit.x},${this.selectedUnit.y})` : 'none';
|
||||
const pending = this.pendingMove
|
||||
? `${this.pendingMove.unit.name}: (${this.pendingMove.fromX},${this.pendingMove.fromY}) -> (${this.pendingMove.toX},${this.pendingMove.toY})`
|
||||
: 'none';
|
||||
|
||||
this.debugOverlay.setText([
|
||||
'Heros Web Debug',
|
||||
`scene=${this.scene.key}`,
|
||||
`turn=${this.turnNumber} faction=${this.activeFaction} phase=${this.phase}`,
|
||||
`selected=${selected}`,
|
||||
`pendingMove=${pending}`,
|
||||
`acted=${Array.from(this.actedUnitIds).join(',') || 'none'}`,
|
||||
`pointerTile=${pointerTile ? `${pointerTile.x},${pointerTile.y}` : 'outside'}`,
|
||||
'F9 toggle overlay / F10 log state'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
35
src/main.ts
35
src/main.ts
@@ -10,9 +10,24 @@ import './styles/global.css';
|
||||
declare global {
|
||||
interface Window {
|
||||
__HEROS_GAME__?: Phaser.Game;
|
||||
__HEROS_DEBUG__?: HerosDebugApi;
|
||||
}
|
||||
}
|
||||
|
||||
type DebugBattleScene = Phaser.Scene & {
|
||||
getDebugState?: () => unknown;
|
||||
toggleDebugOverlay?: () => void;
|
||||
};
|
||||
|
||||
type HerosDebugApi = {
|
||||
game: Phaser.Game;
|
||||
activeScenes: () => string[];
|
||||
battle: () => unknown;
|
||||
goToBattle: () => void;
|
||||
scene: (key: string) => Phaser.Scene | undefined;
|
||||
toggleBattleOverlay: () => void;
|
||||
};
|
||||
|
||||
const config: Phaser.Types.Core.GameConfig = {
|
||||
type: Phaser.AUTO,
|
||||
parent: 'game',
|
||||
@@ -32,4 +47,24 @@ const game = new Phaser.Game(config);
|
||||
|
||||
if (import.meta.env.DEV) {
|
||||
window.__HEROS_GAME__ = game;
|
||||
window.__HEROS_DEBUG__ = createDebugApi(game);
|
||||
console.info('[Heros Debug] Use window.__HEROS_DEBUG__.battle() or press F9 in battle.');
|
||||
}
|
||||
|
||||
function createDebugApi(game: Phaser.Game): HerosDebugApi {
|
||||
const scene = (key: string) => game.scene.getScene(key);
|
||||
const battleScene = () => scene('BattleScene') as DebugBattleScene | undefined;
|
||||
|
||||
return {
|
||||
game,
|
||||
activeScenes: () => game.scene.getScenes(true).map((activeScene) => activeScene.scene.key),
|
||||
battle: () => battleScene()?.getDebugState?.() ?? { active: false, reason: 'BattleScene is not active yet.' },
|
||||
goToBattle: () => {
|
||||
game.scene.start('BattleScene');
|
||||
},
|
||||
scene,
|
||||
toggleBattleOverlay: () => {
|
||||
battleScene()?.toggleDebugOverlay?.();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user