When I try to run the following code, on my console log, I get "Done!!", instead of getting
currentFrame=0
sourceX=0
It's suppose to have a counter, and with and interval of every 300 millisecond, it's suppose to update the "currentFrame" and "sourceX" variable. The condition is true nevertheless It doesn't output anything but "Done!!".
The following is my code:.
var canvas = document.querySelector("canvas");
var drawingSurface = canvas.getContext("2d");
var tileSheet = new Image();
tileSheet.src="frames.png";
var msperFrame = 300;
var interval;
SIZE=128;
tileSheet.addEventListener("load",loadHandler,false);
var monster={
frames:6,
SIZE:128,
currentFrame:0,
sourceX:0,
sourceY:0,
updateAnimation: function(){
var self=this;
if(self.currentFrame <= self.frames){
self.sourceX = self.currentFrame*this.SIZE;
console.log("Current Frame: "+self.currentFrame+"\nSourceX: "+self.sourceX);
self.currentFrame++;
render();
}else{
console.log("Done!!");
window.clearInterval(interval);
}
}
};
function loadHandler(){
interval = window.setInterval(monster.updateAnimation,msperFrame);
}
function render(){
drawingSurface.drawImage(tileSheet,
monster.sourceX,monster.sourceY,monster.SIZE,monster.SIZE,
0,0,monster.SIZE,monster.SIZE);
}
Now that's a funny bug :-)
Your problem is this
: When run by setTimeout
or setInterval
, it defaults to window
, not monster
. Try this:
interval = window.setInterval(function(){monster.updateAnimation();},msperFrame);
By wrapping it inside an anonymous function, you should be fine. You're getting "Done!!" because both properties in if (window.currentFrame <= window.frames)
are undefined.
Side notes:
You're using this.SIZE
instead of self.SIZE
.
300 ms per render loop might produce a chunky animation.
window.setInterval(monster.updateAnimation,msperFrame);
will in effect get translated into
window.setInterval(function(){
var self=this; //here 'this' is window
if(self.currentFrame <= self.frames){
self.sourceX = self.currentFrame*this.SIZE;
console.log("Current Frame: "+self.currentFrame+"\nSourceX: "+self.sourceX);
self.currentFrame++;
render();
}else{
console.log("Done!!");
window.clearInterval(interval);
}
},msperFrame);
This function will be run from global
scope, or from window
scope. So this
will be window
object.
When you do
window.setInterval(function(){monster.updateAnimation();},msperFrame);
as @erik suggested http://jsfiddle.net/Vn3s7/
function(){monster.updateAnimation();}
will be run from window
scope. As monster
is available as global
in window
scope, 'moster.updateAnimation' is available and will be called with this
pointer as monster
itself.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.