Files
test1/game/ui/HUD.ts

163 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 辅助工具
* 负责管理"召唤下一波"按钮、波次提示横幅、胜利/失败结算弹窗
*/
export class HUD {
private scene: Phaser.Scene
private waveBtn: Phaser.GameObjects.Text | null = null
private waveBannerTimeout: (() => void) | null = null
constructor(scene: Phaser.Scene) {
this.scene = scene
}
/**
* 创建"召唤下一波"按钮
* @param onClick 点击回调
*/
createWaveButton(onClick: () => void): void {
if (this.waveBtn) this.waveBtn.destroy()
this.waveBtn = this.scene.add
.text(GAME_WIDTH - 160, HUD_HEIGHT + 20, '▶ 召唤下一波', {
fontFamily: "'Press Start 2P', monospace",
fontSize: '9px',
color: '#A78BFA',
backgroundColor: '#1e3a5f',
padding: { x: 10, y: 6 },
})
.setOrigin(0, 0)
.setDepth(20)
.setInteractive({ useHandCursor: true })
this.waveBtn.on('pointerover', () => {
if (this.waveBtn) this.waveBtn.setStyle({ backgroundColor: '#2d5a8e' })
})
this.waveBtn.on('pointerout', () => {
if (this.waveBtn) this.waveBtn.setStyle({ backgroundColor: '#1e3a5f' })
})
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' })
}
/**
* 显示波次开始横幅
* @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()
}
}