feat(game): 添加开会暂停系统——点击开会按钮暂停游戏,可安心发激励,结束开会后恢复
This commit is contained in:
@@ -474,13 +474,24 @@ export default function GamePage() {
|
||||
const [selectedTower, setSelectedTower] = useState<TowerType | null>(null)
|
||||
const [gameReady, setGameReady] = useState(false)
|
||||
const [waveStarted, setWaveStarted] = useState(false)
|
||||
// 召唤按钮状态(由 HUD 通过 window.__gameSetWaveBtn 驱动)
|
||||
const [inMeeting, setInMeeting] = useState(false) // 开会=游戏暂停
|
||||
const [waveBtn, setWaveBtn] = useState<{ text: string; disabled: boolean }>({
|
||||
text: '▶ 召唤下一波',
|
||||
disabled: false,
|
||||
})
|
||||
const selectedTowerRef = useRef<TowerType | null>(null)
|
||||
|
||||
const handleMeeting = useCallback(() => {
|
||||
if (!gameReady) return
|
||||
if (!inMeeting) {
|
||||
const ok = typeof window !== 'undefined' && (window as any).__gamePause?.()
|
||||
if (ok) setInMeeting(true)
|
||||
} else {
|
||||
const ok = typeof window !== 'undefined' && (window as any).__gameResume?.()
|
||||
if (ok) setInMeeting(false)
|
||||
}
|
||||
}, [gameReady, inMeeting])
|
||||
|
||||
const handleSelectTower = useCallback((type: TowerType) => {
|
||||
const next = selectedTowerRef.current === type ? null : type
|
||||
selectedTowerRef.current = next
|
||||
@@ -545,7 +556,8 @@ export default function GamePage() {
|
||||
;['__gameOnHCChange','__gameOnTowerDeselect','__gameSelectTower',
|
||||
'__gameReady','__gameDifficulty','__gamePuaBuff',
|
||||
'__gameGetHC','__gameSpendHC','__gameWaveStarted',
|
||||
'__gameSetWaveBtn','__gameWaveBtnState','__gameOnWaveClick'].forEach(k => {
|
||||
'__gameSetWaveBtn','__gameWaveBtnState','__gameOnWaveClick',
|
||||
'__gamePause','__gameResume','__gameIsPaused'].forEach(k => {
|
||||
delete (window as any)[k]
|
||||
})
|
||||
}
|
||||
@@ -565,79 +577,126 @@ export default function GamePage() {
|
||||
style={{ backgroundColor: '#0A1628' }}
|
||||
/>
|
||||
|
||||
{/* 右侧面板:HC + 召唤按钮 + PUA激励台 */}
|
||||
{/* 右侧面板:HC + 开会按钮 + 召唤按钮 + PUA激励台 */}
|
||||
<div style={{
|
||||
width: '240px',
|
||||
flexShrink: 0,
|
||||
backgroundColor: 'rgba(10,18,40,0.97)',
|
||||
borderLeft: '2px solid #1e3a5f',
|
||||
borderLeft: `2px solid ${inMeeting ? '#22C55E' : '#1e3a5f'}`,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
overflow: 'hidden',
|
||||
transition: 'border-color 0.2s',
|
||||
boxShadow: inMeeting ? 'inset 0 0 20px rgba(34,197,94,0.08)' : 'none',
|
||||
}}>
|
||||
{/* HC 数量显示 */}
|
||||
{/* HC 数量 + 开会按钮(同一行) */}
|
||||
<div style={{
|
||||
padding: '10px 12px 8px',
|
||||
padding: '8px 12px',
|
||||
borderBottom: '1px solid #1e3a5f',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '8px',
|
||||
}}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
<span style={{ fontFamily: 'VT323, monospace', fontSize: '13px', color: '#64748B' }}>
|
||||
<div style={{ flex: 1 }}>
|
||||
<div style={{ fontFamily: 'VT323, monospace', fontSize: '11px', color: '#475569', marginBottom: '1px' }}>
|
||||
人才储备
|
||||
</span>
|
||||
<span style={{
|
||||
</div>
|
||||
<div style={{
|
||||
fontFamily: "'Press Start 2P', monospace",
|
||||
fontSize: '12px',
|
||||
fontSize: '11px',
|
||||
color: '#A78BFA',
|
||||
letterSpacing: '1px',
|
||||
}}>
|
||||
{hc} HC
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
{/* 开会按钮 */}
|
||||
<button
|
||||
onClick={handleMeeting}
|
||||
disabled={!gameReady || !waveStarted}
|
||||
title={inMeeting ? '结束开会,恢复游戏' : '开会暂停,发起激励'}
|
||||
style={{
|
||||
flexShrink: 0,
|
||||
padding: '6px 10px',
|
||||
backgroundColor: inMeeting ? '#14532D' : '#0F1B2D',
|
||||
border: `2px solid ${inMeeting ? '#22C55E' : '#1e3a5f'}`,
|
||||
borderRadius: '8px',
|
||||
color: inMeeting ? '#4ADE80' : (!gameReady || !waveStarted ? '#334155' : '#94A3B8'),
|
||||
fontFamily: 'VT323, monospace',
|
||||
fontSize: '14px',
|
||||
cursor: !gameReady || !waveStarted ? 'not-allowed' : 'pointer',
|
||||
transition: 'all 0.15s',
|
||||
whiteSpace: 'nowrap',
|
||||
lineHeight: 1.2,
|
||||
boxShadow: inMeeting ? '0 0 10px rgba(34,197,94,0.3)' : 'none',
|
||||
}}
|
||||
>
|
||||
{inMeeting ? '📋 结束开会' : '📋 开会'}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* 召唤下一波按钮 */}
|
||||
<div style={{ padding: '10px 12px', borderBottom: '2px solid #1e3a5f' }}>
|
||||
{/* 开会中提示条 */}
|
||||
{inMeeting && (
|
||||
<div style={{
|
||||
backgroundColor: '#14532D',
|
||||
borderBottom: '1px solid #22C55E',
|
||||
padding: '5px 12px',
|
||||
fontFamily: 'VT323, monospace',
|
||||
fontSize: '13px',
|
||||
color: '#86EFAC',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: '6px',
|
||||
}}>
|
||||
<span style={{ animation: 'pulse 1.5s ease-in-out infinite' }}>●</span>
|
||||
游戏已暂停,可安心激励
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 召唤下一波按钮(开会时禁用) */}
|
||||
<div style={{ padding: '8px 12px', borderBottom: '2px solid #1e3a5f' }}>
|
||||
<button
|
||||
onClick={() => {
|
||||
if (inMeeting) return
|
||||
if (typeof window !== 'undefined') {
|
||||
(window as any).__gameOnWaveClick?.()
|
||||
}
|
||||
}}
|
||||
disabled={waveBtn.disabled || !gameReady}
|
||||
disabled={waveBtn.disabled || !gameReady || inMeeting}
|
||||
style={{
|
||||
width: '100%',
|
||||
padding: '10px 8px',
|
||||
backgroundColor: waveBtn.disabled || !gameReady ? '#0F172A' : '#1e3a5f',
|
||||
border: `2px solid ${waveBtn.disabled || !gameReady ? '#1e293b' : '#7C3AED'}`,
|
||||
backgroundColor: waveBtn.disabled || !gameReady || inMeeting ? '#0F172A' : '#1e3a5f',
|
||||
border: `2px solid ${waveBtn.disabled || !gameReady || inMeeting ? '#1e293b' : '#7C3AED'}`,
|
||||
borderRadius: '8px',
|
||||
color: waveBtn.disabled || !gameReady ? '#4B5563' : '#C4B5FD',
|
||||
color: waveBtn.disabled || !gameReady || inMeeting ? '#4B5563' : '#C4B5FD',
|
||||
fontFamily: 'VT323, monospace',
|
||||
fontSize: '20px',
|
||||
cursor: waveBtn.disabled || !gameReady ? 'not-allowed' : 'pointer',
|
||||
cursor: waveBtn.disabled || !gameReady || inMeeting ? 'not-allowed' : 'pointer',
|
||||
transition: 'all 0.15s ease',
|
||||
letterSpacing: '1px',
|
||||
lineHeight: 1.2,
|
||||
boxShadow: waveBtn.disabled || !gameReady ? 'none' : '0 0 12px rgba(124,58,237,0.3)',
|
||||
boxShadow: waveBtn.disabled || !gameReady || inMeeting ? 'none' : '0 0 12px rgba(124,58,237,0.3)',
|
||||
}}
|
||||
onMouseEnter={e => {
|
||||
if (!waveBtn.disabled && gameReady) {
|
||||
if (!waveBtn.disabled && gameReady && !inMeeting) {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundColor = '#2d3a5e'
|
||||
;(e.currentTarget as HTMLButtonElement).style.boxShadow = '0 0 18px rgba(124,58,237,0.5)'
|
||||
}
|
||||
}}
|
||||
onMouseLeave={e => {
|
||||
if (!waveBtn.disabled && gameReady) {
|
||||
if (!waveBtn.disabled && gameReady && !inMeeting) {
|
||||
(e.currentTarget as HTMLButtonElement).style.backgroundColor = '#1e3a5f'
|
||||
;(e.currentTarget as HTMLButtonElement).style.boxShadow = '0 0 12px rgba(124,58,237,0.3)'
|
||||
}
|
||||
}}
|
||||
>
|
||||
{waveBtn.text}
|
||||
{inMeeting ? '开会中...' : waveBtn.text}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* PUA 激励台 */}
|
||||
<PuaPanel gameReady={gameReady} hc={hc} waveStarted={waveStarted} />
|
||||
<PuaPanel gameReady={gameReady} hc={hc} waveStarted={waveStarted || inMeeting} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user