Files
test1/game/ui/HUD.ts

177 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'
/**
* 游戏 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
*/
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 overlay = this.scene.add.graphics()
overlay.fillStyle(0x000000, 0.6)
overlay.fillRect(0, 0, GAME_WIDTH, 720)
overlay.setDepth(50)
this.scene.add
.text(GAME_WIDTH / 2, 300, '🎉 大厂保卫成功!', {
fontFamily: "'Press Start 2P', monospace",
fontSize: '22px',
color: '#A78BFA',
backgroundColor: '#0A1628',
padding: { x: 24, y: 12 },
})
.setOrigin(0.5, 0.5)
.setDepth(55)
this.scene.add
.text(GAME_WIDTH / 2, 380, 'KPI 绩效已发放!', {
fontFamily: 'VT323, monospace',
fontSize: '24px',
color: '#A78BFA',
})
.setOrigin(0.5, 0.5)
.setDepth(55)
}
/** 显示失败画面 */
showGameOver(): void {
const overlay = this.scene.add.graphics()
overlay.fillStyle(0x000000, 0.7)
overlay.fillRect(0, 0, GAME_WIDTH, 720)
overlay.setDepth(50)
this.scene.add
.text(GAME_WIDTH / 2, 300, 'KPI 归零!被裁了!', {
fontFamily: "'Press Start 2P', monospace",
fontSize: '18px',
color: '#EF4444',
backgroundColor: '#0A1628',
padding: { x: 24, y: 12 },
})
.setOrigin(0.5, 0.5)
.setDepth(55)
}
destroy(): void {
this.waveBtn?.destroy()
if (this.waveBannerTimeout) this.waveBannerTimeout()
}
}