我正在尝试使用HTML5画布,JavaScript和XML制作一种游戏。 我们的想法是,您可以通过将问题和答案放在XML文件中来进行测验。 我写了一个主循环,循环遍历所有问题,构建它们并检查答案的正确性。 现在我只是使用警报和对话框来回答问题 问题是我的主循环是一个大的互连整体,从头到尾遍历整个游戏,而不是让警报框提出问题和对话框来回答,紧接着,我想要一些用户互动。 问题的答案显示在屏幕底部的框中,用户可以控制起重机选择正确的答案。 这是我坚持使用的主循环代码片段:
answer = loadQuestion(i);
if (answer == "correct") {
// answered correctly, update scoreArray and load next question
scoreArray[currentQuestion] = "correct";
// show 'next'-button and wait for press to continue
} else {
// answered incorrectly again, update scoreArray and load next question
scoreArray[currentQuestion] = "error";
// show 'next'-button and wait for press to continue
}
正如您所看到的,我正在调用loadQuestion,它会立即加载问题,显示可能的答案,现在立即抛出一个对话框,您可以在其中键入答案。 此答案将被返回并验证。
我已经编程了起重机的控制装置,用户已经可以拿起一个装有它的盒子。 但是因为我正在调用loadQuestion并期望它返回一个值,所以这不起作用。 如果玩家使用起重机给出答案,我该如何让我的主循环“暂停”,然后继续? 我已经尝试将答案作为一个全局变量,并且只需要一个空的而answer ==“”以保持函数忙于什么都不做,直到答案获得一个值,但这只是冻结了脚本。 我还试图监视应答变量的状态,并且在发生这种情况时清除间隔并返回值,但是这只是返回false,因为函数完成而没有立即返回值。
答案 0 :(得分:19)
如果玩家使用起重机给出答案,我该如何让我的主循环“暂停”,然后继续?
分手吧。 JavaScript中浏览器中唯一的“收益”是让你的函数结束,然后安排稍后回调(通过setTimeout
,setInterval
,ajax回调等)。在您的情况下,我倾向于认为触发回叫的触发器应该是用户回答上一个问题的操作,例如答案框上的click
处理程序或其他一些(而不是setTimeout
等等,这是自动化的。
例如,这段代码:
function loopArray(ar) {
var index;
for (index = 0; index < ar.length; ++index) {
doSomething(ar[index]);
}
}
......可以像这样重铸:
function loopArrayAsync(ar, callback) {
var index;
index = 0;
loop();
function loop() {
if (index < ar.length) {
doSomething(ar[index++]);
setTimeout(loop, 0);
}
else {
callback();
}
}
}
第二个版本在每次循环迭代时都会将控制权返回给浏览器。同样重要的是要注意第二个版本在 之前返回 完成循环,而第一个版本等待所有循环完成,这就是为什么第二个版本具有它完成循环后调用的callback
函数。
调用第一个的代码可能如下所示:
var a = ["one", "two", "three"];
loopArray(a);
// Code that expects the loop to be complete:
doTheNextThing();
doYetAnotherThing();
...而使用异步版本看起来像这样:
var a = ["one", "two", "three"];
loopArrayAsync(a, function() {
// Code that expects the loop to be complete:
doTheNextThing();
doYetAnotherThing();
});
这样做,你可能会发现你使用closures(loop
,上面是一个闭包),所以这篇文章可能很有用:Closures are not complicated
答案 1 :(得分:3)
没有同步。除了alert
,confirm
和prompt
之外,在浏览器JS中暂停了输入/输出工具。由于您不想使用它们 - 请尝试以下模式:
loadQuestion(i, function(answer) {
if (answer == "correct") {
// answered correctly, update scoreArray and load next question
scoreArray[currentQuestion] = "correct";
// show 'next'-button and wait for press to continue
} else {
// answered incorrectly again, update scoreArray and load next question
scoreArray[currentQuestion] = "error";
// show 'next'-button and wait for press to continue
}
resumeGameExecution();
});
即。当用户回答它时 - 回调函数会被执行,你知道你很高兴。
答案 2 :(得分:2)
根据我的理解,你有一个问卷调查申请,你会问一系列问题,然后要求用户使用拖放控件(起重机)放弃他的答案。
我要去切线说设计似乎是错的。 Javascript是基于事件的,并且有一个主要线程循环用于用户交互将降低可用性。我不会使用任何方式来停止线程(也就是在java中)。 Javascript不是为这样的用例编写的。某些浏览器和几乎所有性能分析器(如Yslow)都会将您的应用程序视为无响应。
所以我会给每个问题提供一个由一个内部是序列(问题1 ... 2)的类标识的div。最初只会启用或显示一个问题。一旦用户回答了问题,我将启用已启用的问题。 (在适当的事件中,在这种情况下可能是拖放的下降事件)。由于它是顺序的,我只需检查用户是否已回答问题1,然后我将适当地启用问题2。整个流程应该是事件驱动的。这里的事件是用户回答问题。