canvas drawImage第一次不绘制图像

5
我正在使用HTML5画布制作一个简单的JavaScript游戏。它是一个非常典型的游戏循环设置,包括:
  • init()函数初始化用于playfield的对象,随机一些起始x/y位置和类似的设置任务
  • draw()函数绘制所有游戏对象,包括一些简单的画布形状和几个图像
  • setInterval每25毫秒调用一次draw()
在开始这个项目时,我将setInterval调用放在init()函数的末尾,这样它会在加载页面后立即开始绘制和动画,一切都正常。现在我想在加载时绘制一个完整的静态playfield,然后使用按钮启动主游戏循环间隔。因此,我在init()的末尾添加了一个对draw()的单次调用,问题是当我这样做时,所有的画布形状都被正确地绘制,但是没有任何图像呈现在画布上。
如果让draw()运行几次,它们确实会呈现。
    var previewDraw = setInterval(draw, 25);
    var stopPreviewDraw = function() { clearInterval(previewDraw) }
    setTimeout(stopPreviewDraw, 100)

...但这似乎很愚蠢。为什么一次调用draw()不起作用呢?我在Chrome和Firefox的控制台中记录了这些对象,它们的所有内容看起来都很好;它们已经具有适当的img src路径和开始x/y值可用于传递给创建的新Image(),然后通过我的canvas.2dcontext.drawImage()方法进行调用。

我正在Chrome 6和Firefox 3.6.10中进行测试,它们的行为都让我感到困惑。Chrome的控制台中没有错误或问题,但是如果我尝试只调用一次draw(),Firefox会抛出以下错误:

未捕获的异常:[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMCanvasRenderingContext2D.drawImage]" nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)" location: "JS frame :: http://localhost/my-game-url/ :: drawItem :: line 317" data: no]

我在Google上搜索该错误时建议是图像损坏,但是它们都可以在Preview和Photoshop中打开,没有任何问题。

1个回答

8
我假设你是在窗口对象的onload事件之后调用init()。问题是,这并不能保证在那个时候图像数据已经可用。据我所知,它会在图像从网络获取后触发,但此时仍需要对其进行解码。
你最好等待图像的onload事件。

嗯...不行,因为这是一个练习项目,我太专注于我正在学习的新东西,完全忘记了显而易见的事情(我只是在页面底部内联运行它)。由于图片资源不是很多且都很小,所以在window.onload上运行init()就可以很好地处理这个问题。非常感谢,Jakub。 - RwwL
最终,我想我会用数据URL替换所有的外部图像。 - RwwL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接