0

I'm writing a version of Pong in Javascript. I have a Game object and I'm using the prototype property to define methods on it. I'm getting the following error: "Undefined is not a function". It is being thrown in the Game.prototype.step function so this.update is undefined in there. Here's the code for the Game object:

(function(root) {
  var Pong = root.Pong = (root.Pong || {});

  var Game = Pong.Game = function() {
    this.canvas = document.getElementById('canvas');
    this.canvas.width = 800;
    this.canvas.height = 400;
    this.context = canvas.getContext('2d');
    this.maxStartSpeed = 10;
    this.keysDown = {};
    this.player2 = new Pong.Player({'player': 2});
    this.player1 = new Pong.Player({'player': 1});
    this.ball = new Pong.Ball(400, 200);
  }

  Game.prototype.update = function() {
    this.player1.update();
    this.player2.update();
    this.ball.update(player1.paddle, player2.paddle);
  };

  Game.prototype.render = function() {
    this.context.fillStyle = "#bdc3c7";
    this.context.fillRect(0, 0, width, height);
    this.player1.render();
    this.player2.render();
    this.ball.render();
  };


  Game.prototype.animate =  function(callback) { 
    window.setTimeout(callback, 1000/60) 
  };

  Game.prototype.step = function() {
    this.update();
    this.animate(this.step);
  };

  window.addEventListener("keydown", function (event) {
    Game.keysDown[event.keyCode] = true;
  });

  window.addEventListener("keyup", function (event) {
    delete Game.keysDown[event.keyCode];
  });

  window.onload = function() {
    document.getElementById('canvas-container').appendChild(canvas);
    game = new Game();
    game.animate(game.step);
  };  

})(this);
  • `window.setTimeout(callback, 1000/60) ` changes the context of `callback` to `window`. `window.update` is not defined. – Kevin B Apr 14 '14 at 16:11
  • possible duplicate of [Pass correct "this" context to setTimeout callback?](http://stackoverflow.com/questions/2130241/pass-correct-this-context-to-settimeout-callback) – Kevin B Apr 14 '14 at 16:12

1 Answers1

1

The setTimeout is going to change the scope. To maintain the proper scope, you need to use bind

Change

this.animate(this.step);

to

this.animate(this.step.bind(this));

You need to do the same thing with the other animate calls.

epascarello
  • 204,599
  • 20
  • 195
  • 236