fix(game): 修复底部塔面板不可见问题,改用React层实现,并用AI素材替换Graphics像素块

This commit is contained in:
Cloud Bot
2026-03-21 08:32:23 +00:00
parent 66b7776f32
commit 085aa0a407
14 changed files with 405 additions and 469 deletions

View File

@@ -12,7 +12,6 @@ import {
} from './mapRenderer'
import { TowerManager, type TowerType } from './towers/TowerManager'
import { WaveManager } from './enemies/WaveManager'
import { TowerPanel } from './ui/TowerPanel'
import { HUD } from './ui/HUD'
import { WeeklyReportModal } from './ui/WeeklyReportModal'
@@ -20,6 +19,18 @@ import { WeeklyReportModal } from './ui/WeeklyReportModal'
void MAP_ROWS; void GAME_HEIGHT; void GAME_WIDTH
void BAR_X; void BAR_Y; void BAR_W; void BAR_H
/** 所有游戏精灵的 key → public path 映射 */
const SPRITE_ASSETS: Record<string, string> = {
'tower-intern': '/game-assets/tower-intern.png',
'tower-senior': '/game-assets/tower-senior.png',
'tower-ppt': '/game-assets/tower-ppt.png',
'tower-hrbp': '/game-assets/tower-hrbp.png',
'enemy-fresh': '/game-assets/enemy-fresh.png',
'enemy-old': '/game-assets/enemy-old.png',
'enemy-trouble': '/game-assets/enemy-trouble.png',
'enemy-boss': '/game-assets/enemy-boss.png',
}
export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
class GameScene extends PhaserLib.Scene {
private manager!: GameManager
@@ -30,7 +41,6 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
private tileGraphics!: Phaser.GameObjects.Graphics
private towerManager!: TowerManager
private waveManager!: WaveManager
private towerPanel!: TowerPanel
private hud!: HUD
private weeklyModal!: WeeklyReportModal
private selectedTowerType: TowerType | null = null
@@ -39,6 +49,13 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
constructor() { super({ key: 'GameScene' }) }
preload(): void {
// 加载所有 AI 生成的角色图片
for (const [key, path] of Object.entries(SPRITE_ASSETS)) {
this.load.image(key, path)
}
}
create(): void {
this.manager = GameManager.getInstance()
this.manager.reset()
@@ -70,30 +87,39 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
this.hud = new HUD(this)
this.hud.createWaveButton(() => this.onWaveButtonClick())
this.towerPanel = new TowerPanel('game-container')
this.towerPanel.onSelect((type) => {
this.selectedTowerType = type
if (!type) this.buildModeGraphics.clear()
})
// 接收 React 层传来的选塔事件
if (typeof window !== 'undefined') {
;(window as any).__gameSelectTower = (type: TowerType | null) => {
this.selectedTowerType = type
if (!type) this.buildModeGraphics.clear()
}
}
this.setupInteraction()
// HC/KPI 变化时同步到 React HUD
this.manager.onHCChange.push((hc: number) => {
this.hcText.setText(`HC: ${hc}`)
// 通知 React 层更新塔面板可用状态
if (typeof window !== 'undefined') {
;(window as any).__gameOnHCChange?.(hc)
}
})
this.manager.onKPIChange.push((kpi: number) => {
updateKPIBar(this.kpiBar, kpi)
this.kpiText.setText(`${kpi}%`)
})
this.manager.onHCChange.push((hc: number) => {
this.hcText.setText(`HC: ${hc}`)
this.towerPanel.refreshCardStates()
})
this.manager.onGameOver.push(() => {
this.hud.showGameOver()
this.towerPanel.destroy()
})
this.manager.onVictory.push(() => {
this.hud.showVictory()
this.towerPanel.destroy()
})
// 通知 React 层游戏已就绪
if (typeof window !== 'undefined') {
;(window as any).__gameReady?.()
}
}
update(_time: number, delta: number): void {
@@ -128,7 +154,7 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
}
/** 禁锢全场塔(老板视察效果) */
private freezeAllTowers(duration: number = 3000): void {
freezeAllTowers(duration: number = 3000): void {
this.towerManager.getAllTowers().forEach(tower => {
tower.isFrozen = true
setTimeout(() => { tower.isFrozen = false }, duration)
@@ -136,7 +162,7 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
}
/** 补满全场塔精力 */
private refillAllStamina(): void {
refillAllStamina(): void {
this.towerManager.getAllTowers().forEach(tower => {
tower.stamina = tower.maxStamina
tower['isActive'] = true
@@ -183,6 +209,9 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
const y = HUD_HEIGHT + row * cellH
this.buildModeGraphics.lineStyle(2, 0xa78bfa, 0.9)
this.buildModeGraphics.strokeRect(x + 2, y + 2, cellW - 4, cellH - 4)
// 填充半透明预览
this.buildModeGraphics.fillStyle(0xa78bfa, 0.15)
this.buildModeGraphics.fillRect(x + 2, y + 2, cellW - 4, cellH - 4)
}
private handleTileClick(col: number, row: number, cellW: number, cellH: number): void {
@@ -191,8 +220,11 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
const placed = this.towerManager.placeTower(col, row, this.selectedTowerType)
if (placed) {
this.buildModeGraphics.clear()
this.towerPanel.deselect()
this.selectedTowerType = null
// 通知 React 取消选中状态
if (typeof window !== 'undefined') {
;(window as any).__gameOnTowerDeselect?.()
}
} else {
this.showTip(col, row, cellW, cellH, 'HC不足或格子已占用', '#EF4444')
}
@@ -200,7 +232,7 @@ export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
}
const hasTower = this.towerManager.handleTileClick(col, row)
if (!hasTower && !PATH_TILES.has(`${col},${row}`)) {
this.showTip(col, row, cellW, cellH, '从底部面板选择塔', '#A78BFA')
this.showTip(col, row, cellW, cellH, '请先从底部选择塔', '#A78BFA')
}
}