菲利普的答案已经显示出正确的方向。我只是认为数据结构是多余的。较短的文本将更易于编写和阅读。
即使较短的文本会使算法更复杂,这也是值得做的,因为您只编写一次算法,但是大部分时间将花在编写和维护故事上。因此,请进行优化以简化您将花费大部分时间的零件。
var story = [
{ m: "Hi!" },
{ m: "This is my new game." },
{ question: "Do you like it?", answers: [
{ m: "yes", next: "like_yes" },
{ m: "no", next: "like_no" },
] },
{ label: "like_yes", m: "I am happy you like my game!", next: "like_end" },
{ label: "like_no", m: "You made me sad!", next: "like_end" },
{ label: "like_end" },
{ m: "OK, let's change the topic" }
];
此设计的一些解释:
整个故事写成一个数组。您不必提供数字,它们是由数组语法自动提供的:第一项的索引为0,下一项的索引为1,依此类推。
在大多数情况下,无需写下后续步骤的编号。我假设大多数文本行都不是分支。让我们将“下一步是下一个项目”作为默认假设,仅在其他情况下进行注释。
对于跳跃,请使用标签,而不是数字。然后,如果您以后添加或删除几行,则故事的逻辑将被保留,而您无需调整数字。
在清晰度和简短度之间找到合理的折衷方案。例如,我建议写“ m”而不是“ message”,因为这将是有史以来最常用的命令,因此将其缩写将使文本更易读。但是无需缩短其余关键字。(但是,您可以根据自己的意愿进行操作。重要的是使它对您而言最易读。或者,您可以同时支持“ m”和“ message”作为有效关键字。)
游戏的算法应如下所示:
function execute_game() {
var current_line = 0;
while (current_line < story.length) {
var current_step = story[current_line];
if (undefined !== current_step.m) {
display_message(current_step.m);
if (undefined !== current_step.next) {
current_line = find_label(current_step.next);
} else {
current_line = current_line + 1;
}
} else if (undefined !== current_step.question) {
// display the question: current_step.question
// display the answers: current_step.answers
// choose an answer
// and change current_line accordingly
}
}
}
顺便说一句,这些想法是受Ren'Py启发的,Ren'Py并不是您想要的(不是JavaScript,不是Web),但是无论如何都会给您一些很酷的想法。