Files
test1/game/ui/HUD.ts

165 lines
4.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type Phaser from 'phaser'
import { GAME_WIDTH, HUD_HEIGHT } from '../constants'
import { GameManager } from '../GameManager'
import { showVictoryModal, showDefeatModal } from './EndScreenModal'
/**
* 游戏 HUD 辅助工具
* 召唤下一波按钮已移至 React 右侧面板HUD 只负责横幅提示和结算弹窗
*/
export class HUD {
private scene: Phaser.Scene
private waveBannerTimeout: (() => void) | null = null
// 按钮状态通过 window 回调同步到 React
private _onWaveClick: (() => void) | null = null
constructor(scene: Phaser.Scene) {
this.scene = scene
}
/**
* 注册"召唤下一波"逻辑,并把控制接口暴露给 React 层
*/
createWaveButton(onClick: () => void): void {
this._onWaveClick = onClick
if (typeof window === 'undefined') return
// React 层通过 window.__gameOnWaveClick() 触发
;(window as any).__gameOnWaveClick = () => {
this._onWaveClick?.()
}
// 初始状态:可用
this._notifyReact('▶ 召唤下一波', false)
}
private _notifyReact(text: string, disabled: boolean): void {
if (typeof window !== 'undefined') {
;(window as any).__gameSetWaveBtn?.({ text, disabled })
}
}
setWaveButtonText(text: string): void {
// 保持当前 disabled 状态,只更新文字
if (typeof window !== 'undefined') {
const cur = (window as any).__gameWaveBtnState
const disabled = cur?.disabled ?? false
this._notifyReact(text, disabled)
}
}
disableWaveButton(): void {
this._notifyReact((typeof window !== 'undefined'
? (window as any).__gameWaveBtnState?.text ?? '波次进行中...'
: '波次进行中...'), true)
}
enableWaveButton(): void {
this._notifyReact((typeof window !== 'undefined'
? (window as any).__gameWaveBtnState?.text ?? '▶ 召唤下一波'
: '▶ 召唤下一波'), false)
}
/**
* 显示波次开始横幅
*/
showWaveBanner(waveNumber: number, totalWaves: number): void {
const isBoss = waveNumber === totalWaves
const label = isBoss
? `!! 第${waveNumber}空降VP来袭 !!`
: `${waveNumber} 波来袭!`
const color = isBoss ? '#FBBF24' : '#F43F5E'
const bg = isBoss ? '#7C2D12' : '#0A1628'
const banner = this.scene.add
.text(GAME_WIDTH / 2, HUD_HEIGHT + 60, label, {
fontFamily: "'Press Start 2P', monospace",
fontSize: isBoss ? '16px' : '14px',
color,
backgroundColor: bg,
padding: { x: 20, y: 10 },
})
.setOrigin(0.5, 0.5)
.setDepth(40)
.setAlpha(0)
this.scene.tweens.add({
targets: banner,
alpha: 1,
duration: 300,
yoyo: true,
hold: 1800,
onComplete: () => banner.destroy(),
})
}
/** 显示周报触发提示横幅 */
showWeeklyReportAlert(): void {
const banner = this.scene.add
.text(GAME_WIDTH / 2, HUD_HEIGHT + 120, '周报时间到!请选择正确黑话!', {
fontFamily: "'Press Start 2P', monospace",
fontSize: '11px',
color: '#FCD34D',
backgroundColor: '#78350F',
padding: { x: 16, y: 8 },
})
.setOrigin(0.5, 0.5)
.setDepth(40)
.setAlpha(0)
this.scene.tweens.add({
targets: banner,
alpha: 1,
duration: 400,
yoyo: true,
hold: 2500,
onComplete: () => banner.destroy(),
})
}
/** 显示胜利画面 */
showVictory(): void {
const manager = GameManager.getInstance()
const kpi = manager.kpi
const hc = manager.hc
let grade: string
let gradeColor: string
let gradeDesc: string
if (kpi >= 80) {
grade = 'S级 "超出预期"'
gradeColor = '#fbbf24'
gradeDesc = '恭喜晋升为高级打工人!福报已在路上...'
} else if (kpi >= 60) {
grade = 'A级 "达成预期"'
gradeColor = '#34d399'
gradeDesc = '表现良好明年涨薪3%(扣去通胀后-2%'
} else if (kpi >= 40) {
grade = 'B级 "基本达成"'
gradeColor = '#60a5fa'
gradeDesc = '还需努力下月开始996'
} else {
grade = 'C级 "未达预期"'
gradeColor = '#f87171'
gradeDesc = '已被纳入待优化名单'
}
showVictoryModal({ kpi, hc, grade, gradeColor, gradeDesc })
}
/** 显示失败画面 */
showGameOver(): void {
showDefeatModal()
}
destroy(): void {
if (this.waveBannerTimeout) this.waveBannerTimeout()
if (typeof window !== 'undefined') {
delete (window as any).__gameOnWaveClick
delete (window as any).__gameSetWaveBtn
delete (window as any).__gameWaveBtnState
}
}
}