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
|
showSplash.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 设置前端状态并恢复后端
|
||||||
isManualPaused.value = false
|
isManualPaused.value = false
|
||||||
|
systemApi.resumeGame().catch(console.error)
|
||||||
openedFromSplash.value = false // 游戏开始,清除 Splash 来源标记
|
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 menuDefaultTab = ref<'save' | 'load' | 'create' | 'delete' | 'llm' | 'start'>('load')
|
||||||
const canCloseMenu = ref(true)
|
const canCloseMenu = ref(true)
|
||||||
|
|
||||||
// 监听菜单状态和手动暂停状态,控制游戏暂停/继续
|
// 统一的暂停控制逻辑:
|
||||||
watch([showMenu, isManualPaused], ([menuVisible, manualPaused]) => {
|
// - 菜单打开时:暂停后端(不影响 isManualPaused)
|
||||||
// 只在游戏已准备好时控制暂停
|
// - 菜单关闭时:如果没有手动暂停,恢复后端
|
||||||
|
watch(showMenu, (menuVisible) => {
|
||||||
if (!gameInitialized.value) return
|
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)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
systemStore.resume().catch(console.error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 优化:简化 Watch 逻辑
|
|
||||||
// 核心规则:菜单打开 OR 手动暂停 => 必须暂停
|
|
||||||
// 菜单关闭 AND 手动播放 => 恢复
|
|
||||||
watch([showMenu], ([menuVisible]) => {
|
|
||||||
if (!gameInitialized.value) return
|
|
||||||
if (menuVisible) {
|
if (menuVisible) {
|
||||||
|
// 菜单打开,暂停后端
|
||||||
systemStore.pause().catch(console.error)
|
systemStore.pause().catch(console.error)
|
||||||
} else {
|
} else {
|
||||||
// 关闭菜单时,如果不是手动暂停状态,则恢复
|
// 菜单关闭,只有在非手动暂停时才恢复
|
||||||
if (!isManualPaused.value) {
|
if (!isManualPaused.value) {
|
||||||
systemStore.resume().catch(console.error)
|
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) {
|
function handleKeydown(e: KeyboardEvent) {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
|
|||||||
@@ -46,18 +46,27 @@ export const useSystemStore = defineStore('system', () => {
|
|||||||
isInitialized.value = val;
|
isInitialized.value = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 切换手动暂停状态(用户点击暂停按钮时调用)
|
||||||
async function togglePause() {
|
async function togglePause() {
|
||||||
if (isManualPaused.value) {
|
const newState = !isManualPaused.value;
|
||||||
await resume();
|
isManualPaused.value = newState;
|
||||||
|
try {
|
||||||
|
if (newState) {
|
||||||
|
await systemApi.pauseGame();
|
||||||
} else {
|
} else {
|
||||||
await pause();
|
await systemApi.resumeGame();
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// API 失败时回滚状态
|
||||||
|
isManualPaused.value = !newState;
|
||||||
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 仅调用后端 API,不修改 isManualPaused(用于菜单打开/关闭等系统行为)
|
||||||
async function pause() {
|
async function pause() {
|
||||||
try {
|
try {
|
||||||
await systemApi.pauseGame();
|
await systemApi.pauseGame();
|
||||||
isManualPaused.value = true;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
@@ -66,7 +75,6 @@ export const useSystemStore = defineStore('system', () => {
|
|||||||
async function resume() {
|
async function resume() {
|
||||||
try {
|
try {
|
||||||
await systemApi.resumeGame();
|
await systemApi.resumeGame();
|
||||||
isManualPaused.value = false;
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user