'use client' import { useEffect, useRef, useState, useCallback } from 'react' const TOWER_META = [ { type: 'intern', name: '00后实习生', cost: 50, desc: '近战 15伤 1.5/s', color: '#22C55E', img: '/game-assets/tower-intern.png', tip: '整顿职场:5%概率秒杀' }, { type: 'senior', name: 'P6资深开发', cost: 120, desc: '远程 30伤 5格射程', color: '#3B82F6', img: '/game-assets/tower-senior.png', tip: '代码屎山:附带持续伤害' }, { type: 'ppt', name: 'PPT大师', cost: 100, desc: 'AOE减速 5伤', color: '#F59E0B', img: '/game-assets/tower-ppt.png', tip: '黑话领域:减速40%' }, { type: 'hrbp', name: 'HRBP', cost: 80, desc: '辅助 +20%攻速', color: '#EC4899', img: '/game-assets/tower-hrbp.png', tip: '打鸡血:周围塔攻速+20%' }, ] as const type TowerType = 'intern' | 'senior' | 'ppt' | 'hrbp' export default function GamePage() { const gameRef = useRef<{ destroy: (removeCanvas: boolean) => void } | null>(null) const [hc, setHc] = useState(200) const [selectedTower, setSelectedTower] = useState(null) const [gameReady, setGameReady] = useState(false) // expose setter to game scene via window const selectedTowerRef = useRef(null) const handleSelectTower = useCallback((type: TowerType) => { const next = selectedTowerRef.current === type ? null : type selectedTowerRef.current = next setSelectedTower(next) // notify scene if (typeof window !== 'undefined') { (window as any).__gameSelectTower?.(next) } }, []) useEffect(() => { let mounted = true const initGame = async () => { const Phaser = (await import('phaser')).default const { createGameConfig } = await import('@/game/config') const { createGameScene } = await import('@/game/GameScene') if (!mounted) return const GameScene = createGameScene(Phaser) const config = createGameConfig('game-canvas-container') config.scene = [GameScene] if (config.scale) { config.scale.mode = Phaser.Scale.FIT config.scale.autoCenter = Phaser.Scale.CENTER_BOTH } config.type = Phaser.AUTO // expose HC update to React if (typeof window !== 'undefined') { (window as any).__gameOnHCChange = (val: number) => { if (mounted) setHc(val) } (window as any).__gameOnTowerDeselect = () => { if (mounted) { selectedTowerRef.current = null setSelectedTower(null) } } ;(window as any).__gameReady = () => { if (mounted) setGameReady(true) } } gameRef.current = new Phaser.Game(config) } initGame().catch(console.error) return () => { mounted = false gameRef.current?.destroy(true) gameRef.current = null if (typeof window !== 'undefined') { delete (window as any).__gameOnHCChange delete (window as any).__gameOnTowerDeselect delete (window as any).__gameSelectTower delete (window as any).__gameReady } } }, []) return (
{/* Phaser canvas 区域,flex-1 填满剩余高度 */}
{/* 底部塔选择面板 — 纯 React DOM,不被 Canvas 遮挡 */}
{/* 选塔提示 */}
{selectedTower ? '点击格子建造' : '选择塔 ▼'}
{TOWER_META.map((meta) => { const canAfford = hc >= meta.cost const isSelected = selectedTower === meta.type return ( ) })}
) }