GuardianX GuardianX - 21 days ago 7
Javascript Question

Canvas game Error

I'm trying to create a simple game loop and trying to use OOP paradigm in JS. Here is my code:

HTML

<body onload="Game.OnLoad('gameField')" onkeydown="Game.KeyDown(event)">
<p id="info">1</p>
<p id="info2">2</p>
<canvas id="gameField"
width="896px"
height="717px"
class="game-field"
style="border: 4px solid aqua"
onclick="Game.MouseClick(event)"></canvas>
</body>


JavaScript

// class Timer
// version: 1
// only tick() functionality available
// right now
function Timer() {
var date = new Date();

var prevTick = 0;
var currTick = 0;
// update timer with tick
this.tick = function() {
prevTick = currTick;
currTick = date.getTime();
}
// get time between two ticks
this.getLastTickInterval = function() {
return currTick - prevTick;
}
}

// global object Game
// which handles game loop
// and provide interfaces for
var Game = new function() {
// variables:
this.canvas = 0;
var gameLoopId = 0;
this.timer = new Timer();
// events:
this.KeyDown = function(e) {}

// game loop:
this.Run = function() {
this.timer.tick();
this.Update(this.timer.getLastTickInterval());
this.Draw();
}
this.Update = function(dt) {
document.getElementById("info").innerHTML = dt;
}
this.Draw = function() {}
this.StopGameLoop = function() {
clearInterval(gameLoopId);
}
this.OnLoad = function(canvasName) {
this.canvas = document.getElementById(canvasName);
this.timer.tick();

// start game loop
setInterval(this.Run, 1000);
}
}‚Äč


(Fiddle)

I'm trying to make Game class global. Other classes must be instantinated using
new
.

Classes Game and Timer are placed in different files called Game.js and Timer.js. When I run this code in Chrome I got an error in DevTools:
"Uncaught TypeError: Cannot call method 'tick' of undefined"
in
Game.Run
function at the line
this.timer.tick();


So I wonder, what is the problem with my code? Thanks for reply.

Answer

Your problem is with the context. When you're calling tick this is window, not Game. You can handle this, for example, by setting:

var self = this;        
this.Run = function() {
    self.timer.tick();
    self.Update(self.timer.getLastTickInterval());
    self.Draw();
}
Comments