fix(web): decouple manual pause state from system pause behavior (#37)
The pause indicator was showing 'paused' while the game was still running because isManualPaused was being modified by both user actions (clicking pause button) and system actions (opening menu). Changes: - systemStore: pause()/resume() no longer modify isManualPaused, only togglePause() does (with optimistic update + rollback on failure) - useGameControl: consolidate 3 overlapping watches into 1 clean watch that only handles menu open/close without polluting manual pause state - App.vue: explicitly call resumeGame() API when game initializes
This commit is contained in:
@@ -69,7 +69,9 @@ watch(gameInitialized, (val) => {
|
||||
showSplash.value = false
|
||||
}
|
||||
|
||||
// 设置前端状态并恢复后端
|
||||
isManualPaused.value = false
|
||||
systemApi.resumeGame().catch(console.error)
|
||||
openedFromSplash.value = false // 游戏开始,清除 Splash 来源标记
|
||||
}
|
||||
})
|
||||
|
||||
@@ -14,50 +14,23 @@ export function useGameControl(gameInitialized: Ref<boolean>) {
|
||||
const menuDefaultTab = ref<'save' | 'load' | 'create' | 'delete' | 'llm' | 'start'>('load')
|
||||
const canCloseMenu = ref(true)
|
||||
|
||||
// 监听菜单状态和手动暂停状态,控制游戏暂停/继续
|
||||
watch([showMenu, isManualPaused], ([menuVisible, manualPaused]) => {
|
||||
// 只在游戏已准备好时控制暂停
|
||||
// 统一的暂停控制逻辑:
|
||||
// - 菜单打开时:暂停后端(不影响 isManualPaused)
|
||||
// - 菜单关闭时:如果没有手动暂停,恢复后端
|
||||
watch(showMenu, (menuVisible) => {
|
||||
if (!gameInitialized.value) return
|
||||
|
||||
if (menuVisible || manualPaused) {
|
||||
// 如果不是因为菜单打开而暂停(即用户手动暂停),则不需额外操作,因为状态已经在 store 里了
|
||||
// 但如果是菜单打开导致需要暂停,我们需要调用 pause
|
||||
if (menuVisible && !manualPaused) {
|
||||
systemStore.pause().catch(console.error)
|
||||
} else if (!menuVisible && !manualPaused) {
|
||||
// 菜单关闭且非手动暂停 -> 恢复
|
||||
systemStore.resume().catch(console.error)
|
||||
} else if (manualPaused) {
|
||||
// 只要是手动暂停,就确保是暂停状态
|
||||
systemStore.pause().catch(console.error)
|
||||
}
|
||||
if (menuVisible) {
|
||||
// 菜单打开,暂停后端
|
||||
systemStore.pause().catch(console.error)
|
||||
} else {
|
||||
systemStore.resume().catch(console.error)
|
||||
// 菜单关闭,只有在非手动暂停时才恢复
|
||||
if (!isManualPaused.value) {
|
||||
systemStore.resume().catch(console.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 优化:简化 Watch 逻辑
|
||||
// 核心规则:菜单打开 OR 手动暂停 => 必须暂停
|
||||
// 菜单关闭 AND 手动播放 => 恢复
|
||||
watch([showMenu], ([menuVisible]) => {
|
||||
if (!gameInitialized.value) return
|
||||
if (menuVisible) {
|
||||
systemStore.pause().catch(console.error)
|
||||
} else {
|
||||
// 关闭菜单时,如果不是手动暂停状态,则恢复
|
||||
if (!isManualPaused.value) {
|
||||
systemStore.resume().catch(console.error)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Watch 手动暂停状态的变化,同步到后端
|
||||
watch(isManualPaused, (val) => {
|
||||
if (!gameInitialized.value) return
|
||||
if (val) systemStore.pause().catch(console.error)
|
||||
else if (!showMenu.value) systemStore.resume().catch(console.error)
|
||||
})
|
||||
|
||||
// 快捷键处理
|
||||
function handleKeydown(e: KeyboardEvent) {
|
||||
if (e.key === 'Escape') {
|
||||
|
||||
@@ -46,18 +46,27 @@ export const useSystemStore = defineStore('system', () => {
|
||||
isInitialized.value = val;
|
||||
}
|
||||
|
||||
// 切换手动暂停状态(用户点击暂停按钮时调用)
|
||||
async function togglePause() {
|
||||
if (isManualPaused.value) {
|
||||
await resume();
|
||||
} else {
|
||||
await pause();
|
||||
const newState = !isManualPaused.value;
|
||||
isManualPaused.value = newState;
|
||||
try {
|
||||
if (newState) {
|
||||
await systemApi.pauseGame();
|
||||
} else {
|
||||
await systemApi.resumeGame();
|
||||
}
|
||||
} catch (e) {
|
||||
// API 失败时回滚状态
|
||||
isManualPaused.value = !newState;
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 仅调用后端 API,不修改 isManualPaused(用于菜单打开/关闭等系统行为)
|
||||
async function pause() {
|
||||
try {
|
||||
await systemApi.pauseGame();
|
||||
isManualPaused.value = true;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -66,7 +75,6 @@ export const useSystemStore = defineStore('system', () => {
|
||||
async function resume() {
|
||||
try {
|
||||
await systemApi.resumeGame();
|
||||
isManualPaused.value = false;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user