-1
\$\begingroup\$

I am making a 2D canvas game in JavaScript. I am trying to make the enemies shoot a bullet every 3 seconds.

for (var i = 0; i < enemyBullets.length; i++) {
    enemyBullets[i].show();
    enemyBullets[i].move();
}
// With this loop, whenever there is a bullet added to
// the array , it gets drawn on the canvas and updated.

function Enemy(x, y) {
   this.shoot = function(){
        var ebullet = new enemyBullet(this.x, this.y);
        enemyBullets.push(ebullet);
        // Here I have the enemy object and the function
        // which adds the bullet to the array.
    }
}

Here is how I use the enemy.shoot function in the draw() function, which is called via requestAnimationFrame():

function lol(){
    for(var v = 0; v<enemies.length;v++){
        enemies[v].shoot();
    }
}
setTimeout(lol,3000); // This is what I've tried so far

When I do this, the enemies are not shooting a single bullet every 3 seconds as desired. Instead, 3 seconds after the beginning of the program, they start adding infinite bullets to the array and I don't know how to handle it.

\$\endgroup\$
5
  • 1
    \$\begingroup\$ Are you starting a new timeout every time you draw a frame? This looks similar to the error explained in this answer - not javascript, but the same overall idea of "start your timer once, don't stack an ever-increasing collection of timers". \$\endgroup\$ Commented Oct 30, 2019 at 16:53
  • \$\begingroup\$ I actually struggle a little bit reading this code , since i'm a beginner and i only know javascript. If you have the time to explain it , can you please do that \$\endgroup\$ Commented Oct 30, 2019 at 17:07
  • 1
    \$\begingroup\$ The code is not the part to look at. That's for Unity and doesn't relate to your issue. The reason I linked to this was for the explanation of what happens when you trigger a new times interval every time you draw a frame. You're not saying "keep ticking the timer I told you to start last frame" — that happens anyway. Instead you're starting a new timer that will finish a frame after the previous one. Stack up enough of these, and your enemies shoot every frame instead of only once every 3 seconds, because you have a whole stack of timeouts completing one after the other. \$\endgroup\$ Commented Oct 30, 2019 at 17:12
  • \$\begingroup\$ I tried it without the for loop and it actually worked , it shot once for every 3 seconds , but... it only shot from the first enemy and there are two more left ... that's why i need to loop throught the array of enemies , so i can use the shoot function , for each of the elements every 3 seconds , but it seems that setInterval and loops don't work with each other or im doing something wrong ... \$\endgroup\$ Commented Oct 30, 2019 at 17:18
  • 2
    \$\begingroup\$ Does this answer your question? Making an enemy shoot every few seconds \$\endgroup\$ Commented Feb 6, 2020 at 7:35

1 Answer 1

0
\$\begingroup\$

Use setInterval instead This will make the function get called multiple times.

The other option is to put a setTimeout call inside the lol function so it will be rescheduled.

To stop the scheduled call you can pass the return value of the setInterval or latest setTimeout to clearInterval or clearTimeout resp.

\$\endgroup\$
1
  • \$\begingroup\$ I tried with setInterval , it does the same thing , they start shooting 3 seconds after the program starts and when they start , they do it very fast and there is no delay. \$\endgroup\$ Commented Oct 30, 2019 at 17:10

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.