Files
test1/game/GameScene.ts

149 lines
4.0 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 { MAP_COLS, MAP_ROWS, HUD_HEIGHT, GAME_HEIGHT, GAME_WIDTH } from './constants'
import { GameManager } from './GameManager'
import {
PATH_TILES,
getCellSize,
drawAllTiles,
renderMapLabels,
renderHUD,
updateKPIBar,
BAR_X,
BAR_Y,
BAR_W,
BAR_H,
} from './mapRenderer'
/**
* 创建主游戏场景类(工厂函数,接收动态导入的 Phaser 实例)
* 这样可以保证 SSR 安全(只在客户端执行)
*/
export function createGameScene(PhaserLib: typeof Phaser): typeof Phaser.Scene {
class GameScene extends PhaserLib.Scene {
private manager!: GameManager
private kpiBar!: Phaser.GameObjects.Graphics
private kpiText!: Phaser.GameObjects.Text
private hcText!: Phaser.GameObjects.Text
private hoveredTile: { col: number; row: number } | null = null
private tileGraphics!: Phaser.GameObjects.Graphics
constructor() {
super({ key: 'GameScene' })
}
create(): void {
this.manager = GameManager.getInstance()
this.manager.reset()
this.manager.gameState = 'playing'
// 渲染地图
this.tileGraphics = this.add.graphics()
drawAllTiles(this.tileGraphics, null)
// 地图装饰标签
renderMapLabels(this)
// HUD在地图之上
const hud = renderHUD(this)
this.kpiBar = hud.kpiBar
this.kpiText = hud.kpiText
this.hcText = hud.hcText
// 鼠标交互
this.setupInteraction()
// GameManager 事件回调 → 更新 HUD
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}`)
})
}
/** 注册鼠标悬停 + 点击事件 */
private setupInteraction(): void {
const { cellW, cellH } = getCellSize()
this.input.on(
'pointermove',
(pointer: Phaser.Input.Pointer) => {
const col = Math.floor(pointer.x / cellW)
const row = Math.floor((pointer.y - HUD_HEIGHT) / cellH)
if (col >= 0 && col < MAP_COLS && row >= 0 && row < MAP_ROWS) {
if (!PATH_TILES.has(`${col},${row}`)) {
if (
!this.hoveredTile ||
this.hoveredTile.col !== col ||
this.hoveredTile.row !== row
) {
this.hoveredTile = { col, row }
drawAllTiles(this.tileGraphics, this.hoveredTile)
}
return
}
}
if (this.hoveredTile !== null) {
this.hoveredTile = null
drawAllTiles(this.tileGraphics, null)
}
}
)
this.input.on(
'pointerdown',
(pointer: Phaser.Input.Pointer) => {
const col = Math.floor(pointer.x / cellW)
const row = Math.floor((pointer.y - HUD_HEIGHT) / cellH)
if (
col >= 0 && col < MAP_COLS &&
row >= 0 && row < MAP_ROWS &&
!PATH_TILES.has(`${col},${row}`)
) {
this.showBuildPrompt(col, row, cellW, cellH)
}
}
)
}
/** 点击可建格子时的占位提示Phase 1 */
private showBuildPrompt(
col: number,
row: number,
cellW: number,
cellH: number
): void {
const x = col * cellW + cellW / 2
const y = HUD_HEIGHT + row * cellH + cellH / 2
const tip = this.add
.text(x, y - 20, '建塔 (即将开放)', {
fontFamily: 'VT323, monospace',
fontSize: '18px',
color: '#F43F5E',
backgroundColor: '#0a1628',
padding: { x: 8, y: 4 },
})
.setOrigin(0.5, 1)
.setDepth(20)
this.time.delayedCall(1500, () => {
tip.destroy()
})
}
}
// 避免 unused variable 警告
void MAP_ROWS
void GAME_HEIGHT
void GAME_WIDTH
void BAR_X
void BAR_Y
void BAR_W
void BAR_H
return GameScene
}