feat: press Esc to open menu during gameplay, close with Esc

This commit is contained in:
2026-06-09 15:40:01 +08:00
parent 72e442f2c3
commit 6b4114af43

View File

@@ -8,11 +8,14 @@ import HotspotLayer from '@/components/HotspotLayer.vue'
import SaveLoadMenu from '@/components/SaveLoadMenu.vue'
import ChapterSelect from '@/components/ChapterSelect.vue'
import PlaybackBar from '@/components/PlaybackBar.vue'
import LangSwitch from '@/components/LangSwitch.vue'
import { useGameEngine } from '@/composables/useGameEngine'
import { useGameStore } from '@/stores/gameStore'
import { useFullscreen } from '@/composables/useFullscreen'
import { useI18n } from '@/composables/useI18n'
const store = useGameStore()
const { t, currentLang } = useI18n()
const { isFullscreen, toggle: toggleFullscreen } = useFullscreen()
const videoElA = ref<HTMLVideoElement | null>(null)
const videoElB = ref<HTMLVideoElement | null>(null)
@@ -108,6 +111,9 @@ function onGlobalKeydown(e: KeyboardEvent) {
showChapterSelect.value = false
} else if (showMenu.value) {
showMenu.value = false
} else if (started.value && !store.gameEnded) {
showMenu.value = true
refreshSaves()
}
}
}
@@ -116,8 +122,6 @@ function onGlobalMouseMove() {
store.setInputMode('mouse')
}
const keyboardKeys = ['ArrowDown', 'ArrowUp', 'ArrowLeft', 'ArrowRight', 'Enter', 'Tab', ' ', 'w', 'a', 's', 'd']
onMounted(() => {
document.addEventListener('keydown', onGlobalKeydown)
document.addEventListener('mousemove', onGlobalMouseMove)
@@ -133,7 +137,7 @@ init()
<template>
<div class="app-container">
<div v-if="loading" class="loading">加载中...</div>
<div v-if="loading" class="loading">{{ t('ui.loading') }}</div>
<template v-else>
<div class="game-screen">
<GamePlayer v-show="!store.isImageScene" @video-ready="onVideoReady" />
@@ -146,6 +150,8 @@ init()
<Subtitles
:current-time="store.videoTime"
:subtitle-url="store.currentScene?.subtitleUrl ?? null"
:subtitles="store.currentScene?.subtitles ?? null"
:lang="currentLang"
/>
<QTEOverlay
:visible="store.qteActive"
@@ -169,21 +175,22 @@ init()
@skip="handleSkip"
@speed-change="handleSpeedChange"
/>
<button class="top-btn" @click="toggleFullscreen" :title="isFullscreen ? '退出全屏' : '全屏'">
<button class="top-btn" @click="toggleFullscreen" :title="isFullscreen ? t('ui.exitFullscreen') : t('ui.fullscreen')">
{{ isFullscreen ? '⛶' : '⛶' }}
</button>
<button class="top-btn" @click="toggleMenu">菜单</button>
<button class="top-btn" @click="toggleMenu">{{ t('ui.menu') }}</button>
</div>
</div>
<div v-if="!started" class="start-overlay">
<button class="start-btn" @click="handleStart">开始游戏</button>
<button v-if="hasAutoSave" class="start-btn resume-btn" @click="handleResume">继续上次进度</button>
<button v-if="store.chapters.length > 0" class="start-btn chapters-btn" @click="openChapterSelect">章节选择</button>
<LangSwitch />
<button class="start-btn" @click="handleStart">{{ t('ui.start') }}</button>
<button v-if="hasAutoSave" class="start-btn resume-btn" @click="handleResume">{{ t('ui.resume') }}</button>
<button v-if="store.chapters.length > 0" class="start-btn chapters-btn" @click="openChapterSelect">{{ t('ui.chapters') }}</button>
</div>
<div v-if="store.gameEnded" class="game-end-overlay">
<div class="game-end-text">游戏结束</div>
<div class="game-end-text">{{ t('ui.gameEnd') }}</div>
<div v-if="store.chapters.length > 0" class="game-end-actions">
<button class="end-btn" @click="openChapterSelect">章节选择</button>
<button class="end-btn" @click="openChapterSelect">{{ t('ui.chapters') }}</button>
</div>
</div>
<SaveLoadMenu
@@ -277,6 +284,7 @@ html, body {
inset: 0;
background: rgba(0, 0, 0, 0.8);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 100;
@@ -292,6 +300,7 @@ html, body {
inset: 0;
background: rgba(0, 0, 0, 0.85);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 100;
@@ -307,6 +316,7 @@ html, body {
cursor: pointer;
letter-spacing: 4px;
transition: background 0.2s;
margin-top: 16px;
}
.start-btn:hover {
@@ -314,13 +324,11 @@ html, body {
}
.resume-btn {
margin-top: 16px;
border-color: rgba(100, 200, 255, 0.3);
color: #8cf;
}
.chapters-btn {
margin-top: 16px;
border-color: rgba(255, 200, 100, 0.3);
color: #fc8;
}