如何高效检测游戏对话对象的函数执行完成状态?
解决方案
给你几个更高效的替代方案,适配不同场景:
1. 让对话类实例自身维护执行状态
不用额外数组跟踪,直接在每个对话类里加个状态属性,函数执行完标记为已完成。这样避免了索引管理的麻烦,也更直观。
示例代码:
// 对话类定义 class Dialogue { constructor() { this.isExecuted = false; // 自身维护执行状态 } run() { // 这里是你的对话逻辑、Canvas绘制代码 console.log("对话执行中..."); // 执行完毕后标记状态 this.isExecuted = true; } } // 实例化所有对话对象 const dialogues = [ new Dialogue(), new Dialogue(), new Dialogue() ]; // 执行所有对话 dialogues.forEach(d => d.run()); // 检查是否全部执行完成 const allDone = dialogues.every(d => d.isExecuted); if (allDone) { // 推进程序逻辑 console.log("所有对话执行完毕,继续游戏流程"); }
2. 用Promise管理异步执行(适合带动画/延迟的对话)
如果你的对话函数包含异步操作(比如文字渐显、等待用户点击),用Promise包装每个函数,然后用Promise.all等待所有完成,彻底告别手动状态跟踪。
示例代码:
class Dialogue { run() { return new Promise((resolve) => { // 异步对话逻辑,比如Canvas绘制动画 setTimeout(() => { console.log("异步对话执行完成"); resolve(); // 执行完成后resolve }, 1000); }); } } // 收集所有对话的Promise const dialoguePromises = [new Dialogue(), new Dialogue()].map(d => d.run()); // 等待所有对话执行完毕 (async () => { await Promise.all(dialoguePromises); // 这里推进程序,不会出现绘制重叠 console.log("所有异步对话完成,继续游戏"); })();
3. 回调函数计数模式
给每个对话函数传入回调,每完成一个就计数,达到总数后触发后续逻辑,适合简单的同步/异步混合场景。
示例代码:
class Dialogue { run(onComplete) { // 对话绘制逻辑 console.log("对话执行完成"); // 执行完调用回调 onComplete(); } } const totalDialogues = 3; let completedCount = 0; const onDialogueDone = () => { completedCount++; if (completedCount === totalDialogues) { // 所有完成,推进程序 console.log("全部对话完成,继续游戏"); } }; // 创建实例并执行 new Dialogue().run(onDialogueDone); new Dialogue().run(onDialogueDone); new Dialogue().run(onDialogueDone);
4. 状态机管理对话流程(适合复杂游戏对话)
如果你的对话有分支、线性流程,直接用状态机管理当前流程节点,不用跟踪每个函数的执行状态,只关心当前流程走到哪一步。
示例代码:
// 状态机定义 const DialogueState = { START: 'start', DIALOGUE_1: 'dialogue1', DIALOGUE_2: 'dialogue2', END: 'end' }; let currentState = DialogueState.START; class Dialogue1 { run() { // 绘制对话1 console.log("执行对话1"); // 完成后切换状态 currentState = DialogueState.DIALOGUE_2; } } class Dialogue2 { run() { // 绘制对话2 console.log("执行对话2"); currentState = DialogueState.END; } } // 游戏主循环里检查状态 function gameLoop() { switch(currentState) { case DialogueState.START: new Dialogue1().run(); break; case DialogueState.DIALOGUE_2: new Dialogue2().run(); break; case DialogueState.END: // 对话全部完成,推进游戏 console.log("对话流程结束,进入下一阶段"); break; } } // 启动循环 gameLoop();
这些方案都比数组跟踪更高效,也更易维护。如果是同步绘制优先选方案1,异步动画选方案2,流程复杂选方案4。
内容的提问来源于stack exchange,提问作者Pandas Are Cool
相关产品推荐
相关产品推荐

