0
\$\begingroup\$

I am getting the following error ONLY when running my game in Firefox (3.6)

Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage]

The issue does not occur in the other major browsers, and my game runs completely fine after I click 'OK.'

Here are a few snippets of code where I have localized the issue to. Has anybody seen this issue before? According to Google it has something to do with drawing the image before it is loaded, but from my understanding I am loading it properly before using it!.

player class

var player = new (function(){
  var that = this;
  that.image = new Image();
  that.image.src = "res/enemy1_sprites.png";
  that.width = 16;
  that.height = 16;
  that.frames = 2;
  that.actualFrame = 0;
  that.spriteXoffset = 0;
  that.spriteYoffset = 0;
  that.moved = false;
  that.boundary = false;
  that.num_balls = 5;
  that.rootX = 350;
  that.rootY = 250;
  that.ballX = [that.rootX,0,0,0,0];
  that.ballY = [that.rootY,that.rootY,that.rootY,that.rootY,that.rootY];

  that.directions = {"up":0, "right":1, "down":2, "left":3};
  that.dirs  = [that.directions.right,that.directions.right,that.directions.right,that.directions.right,that.directions.right];

  for (i = 1; i < that.num_balls; i++)
    that.ballX[i] = that.rootX - (i * that.width);

...
...

that.draw = function(){
    try {
      for (var i = that.num_balls-1; i >= 0; i--)
      {
        // update animation
        switch (that.dirs[i])
        {
          case that.directions.left:
            that.moveLeft();
          break;
          case that.directions.right:
            that.moveRight();
          break;
          case that.directions.up:
            that.moveUp();
          break;
          case that.directions.down:
            that.moveDown();
          break;
        }
        ctx.drawImage(that.image, that.spriteXoffset, that.spriteYoffset, that.width, that.height, that.ballX[i], that.ballY[i], that.width, that.height);
      }
    } 
    catch (e) {
      alert(e.message);
    };

    if (that.moved)
    {
      if (that.spriteYoffset > 0)
        that.spriteYoffset = 0;
      else
        that.spriteYoffset += 16;
      that.moved = false;
    }
  }
})();

game loop

 var GameLoop = function(){
    ..
    ..
     player.move();
     player.draw();
    ..
    ..
      if (state)
        gLoop = setTimeout(GameLoop, GAME_SPEED);
    }
\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

The javascript is loaded and starts executing before you load the image, as you pointed out. When you do:

that.image = new Image();
that.image.src = "res/enemy1_sprites.png";

You are starting to load it, but then the javascript continues executing and reaches your line

ctx.drawImage(that.image, that.spriteXoffset, that.spriteYoffset, that.width, that.height, that.ballX[i], that.ballY[i], that.width, that.height);

... without knowing if the image is loaded or not. You need to check for that. The question is where to wait for the image to be loaded. An easy option is to modify your draw() function, so that the line I just quoted above this paragraph becomes:

if (that.image.complete)
    ctx.drawImage(that.image, ...)

But in this case you will be updating the whole game before being able to show it. It would be better to make the game wait for the image to be loaded. Then the game loop becomes something like:

..
if (player.image.complete) {
    player.move();
    player.draw();
}
..

If you have more than one image in your game (and not just the player one), you should wait for all of them to be loaded before launching the GameLoop function. This way you don't have to introduce extra checks within your game code. You can do that by launching a function with a timeout that periodically checks if all of them are loaded. When the condition is met, then you can launch GameLoop. But that is just an idea, there might be better ways.

\$\endgroup\$
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .