172 lines
4.9 KiB
TypeScript
172 lines
4.9 KiB
TypeScript
import type Phaser from 'phaser'
|
||
import { GAME_WIDTH, HUD_HEIGHT } from '../constants'
|
||
import { GameManager } from '../GameManager'
|
||
import { showVictoryModal, showDefeatModal } from './EndScreenModal'
|
||
|
||
/**
|
||
* 游戏 HUD 辅助工具
|
||
* 负责管理"召唤下一波"按钮、波次提示横幅、胜利/失败结算弹窗
|
||
*/
|
||
export class HUD {
|
||
private scene: Phaser.Scene
|
||
private waveBtn: Phaser.GameObjects.Text | null = null
|
||
private waveBannerTimeout: (() => void) | null = null
|
||
private _onClick: (() => void) | null = null
|
||
|
||
constructor(scene: Phaser.Scene) {
|
||
this.scene = scene
|
||
}
|
||
|
||
/**
|
||
* 创建"召唤下一波"按钮
|
||
* @param onClick 点击回调
|
||
*/
|
||
createWaveButton(onClick: () => void): void {
|
||
if (this.waveBtn) this.waveBtn.destroy()
|
||
this._onClick = onClick
|
||
|
||
this.waveBtn = this.scene.add
|
||
.text(GAME_WIDTH / 2, HUD_HEIGHT + 16, '▶ 召唤下一波', {
|
||
fontFamily: 'VT323, monospace',
|
||
fontSize: '26px',
|
||
color: '#A78BFA',
|
||
backgroundColor: '#1e3a5f',
|
||
padding: { x: 20, y: 8 },
|
||
stroke: '#7C3AED',
|
||
strokeThickness: 1,
|
||
})
|
||
.setOrigin(0.5, 0)
|
||
.setDepth(20)
|
||
.setInteractive({ useHandCursor: true })
|
||
|
||
this.waveBtn.on('pointerover', () => {
|
||
if (this.waveBtn) this.waveBtn.setStyle({ backgroundColor: '#2d5a8e', color: '#C4B5FD' })
|
||
})
|
||
this.waveBtn.on('pointerout', () => {
|
||
if (this.waveBtn) this.waveBtn.setStyle({ backgroundColor: '#1e3a5f', color: '#A78BFA' })
|
||
})
|
||
this.waveBtn.on('pointerdown', () => onClick())
|
||
}
|
||
|
||
/** 更新按钮文字(如禁用状态) */
|
||
setWaveButtonText(text: string): void {
|
||
this.waveBtn?.setText(text)
|
||
}
|
||
|
||
disableWaveButton(): void {
|
||
if (!this.waveBtn) return
|
||
this.waveBtn.setStyle({ color: '#4B5563', backgroundColor: '#0F172A' })
|
||
this.waveBtn.removeAllListeners('pointerdown')
|
||
}
|
||
|
||
enableWaveButton(): void {
|
||
if (!this.waveBtn) return
|
||
this.waveBtn.setStyle({ color: '#A78BFA', backgroundColor: '#1e3a5f' })
|
||
// 重新绑定点击事件(disableWaveButton 会 removeAllListeners)
|
||
this.waveBtn.removeAllListeners('pointerdown')
|
||
if (this._onClick) {
|
||
this.waveBtn.on('pointerdown', () => this._onClick!())
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 显示波次开始横幅
|
||
* @param waveNumber 当前波次(1-based)
|
||
* @param totalWaves 总波次数
|
||
*/
|
||
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(),
|
||
})
|
||
}
|
||
|
||
/** 显示胜利画面(完整绩效评级弹窗,委托给 EndScreenModal) */
|
||
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 })
|
||
}
|
||
|
||
/** 显示失败画面(仿钉钉退群通知,委托给 EndScreenModal) */
|
||
showGameOver(): void {
|
||
showDefeatModal()
|
||
}
|
||
|
||
destroy(): void {
|
||
this.waveBtn?.destroy()
|
||
if (this.waveBannerTimeout) this.waveBannerTimeout()
|
||
}
|
||
}
|