I am making a 2d canvas game in Javascript. I am trying to make the enemies that are coming to my hero to shoot a bullet every 3 seconds.

for (var i = 0; i < enemyBullets.length; i++) {
        }//which this statement , 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 in requestAnimationFrame();:

function lol(){
            for(var v = 0; v<enemies.length;v++){
setTimeout(lol,3000);//this is what ive tried so fa

when i do this , the enemies are shooting not a single bullet every 3 seconds but after 3 seconds of the beggining of the program , they start adding infinity bullets to the array and i don't know how to handle it.

  • 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\$ – DMGregory Oct 30 '19 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\$ – Chrissisbeast Oct 30 '19 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\$ – DMGregory Oct 30 '19 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\$ – Chrissisbeast Oct 30 '19 at 17:18
  • \$\begingroup\$ Does this answer your question? Making an enemy shoot every few seconds \$\endgroup\$ – Lovro Feb 6 '20 at 7:35

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.

  • \$\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\$ – Chrissisbeast Oct 30 '19 at 17:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.