feat: intro video, asset updates, roadmap and engine improvements

This commit is contained in:
2026-06-10 14:47:45 +08:00
parent 68312c6137
commit 76581d0326
8 changed files with 152 additions and 3 deletions

View File

@@ -37,6 +37,10 @@ const canSkip = ref(false)
const paused = ref(false)
const promptToast = ref('')
const showPromptToast = ref(false)
const showIntro = ref(false)
const introWatched = ref(false)
const introVideoRef = ref<HTMLVideoElement | null>(null)
const menuVideoRef = ref<HTMLVideoElement | null>(null)
const { loadGame, start, resumeAutoSave, makeChoice, clickHotspot, startChapter,
skipScene, setSpeed, getSpeed, isSceneWatched,
@@ -68,6 +72,21 @@ async function init() {
}
loading.value = false
hasAutoSave.value = (await saveSystem.load(0)) !== null
if (store.introVideo) {
introWatched.value = await isSceneWatched('__intro__')
showIntro.value = true
}
}
function onIntroEnded() {
saveSystem.markWatched('__intro__')
showIntro.value = false
}
function skipIntro() {
saveSystem.markWatched('__intro__')
showIntro.value = false
}
function handleStart() {
@@ -212,7 +231,16 @@ init()
<div class="app-container">
<div v-if="loading" class="loading">{{ t('ui.loading') }}</div>
<template v-else>
<div class="game-screen">
<div v-if="showIntro" class="intro-overlay" @click="skipIntro">
<video ref="introVideoRef" :src="store.introVideo" class="intro-video" autoplay @ended="onIntroEnded"></video>
<button v-if="introWatched" class="intro-skip-btn" @click.stop="skipIntro">{{ t('ui.skip') }}</button>
</div>
<div v-if="store.menuVideo && (!started || store.gameEnded)" class="menu-bg">
<video ref="menuVideoRef" :src="store.menuVideo" class="menu-bg-video" autoplay loop muted></video>
</div>
<div class="game-screen" v-show="started && !store.gameEnded">
<GamePlayer v-show="!store.isImageScene" @video-ready="onVideoReady" />
<HotspotLayer
:hotspots="store.hotspots"
@@ -418,6 +446,54 @@ html, body {
color: #888;
}
.intro-overlay {
position: fixed;
inset: 0;
background: #000;
z-index: 500;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.intro-video {
width: 100%;
height: 100%;
object-fit: contain;
}
.intro-skip-btn {
position: absolute;
bottom: 40px;
right: 40px;
padding: 10px 24px;
font-size: 14px;
color: #fff;
background: rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.3);
border-radius: 4px;
cursor: pointer;
letter-spacing: 2px;
z-index: 10;
}
.intro-skip-btn:hover {
background: rgba(0, 0, 0, 0.7);
}
.menu-bg {
position: fixed;
inset: 0;
z-index: 0;
}
.menu-bg-video {
width: 100%;
height: 100%;
object-fit: cover;
}
.prompt-toast {
position: absolute;
top: 50%;