0

I have been bashing my head on this and I know that it's probably an easy fix but I can't for the life of me figure out what is wrong. I am trying to call a class function within a for loop and I've tried a few methods but i've come up with diddly-squat so far. I'll plug in the relevant snippets below. For reference this is a project to make a web-based simple game and I've chosen a bastardization of galaga and asteroids hence, "ship" and "asteroids." My question is why won't it populate the class function .spawn(); that's been assigned to the items in the "rock" iterative? Any advice would be extremely helpful.

var rock = []; //I know global variables = evil, but I'm still early in development

function setup() {
...
//Asteroids
  for(var i = 0; i<5; i++){
    var y = random(0,350);
    var speed = random(2,5);
    rock.push(new asteroid(800,y,speed,10));
  }
 ...
 }
 
 function draw() {
...
 //Spawn Asteroids
 //rock[0].spawn(); //<-------Single instance of object from array(works as intended)

  /*for (let c of rock){  //<-------Tried changing variable type to const as well because I was pulling my hair out and that did nothing either. 
    this.spawn();
  }*/

  /*for (let c in rock){  //<-------Covering my bases
    this.spawn();
  }*/

  rock.forEach(index => this.spawn()); //<------Last thing I tried
 
...
 }
 //////////////////////////////////////////////////////////////////////////////
 class asteroid {
 
...
 
 spawn(){
      this.move();
      this.display();
      this.offScreen();
      this.speed = random(2,5);
    }
...

}
////////////////////////////////////////////////////////////////////////////////////////////
Note: I tried to create a facsimile of another for loop that I used for
the ship attack but it didn't work either. It's this snippet below.

    draw(){
        this.bullets.forEach((bullet) => {
              if(this.isBulletOffScreen(bullet)){
                  const index = this.bullets.indexOf(bullet);
                  this.bullets.splice(index, 1);
              }  
            bullet.draw();
        });
    }

I don't have the one I tried to adapt because I felt I was way over complicating a simple object so I erased it but this is the working code for the projectile controller class that I was copying from.

P.S. Here is the Error message I keep getting.

* p5.js says: [sketch.js, line 86] "spawn" could not be called as a function. Verify whether "this" has "spawn" in it and check the spelling, letter-casing (JavaScript is case-sensitive) and its type.

** Uncaught TypeError: this.spawn is not a function at draw (sketch.js:86:10) at p5._main.default.redraw (p5.js:71990:27) at _draw (p5.js:64140:25) ​**

Zack
  • 13
  • 2
  • `index.spawn()`, `this` doesn't refer to an instance of `rock` in the callback. – Teemu Mar 31 '22 at 16:25
  • Does this answer your question? [How to access the correct \`this\` inside a callback](https://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-inside-a-callback) – Jared Smith Mar 31 '22 at 16:27
  • when I use rock[c] it doesn't work either and if I'm not mistaken, which I very well could be, with the implementation of thisArg this.spawn(); should still reference the instance. I could be wrong though. Also, I've tried using an established variable like "var self = this;" and it didn't work either. – Zack Mar 31 '22 at 16:29
  • `rock` is an array of instances of `asteroid` class. `forEach` iterates through these instances, and `index` refers to the current instance in the iteration. Hence `index.spawn()` calls `spawn` method in that instance with correct `this` value. If the asteroids are still not moving, there's something else wrong in the code too. – Teemu Mar 31 '22 at 16:32
  • @Teemu They won't populate at all, not just unmoving The whole thing freezes with those error codes and when I instance it as a single object the function works perfectly, it's something with accessing that function in a for loop. I've even used a basic for loop iterating through rock[0-4] and that won't work either. – Zack Mar 31 '22 at 16:39
  • What ever it is, if [the fix](https://jsfiddle.net/w7udftgL/) I've suggested above doesn't work, then the error is somewhere outside of the example code. – Teemu Mar 31 '22 at 16:46
  • @Teemu I think I misunderstood before because I made the adjustment that you showed in your link and it started working. Thank you so much. I'm sure I tried that before but I must have made an error. – Zack Mar 31 '22 at 16:54

1 Answers1

0

@Teemu had the answer and it took a bit for my thick skull to work it out. By adjusting the forEach to resemble this:

rock.forEach(index => index.spawn());

They spawn and now I can start moving forward again. Thank you again Teemu!

Zack
  • 13
  • 2