Reputation: 31
I'm trying to add sprites to my game engine and I've tried a whole bunch of things. The problem is that the game can run but my image never shows. EDIT: I have found by putting the image and src in the coin class constructor makes it render.
I've tried window.onLoad, img.onLoad, putting the vars in the constructor, splitting it into 2 functions (load and draw).
class gameObject {
constructor(x,y,id){
this.x = x;
this.y = y;
this.id = id;
var velX, velY, width, height;
}
drawRect(){
c.fillRect(this.x, this.y, this.width, this.height);
}
drawSprite(url){
this.img = new Image();
this.img.src = url;
this.img.onload = function(){
function draw(){
c.drawImage(this.img, this.x, this.y, this.width, this.height)
}
draw();
}
}
move(){
this.x += this.velX;
this.y += this.velY;
}
}
class Coin extends gameObject{
constructor(x,y,id,img){
super(x,y,id);
this.velX = 0;
this.velY = 0;
this.width = 32;
this.height = 32;
}
tick(){
this.move();
}
render(){
this.drawSprite("coin.png");
}
}
I need the image to show but it doesn't show and the game still runs.
Upvotes: 0
Views: 3897
Reputation: 19301
As per MDN, the value of this
is undefined
in function draw
because it's a nested function inside a class declaration - and class declarations are parsed in strict mode.
One solution is to
draw
so it captures the lexical this
value when it is assigned to a variable,this
value refers to the class instance instead of the image element, andonload
handlers before setting their src
attribute:drawSprite(url){
let draw = ()=>c.drawImage(this.img, this.x, this.y, this.width, this.height);
this.img = new Image();
this.img.onload = draw;
this.img.src = url;
}
Further testing showed that CanvasRenderingContext2D method drawImage
can not handle undefined values for x and y, and will draw nothing if they are.
class gameObject {
constructor(x,y,id){
this.x = x || 0; // default x and y to zero
this.y = y || 0;
this.id = id;
var velX, velY, width, height;
}
Defaulting undefined values to zero should help gettting further along with development.
Upvotes: 1
Reputation: 31
Ok so the only solution I found was to move this.img & this.img.src to the class as shown here
class Coin extends gameObject{
constructor(x,y,id){
super(x,y,id);
this.velX = 0;
this.velY = 0;
this.width = 32;
this.height = 32;
this.img = new Image();
this.img.src = "coin.png";
}
tick(){
this.move();
}
render(){
this.drawSprite()
}
}
and also apparently when waiting for the img to load also causes it to not show up so i just did this.
drawSprite(){
c.drawImage(this.img, this.x, this.y, this.width, this.height);
}
I am also keeping it as the draw sprite function because I am going to make it also read from sprite sheets
Upvotes: 0