Now, they don't move at all. Why?
A couple of possible reasons:
If NPCid
isn't declared anywhere: Your code is throwing a ReferenceError
.
If NPCid
is declared somewhere but it's not a global: When you pass a string into setTimeout
, it doesn't get evaluated in the current execution context and doesn't have access to NPCid
. In general, don't pass strings into setTimeout
.
If NPCid
is a global: When the delayed code is executed, they'll all see the same value for NPCid
, which is its value at the end of the loop.
Instead: If you're doing this on NodeJS (I'm just inferring this from what you're doing), you can do this):
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!!
}
};
That works because on NodeJS (and Firefox), setTimeout
can accept arguments to pass to the function to call.
If you're not using NodeJS or Firefox, but you do have access to ES5's Function#bind
, you can do this:
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#bind
returns a function that, when called, will call the original function with a specific this
value and the arguments you give it.
If not, you can write your own bind
, or do it like this:
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);
};
}
};
That works by creating a function that, when called, turns around and calls NPCAI with the value we pass into it.