0

As an exercise, I went through this tutorial, then attempted to create a version that puts everything into its own class to clean it up so I can add some of my own additions. The issue is that I am running into an error that doesn't seem to make any sense. (all the commented stuff is filled in on my end, but it didn't seem relevant to the question) Uncaught TypeError: Cannot read property 'lastRender' of null at loop (game-loop.js:13)

class GameLoop {
  constructor(player, canvas) {
    // Set other variables
    this.lastRender = 0;
    window.requestAnimationFrame(this.loop);
  }

  loop(timestamp) {
    let progress = timestamp - this.lastRender; // This is ln. 13 in the actual program

    this.update(progress);
    this.draw();

    this.lastRender = timestamp;
    window.requestAnimationFrame(this.loop);
  }

  update(progress) {
    // Update function
  }

  draw() {
    // Draw function
  }

}

Additionally when I remove the lastRender variable from the class, it stops giving me that error, but instead says Uncaught TypeError: Cannot read property 'update' of null at loop (game-loop.js:15)

Zelkins
  • 723
  • 1
  • 5
  • 22

1 Answers1

3

You will need to use .bind() to make this have the right value. Change this:

window.requestAnimationFrame(this.loop);

to this:

window.requestAnimationFrame(this.loop.bind(this));

When you pass a method as a callback as you are doing with this.loop, the value of this is not passed, only the reference to the method. So, when window.requestAnimationFrame() calls loop() it isn't calling it in a way that will make this have the right value inside the method and thus you get the error you see when you try to use this.anything.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • I tried this already but it didn't seem to change anything so I took it out. – Zelkins Dec 27 '17 at 06:30
  • Also what is the difference between using bind and not? – Zelkins Dec 27 '17 at 06:30
  • @ZacharyElkins - You need to use it all places you pass a method as a callback (at least the two places you show `window.requestAnimationFrame()`. There's more explanation in my answer now. – jfriend00 Dec 27 '17 at 06:31
  • Weirdly enough, It works now. I might have forgotten something maybe? Odd. – Zelkins Dec 27 '17 at 06:32
  • Continuing the same logic, `this.loop=this.loop.bind(this)` in the constructor allows `loop` to be passed to the animation requests without binding it on every iteration. – traktor Dec 27 '17 at 06:41
  • @traktor53 - Yes, that would work too. – jfriend00 Dec 27 '17 at 07:15