Skip to content Skip to sidebar Skip to footer

Html5 Canvas Images Are Not Loading Using Drawimage()

I'm following a tutorial on a flappy bird game by freeCodeCamp https://www.youtube.com/watch?v=pufKO5EG8nc But I'm doing it using a class to learn more about it. The problem is, th

Solution 1:

Your problem has to do with the scope - which refers to the accessibility of variables, objects and functions - and the meaning of the this keyword depending on the actual scope.

To get a better understanding let's have a look at the following example:

classGame {
  constructor() {
    console.log("Game constructor:", this);
    this.player = newImage();
    this.player.onload = this.draw;
    this.player.src = "https://picsum.photos/200/300";
  }

  draw() {
    console.log("draw:", this);
  }
}
let game = newGame();

If you click 'Run code snippet', you should see the following output in the console:

Gameconstructor: {}
draw: <imgsrc="https://picsum.photos/200/300"></img>

As you can see a call to this inside draw() does not refer to the same thing anymore. In the first case it's an object instance of Game (hinted by the curly brackets) and in the second case it's an instance of a HTMLImageElement.

So your code simply fails because:

this.loadedSprites += 1;
if (this.loadedSprites >= this.sprites) {

don't reference the Game class's private variables loadedSprites and sprites - in fact it doesn't refer anything at all as it's simply undefined within the scope of the draw function thus loadedSprites doesn't ever get incremented.

One workaround is passing the context of the Game class to each Image instance using a new property e.g. .reference.

this.player = new Image();
this.player.reference = this;
this.player.onload = this.draw;

and use it inside draw() like:

draw() {
     this.reference.loadedSprites += 1;
}

Here's a complete example based on your code:

const canvas = document.querySelector("#canvas");
classGame {
  constructor(c) {
    this.c = c; //canvasthis.ctx = c.getContext("2d"); // contextthis.sprites = 5;
    this.loadedSprites = 0;

    this.player = newImage(); // define imagesthis.player.reference = this;
    this.bg = newImage();
    this.bg.reference = this;
    this.fg = newImage();
    this.fg.reference = this;
    this.north = newImage();
    this.north.reference = this;
    this.south = newImage();
    this.south.reference = this;

    this.pX = 10; // player starting locationthis.pY = 150;

    // set sprite locations and load.this.player.onload = this.draw;
    this.player.src = "https://picsum.photos/id/237/20/20";

    this.bg.onload = this.draw;
    this.bg.src = "https://picsum.photos/id/22/20/20";

    this.fg.onload = this.draw;
    this.fg.src = "https://picsum.photos/id/30/20/20";

    this.gap = 80;
    this.constant = this.north.height + this.gap;

    this.north.onload = this.draw;
    this.north.src = "https://picsum.photos/id/37/20/20";

    this.south.onload = this.draw;
    this.south.src = "https://picsum.photos/id/137/20/20";
  }

  //draw imagesdraw() {
    let ref = this.reference;
    ref.loadedSprites += 1;
    if (ref.loadedSprites >= ref.sprites) {
      ref.ctx.drawImage(ref.bg, 0, 0);
      ref.ctx.drawImage(ref.north, 100, 0);
      ref.ctx.drawImage(ref.south, 0, 0 + ref.constant);
      ref.ctx.drawImage(ref.fg, 0, ref.c.height - ref.fg.height);
      ref.ctx.drawImage(ref.player, ref.pX, ref.pY);
    }
  }
}
let game = newGame(canvas);
<canvasid="canvas"width="512"height="512"></canvas>

Post a Comment for "Html5 Canvas Images Are Not Loading Using Drawimage()"