0

関数 PS.Tick() は 100 ミリ秒ごとに呼び出され、その仕事は NPC の AI 関数を呼び出して移動できるようにすることです。

PS.Tick = function ()
{
"use strict";
for (NPCid = 0; NPCid < NPCnumber; NPCid++)
{
    NPCAI(NPCid);
};
}; 

しかし、NPC が 100 ミリ秒ごとに同時に移動するのではなく、独自の頻度で移動するようにしたいので、次のコードを試しました。

PS.Tick = function ()
{
"use strict";
for (NPCid = 0; NPCid < NPCnumber; NPCid++)
{
    var timeout = 0;
    timeout = PS.Random (1000);
    setTimeout("NPCAI(NPCid)",timeout);
};
};

今、彼らはまったく動かない。なんで?それらを異なる時間間隔で移動させるにはどうすればよいですか?

4

3 に答える 3

2

それを作る

for (NPCid = 0; NPCid < NPCnumber; NPCid++) {
    var timeout = 0;
    timeout = PS.Random (1000);
    (function (id) {
        setTimeout(function(){NPCAI(id)},timeout);
    })(NPCid); };

クロージャで ID をキャプチャするには、その追加の関数が必要です。これがないと、ループの最後の ID のみが各インスタンスに渡されます。

于 2012-07-09T15:46:40.523 に答える
0

今、彼らはまったく動かない。なんで?

いくつかの理由が考えられます:

  • どこにも宣言されていない場合NPCid: あなたのコードはReferenceError.

  • NPCidがどこかで宣言されているがグローバルではない場合: 文字列を に渡すとsetTimeout、現在の実行コンテキストで評価されず、 にアクセスできませんNPCid。一般に、文字列を に渡さないでくださいsetTimeout

  • がグローバルの場合NPCid: 遅延コードが実行されると、ループの最後NPCidの値であるに対してすべて同じ値が表示されます。

代わりに: NodeJS でこれを行っている場合 (私はあなたがしていることからこれを推測しているだけです)、これを行うことができます):

PS.Tick = function ()
{
    "use strict";

    // (I'm assuming NPCid is defined somewhere; if not, add `var NPCid;` here)

    for (NPCid = 0; NPCid < NPCnumber; NPCid++)
    {
        var timeout = 0;
        timeout = PS.Random (1000);
        setTimeout(NPCAI, timeout, NPCid); // NodeJS (and Firefox) ONLY!!
    }
};

NodeJS (および Firefox) では、setTimeout呼び出す関数に渡す引数を受け入れることができるため、これは機能します。

NodeJS または Firefox を使用していないが、ES5 のFunction#bindにアクセスできる場合は、次のようにすることができます。

PS.Tick = function ()
{
    "use strict";

    // (I'm assuming NPCid is defined somewhere; if not, add `var NPCid;` here)

    for (NPCid = 0; NPCid < NPCnumber; NPCid++)
    {
        var timeout = 0;
        timeout = PS.Random (1000);
        setTimeout(NPCAI.bind(undefined, NPCid), timeout);
    }
};

Function#bindthis呼び出されると、特定の値と指定した引数で元の関数を呼び出す関数を返します。

そうでない場合は、独自の を作成するか、次のようにすることができますbind

PS.Tick = function ()
{
    "use strict";

    // (I'm assuming NPCid is defined somewhere; if not, add `var NPCid;` here)

    for (NPCid = 0; NPCid < NPCnumber; NPCid++)
    {
        var timeout = 0;
        timeout = PS.Random (1000);
        setTimeout(makeHandler(NPCid), timeout);
    }

    function makeHandler(id) {
        return function() {
            NPCAI(id);
        };
    }
};

これは、呼び出されたときに向きを変えて、渡した値で NPCAI を呼び出す関数を作成することで機能します。

于 2012-07-09T15:50:38.933 に答える
-1

あなたの setTimeout は関数を呼び出しません。

これを試して:

setTimeout(function(){ NPCAI(NPCid); }, timeout);

または、各 NPC に個別に設定された間隔を使用することをお勧めしますが、多くのタイムアウトと間隔を使用することは非常に非効率的であるため、遅延に注意して準備してください。

于 2012-07-09T15:48:49.387 に答える