-
-
Notifications
You must be signed in to change notification settings - Fork 352
Flowchart #996
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Flowchart #996
Changes from all commits
0fb8f74
f3ee885
f594871
9e3ad7c
e325e8e
4f885cd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,172 @@ | ||
| { | ||
| "flowcharts": [ | ||
| { | ||
| "id": "main", | ||
| "name": "示例游戏主线", | ||
| "type": "main", | ||
| "nodes": [ | ||
| { | ||
| "id": "start", | ||
| "type": "root", | ||
| "position": { "x": 250, "y": 0 }, | ||
| "data": { | ||
| "label": "入口选择", | ||
| "sceneName": "start.txt", | ||
| "isRoot": true | ||
| } | ||
| }, | ||
| { | ||
| "id": "zh_cn", | ||
| "type": "chapter", | ||
| "position": { "x": 0, "y": 120 }, | ||
| "data": { | ||
| "label": "简体中文演示", | ||
| "sceneName": "demo_zh_cn.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "ja", | ||
| "type": "chapter", | ||
| "position": { "x": 240, "y": 120 }, | ||
| "data": { | ||
| "label": "日本語デモ", | ||
| "sceneName": "demo_ja.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "en", | ||
| "type": "chapter", | ||
| "position": { "x": 480, "y": 120 }, | ||
| "data": { | ||
| "label": "English Demo", | ||
| "sceneName": "demo_en.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "function_test", | ||
| "type": "branch", | ||
| "position": { "x": 720, "y": 120 }, | ||
| "data": { | ||
| "label": "功能测试入口", | ||
| "sceneName": "function_test.txt" | ||
| } | ||
| } | ||
| ], | ||
| "edges": [ | ||
| { "id": "e-start-zh-cn", "source": "start", "target": "zh_cn" }, | ||
| { "id": "e-start-ja", "source": "start", "target": "ja" }, | ||
| { "id": "e-start-en", "source": "start", "target": "en" }, | ||
| { "id": "e-start-function-test", "source": "start", "target": "function_test" } | ||
| ] | ||
| }, | ||
| { | ||
| "id": "function-tests", | ||
| "name": "功能测试分支", | ||
| "type": "character", | ||
| "nodes": [ | ||
| { | ||
| "id": "function_test", | ||
| "type": "root", | ||
| "position": { "x": 550, "y": 0 }, | ||
| "data": { | ||
| "label": "功能测试入口", | ||
| "sceneName": "function_test.txt", | ||
| "isRoot": true | ||
| } | ||
| }, | ||
| { | ||
| "id": "animation", | ||
| "type": "event", | ||
| "position": { "x": 0, "y": 120 }, | ||
| "data": { | ||
| "label": "口型动画测试", | ||
| "sceneName": "demo_animation.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "var", | ||
| "type": "event", | ||
| "position": { "x": 220, "y": 120 }, | ||
| "data": { | ||
| "label": "变量插值测试", | ||
| "sceneName": "demo_var.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "change_config", | ||
| "type": "event", | ||
| "position": { "x": 440, "y": 120 }, | ||
| "data": { | ||
| "label": "配置修改测试", | ||
| "sceneName": "demo_changeConfig.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "performs", | ||
| "type": "event", | ||
| "position": { "x": 660, "y": 120 }, | ||
| "data": { | ||
| "label": "Pixi 演出测试", | ||
| "sceneName": "demo_performs.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "flow_control", | ||
| "type": "branch", | ||
| "position": { "x": 880, "y": 120 }, | ||
| "data": { | ||
| "label": "流程控制测试", | ||
| "sceneName": "demo_test_flow_control.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "variable_flow", | ||
| "type": "branch", | ||
| "position": { "x": 1100, "y": 120 }, | ||
| "data": { | ||
| "label": "变量流程测试", | ||
| "sceneName": "demo_test_variable_flow_control.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "input_flow", | ||
| "type": "branch", | ||
| "position": { "x": 1320, "y": 120 }, | ||
| "data": { | ||
| "label": "用户输入流程测试", | ||
| "sceneName": "demo_test_input_flow_control.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "dom_control", | ||
| "type": "event", | ||
| "position": { "x": 1540, "y": 120 }, | ||
| "data": { | ||
| "label": "DOM 生命周期测试", | ||
| "sceneName": "demo_test_dom_control.txt" | ||
| } | ||
| }, | ||
| { | ||
| "id": "flow_child", | ||
| "type": "event", | ||
| "position": { "x": 880, "y": 240 }, | ||
| "data": { | ||
| "label": "callScene 子场景", | ||
| "sceneName": "demo_test_flow_control_child.txt" | ||
| } | ||
| } | ||
| ], | ||
| "edges": [ | ||
| { "id": "e-function-animation", "source": "function_test", "target": "animation" }, | ||
| { "id": "e-function-var", "source": "function_test", "target": "var" }, | ||
| { "id": "e-function-change-config", "source": "function_test", "target": "change_config" }, | ||
| { "id": "e-function-performs", "source": "function_test", "target": "performs" }, | ||
| { "id": "e-function-flow-control", "source": "function_test", "target": "flow_control" }, | ||
| { "id": "e-function-variable-flow", "source": "function_test", "target": "variable_flow" }, | ||
| { "id": "e-function-input-flow", "source": "function_test", "target": "input_flow" }, | ||
| { "id": "e-function-dom-control", "source": "function_test", "target": "dom_control" }, | ||
| { "id": "e-flow-control-child", "source": "flow_control", "target": "flow_child" } | ||
| ] | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,207 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { SceneManager } from '@/Core/Modules/scene'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { stageStateManager } from '@/Core/Modules/stage/stageStateManager'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import { ISaveData } from '@/store/userDataInterface'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import axios from 'axios'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import cloneDeep from 'lodash/cloneDeep'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import localforage from 'localforage'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export interface IFlowchartNodeData extends Record<string, unknown> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| label: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sceneName: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| isRoot?: boolean; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export interface IFlowchartNode { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| position: { x: number; y: number }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| data: IFlowchartNodeData; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type?: 'root' | 'chapter' | 'branch' | 'ending' | 'event' | string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export interface IFlowchartEdge { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| source: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| target: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export interface IFlowchart { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| id: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type?: 'main' | 'character'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nodes: IFlowchartNode[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| edges: IFlowchartEdge[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export interface IFlowchartData { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| flowcharts: IFlowchart[]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const FLOWCHART_UPDATED_EVENT = 'webgal-flowchart-updated'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| export class FlowchartManager { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public enabled = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private gameKey = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private data: IFlowchartData = { flowcharts: [] }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private unlocked = new Set<string>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private snapshots = new Map<string, ISaveData>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private pendingUnlockCurrentScene = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private waitingUnlockSceneKey = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public constructor(private readonly sceneManager: SceneManager) {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public async init(gameKey: string, enabled: boolean) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.gameKey = gameKey; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.enabled = enabled; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.data = { flowcharts: [] }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.unlocked.clear(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.snapshots.clear(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!enabled || !gameKey) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const res = await axios.get('./game/flowchart.json'); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.data = normalizeFlowchartData(res.data); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const unlocked = await localforage.getItem<string[]>(this.progressKey()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.unlocked = new Set(Array.isArray(unlocked) ? unlocked : []); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.unlockPendingCurrentScene(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.data = { flowcharts: [] }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public hasFlowchart() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return this.enabled && this.data.flowcharts.length > 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public getFlowcharts() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return this.data.flowcharts; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public getEventName() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return FLOWCHART_UPDATED_EVENT; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public isUnlocked(flowchartId: string, nodeId: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return this.unlocked.has(this.nodeKey(flowchartId, nodeId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public requestUnlockCurrentScene() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (this.currentSceneKey() !== this.waitingUnlockSceneKey) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.pendingUnlockCurrentScene = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public unlockPendingCurrentScene() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!this.pendingUnlockCurrentScene || !this.hasFlowchart()) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.pendingUnlockCurrentScene = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.waitingUnlockSceneKey = ''; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.unlockCurrentScene(true); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public waitForCurrentSceneDialog() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.pendingUnlockCurrentScene = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.waitingUnlockSceneKey = this.currentSceneKey(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public async loadSnapshot(flowchartId: string, nodeId: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const key = this.nodeKey(flowchartId, nodeId); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!this.unlocked.has(key)) return null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const cached = this.snapshots.get(key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (cached) return cached; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return await localforage.getItem<ISaveData>(this.snapshotKey(flowchartId, nodeId)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public async clearProgress() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const keys = [...this.unlocked]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.unlocked.clear(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.snapshots.clear(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await Promise.all(keys.map((key) => localforage.removeItem(this.snapshotKeyByNodeKey(key)))); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| await localforage.removeItem(this.progressKey()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window.dispatchEvent(new Event(FLOWCHART_UPDATED_EVENT)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public unlockCurrentScene(refreshSnapshot = false) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!this.hasFlowchart()) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const sceneNames = new Set([ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| normalizeSceneName(this.sceneManager.sceneData.currentScene.sceneName), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| normalizeSceneName(this.sceneManager.sceneData.currentScene.sceneUrl), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const matched = this.data.flowcharts.flatMap((flowchart) => | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| flowchart.nodes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .filter((node) => sceneNames.has(normalizeSceneName(node.data?.sceneName))) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .map((node) => ({ flowchart, node })), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (matched.length === 0) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const snapshot = this.createSnapshot(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let changed = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| matched.forEach(({ flowchart, node }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const key = this.nodeKey(flowchart.id, node.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const isUnlocked = this.unlocked.has(key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (isUnlocked && !refreshSnapshot) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!isUnlocked) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| changed = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.unlocked.add(key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| this.snapshots.set(key, snapshot); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| localforage.setItem(this.snapshotKey(flowchart.id, node.id), snapshot); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (changed) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| localforage.setItem(this.progressKey(), [...this.unlocked]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| window.dispatchEvent(new Event(FLOWCHART_UPDATED_EVENT)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private createSnapshot(): ISaveData { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nowStageState: cloneDeep(stageStateManager.getViewStageState()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| backlog: [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| index: -1, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| saveTime: new Date().toLocaleDateString() + ' ' + new Date().toLocaleTimeString('chinese', { hour12: false }), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 在
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sceneData: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| currentSentenceId: this.sceneManager.sceneData.currentSentenceId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sceneStack: cloneDeep(this.sceneManager.sceneData.sceneStack), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sceneName: this.sceneManager.sceneData.currentScene.sceneName, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| sceneUrl: this.sceneManager.sceneData.currentScene.sceneUrl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| previewImage: '', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+151
to
+165
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 在
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private progressKey() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return `${this.gameKey}-flowchart`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private snapshotKey(flowchartId: string, nodeId: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return `${this.gameKey}-flowchart-${flowchartId}-${nodeId}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private snapshotKeyByNodeKey(key: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return `${this.gameKey}-flowchart-${key}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private nodeKey(flowchartId: string, nodeId: string) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return `${flowchartId}-${nodeId}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private currentSceneKey() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const { currentScene } = this.sceneManager.sceneData; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return `${normalizeSceneName(currentScene.sceneName)}|${normalizeSceneName(currentScene.sceneUrl)}`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+183
to
+186
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 在 private currentSceneKey() {
const currentScene = this.sceneManager?.sceneData?.currentScene;
if (!currentScene) return '';
return `${normalizeSceneName(currentScene.sceneName)}|${normalizeSceneName(currentScene.sceneUrl)}`;
} |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function normalizeFlowchartData(raw: string | IFlowchartData): IFlowchartData { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const data = typeof raw === 'string' ? JSON.parse(raw) : raw; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const flowcharts: IFlowchart[] = Array.isArray(data?.flowcharts) ? data.flowcharts : []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| flowcharts: flowcharts.map((flowchart) => ({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ...flowchart, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| type: flowchart.id === 'main' ? 'main' : flowchart.type || 'character', | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nodes: Array.isArray(flowchart.nodes) ? flowchart.nodes : [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| edges: Array.isArray(flowchart.edges) ? flowchart.edges : [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function normalizeSceneName(sceneName = '') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return decodeURI(sceneName) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/\\/g, '/') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/^\.?\/?game\/scene\//, '') | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .replace(/^\.?\//, ''); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在
unlockCurrentScene中,直接访问this.sceneManager.sceneData.currentScene可能会在场景尚未加载完成时(例如初始化阶段)由于currentScene为undefined而抛出TypeError。建议添加安全的空值检查。