feat: P1 core - seamless video switching, conditional branches, save/load
- VideoManager: A/B dual-buffered video with crossfade transitions and candidate preloading - Engine: condition-based choice filtering, ChoiceSystem timer, resumeScene for save/load - SceneManager: getCandidateUrls for preloading next scenes - SaveSystem: Dexie.js IndexedDB multi-slot save/load - ChoiceSystem: timed choices with countdown and auto-default on timeout - GamePlayer: dual video elements with crossfade CSS - ChoicePanel: timer progress bar and countdown text - SaveLoadMenu: save/load UI component - App.vue: menu trigger, dual video refs, save/load integration - gameStore: timer state, saves list - demo.json: conditional choice example (secret ending, requires trust >= 80) - ROADMAP: mark P1 as completed
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { GameData, SceneNode } from '../types'
|
||||
import type { GameData, SceneNode, Choice, Condition } from '../types'
|
||||
|
||||
export class SceneManager {
|
||||
private scenes: Record<string, SceneNode> = {}
|
||||
@@ -22,4 +22,30 @@ export class SceneManager {
|
||||
getAllSceneIds(): string[] {
|
||||
return Object.keys(this.scenes)
|
||||
}
|
||||
|
||||
getCandidateTargetIds(scene: SceneNode, evaluateCondition: (conds?: Condition[]) => boolean): string[] {
|
||||
const targets: string[] = []
|
||||
|
||||
if (scene.choices) {
|
||||
for (const choice of scene.choices) {
|
||||
if (!choice.conditions || evaluateCondition(choice.conditions)) {
|
||||
if (!targets.includes(choice.targetScene)) {
|
||||
targets.push(choice.targetScene)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (scene.nextScene && !targets.includes(scene.nextScene)) {
|
||||
targets.push(scene.nextScene)
|
||||
}
|
||||
|
||||
return targets
|
||||
}
|
||||
|
||||
getCandidateUrls(scene: SceneNode, evaluateCondition: (conds?: Condition[]) => boolean): string[] {
|
||||
return this.getCandidateTargetIds(scene, evaluateCondition)
|
||||
.map(id => this.scenes[id]?.videoUrl)
|
||||
.filter((url): url is string => !!url)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user