11

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 を呼び出して値を返すことを期待しているため、これは機能しません。クレーンを使用しているプレーヤーから応答が返されるまでメイン ループを「一時停止」してから続行するにはどうすればよいですか? 私はすでに答えをグローバル変数にしてみましたが、空のwhile answer == ""を使用して、答えが値を取得するまで関数をビジー状態に保ちましたが、これはスクリプトをフリーズさせるだけです。また、回答変数のステータスを監視するために間隔をいじり、間隔をクリアして、これが発生したときに値を返しますが、関数はすぐに値を返さずに完了するため、単に false を返します。

4

3 に答える 3

23

クレーンを使用しているプレーヤーから応答が返されるまでメイン ループを「一時停止」してから続行するにはどうすればよいですか?

それを壊すことによって。ブラウザーでの JavaScript の唯一の「利回り」は、関数を終了させて​​から、後で ( 、 、ajax コールバックなどを介して) コールバックされるように手配することsetTimeoutですsetInterval。あなたの場合、あなたに電話をかけるトリガーは、前の質問に答えるユーザーのアクション、たとえば、回答ボックスのハンドラーなど(自動化されているなどで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();
        }
    }
}

2 番目のバージョンでは、ループの反復ごとに制御がブラウザに返されます。2 番目のバージョンはループが完了するに戻ることに注意することも重要です。一方、最初のバージョンはすべてのループが完了するまで待機します。これが、2 番目のバージョンが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();
});

これを行うと、おそらくクロージャーを使用していることに気付くでしょう(loop上記の はクロージャーです)

于 2011-04-05T12:00:36.047 に答える
6

同期はありません。alertconfirmおよびを除くブラウザ JS の入出力ツールを一時停止しましpromptた。それらを使用したくないので、次のパターンを試してください。

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();
});

つまり、ユーザーが応答すると、コールバック関数が実行され、準備が整ったことがわかります。

于 2011-04-05T12:02:49.963 に答える
4

私が理解していることから、アンケートアプリケーションがあり、一連の質問をしてから、ユーザーにドラッグアンドドロップコントロール(クレーン)を使用して回答をドロップするように依頼します。

私は接線を取り、設計が間違っているようだと言います。Javascript はイベント ベースであり、ユーザー インタラクションのために 1 つのメイン スレッドがループすると、使いやすさが低下します。スレッドを停止する方法は一切使用しません (Java では別名)。Javascript は、そのようなユースケース用に作成されていません。アプリケーションは、一部のブラウザーやほとんどすべてのパフォーマンス アナライザー (Yslow など) によって応答がないと認識されます。

したがって、各質問に、内部的にシーケンス (question1..2) であるクラスによって識別される div を提供します。最初は 1 つの質問のみが有効または表示されます。ユーザーが質問に回答したら、有効な質問を有効にします。(適切なイベント、この場合はおそらくドラッグ アンド ドロップのドロップ イベント)。シーケンシャルなので、ユーザーが質問 1 に回答したかどうかを確認するだけでよく、質問 2 を適切に有効にします。フロー全体がイベント ドリブンである必要があります。ここでのイベントは、ユーザーが質問に回答したことです。

于 2011-04-05T12:12:30.357 に答える