简体   繁体   中英

How to solve this setInterval issue?

I'm having trouble with setInterval. In my game I want the player to be able to shoot an arrow, but every time he shoots the arrows are going faster! This is the arrow constructor:

arrows = [];

Arrow = function(x, y, followX, followY) // (player.x, player.y, followX, followY)
{
     ar = this;

     ar.rect = [x, y, 28, 3];

     ar.x = x;
     ar.y = y;

     ar.followX = followX;
     ar.followY = followY;

     if(ar.followY - ar.y < 0)
     {
          ar.where = [-(((ar.followX - ar.x)/200)/((ar.followY - ar.y)/200)), -1];
     }
     else
     {
          ar.where = [(((ar.followX - ar.x)/200)/((ar.followY - ar.y)/200)), 1];
     }

     ar.flying = setInterval(function()
     {
          ar.rect[0] += ar.where[0]/10;
          ar.rect[1] += ar.where[1]/10;
     }, 1);

     ar.fall = setTimeout(function()
     {
          for(a = 0; a < arrows.length; a++)
               if (arrows[a] == ar)
               {
                    clearInterval(ar.flying);
                    arrows = sliceHere(arrows, a);
               }
     }, 1000);
}

So the general idea is that the arrow flies for one second, and then gets deleted.

This is how and arrow gets created:

fireArrow = function(player)
{
     arrows.push(new Arrow(player.rect[0] + player.rect[2] - 1, player.rect[1] + player.rect[3]/2 - 10, player.rect[0] + player.mouse.x - sx/2, player.rect[1] + player.mouse.y - sy/2));
}

After that, I'm just drawing arrows on the screen, I also always fire from the same spot, and in the same direction.

Not sure if this is the only problem, but you should change this line:

ar = this;

to

var ar = this;

And the same for your a loop counter.

At the moment you don't use var anywhere which means all of your variables are global.

Which in general is going to lead to all kinds of confusion, but more specifically means that if you fire multiple arrows, each will kick off its own setInterval but the references to ar in the interval function will all refer to the same global variable and so will all move the most recently fired arrow thus making it speed up.

Declare ar with var and it becomes local to the Arrow function (but is still accessible to functions nested inside that function like the ones you create for your setInterval ). The magic of closures means each of your intervals will refer only to the now local ar from the surrounding scope and each arrow will become properly independent.

The only time you should ever use a variable without declaring it with var is when you specifically want to create a global from within a function. And even then you should ask yourself if that's the best way to go.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM