我正在学习HTML5(和OO Javascript),并试图制作一个简单的游戏引擎,但渲染到画布在非常奇怪的条件下工作。这是该页面的链接,这是我的索引.html:
<html>
<head>
<script type="text/javascript">
function load()
{
var game = new Game();
game.start();
}
</script>
<title>Game</title>
<style>
canvas
{
outline:0;
border:1px solid #000;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body onload="load()">
<canvas id='c'></canvas>
<script src="classes/Tuple.js"></script>
<script src="classes/Rect.js"></script>
<script src="classes/Sprite.js"></script>
<script src="classes/Game.js"></script>
</body>
</html>
首次加载时,它将在Firefox 11.0中给出NS_ERROR_DOM_TYPE_MISMATCH_ERR异常,在Chrome 18.0中给出TypeError异常。要使其正常工作:
火狐 11.0
- 在地址栏中选择 URL,然后手动按回车键或
- 单击刷新按钮或
- 按 F5。
铬 18.0
- 在地址栏中选择 URL,然后手动按回车键或
- 单击刷新按钮或
- 按 F5 或
- 按 Shift/Ctrl + F5。
我怀疑 - 只是一个猜测,但似乎一个或多个.js文件在第一次页面加载期间调用时不可用/准备就绪。在Firebug中经历了几次之后,似乎精灵图像永远不会在第一页请求中加载。
也许一些.js文件仍在下载,因为正在对 Game() 进行实例化,然后缓存,并且只有在第二个页面加载时才能使用?
有什么想法吗?我很感激你的看法,谢谢!
我在本地复制了您的文件并进行了一些测试。在我看来,不可用的不是你的JavaScript文件,而是你的精灵。
在调用 Game.start
之前,您不会加载 PNG。 当您执行以下操作时:
roadSpritesheetImage.src = "assets/sprites/player/playerSpriteSheet.png";
这将开始映像的异步下载。其余代码在图像完全加载之前执行,因此当您对图像进行切片时,您将对其进行切片,就好像 src 属性为 null 一样。
这就是为什么您可以点击刷新并且一切都按预期工作的原因......图像被缓存。
您可以通过在画布之前添加图像标签来抢占精灵的加载:
<img src="assets/sprites/player/playerSpriteSheet.png" style="display:none;" />
这将起作用,因为在内容(包括图像)完全加载之前不会触发 body load 事件(我相信,我必须查找这个)。 然后,如果将此图像分配给img.src
,则将引用缓存的图像。
或者,您可以将游戏功能的其余部分绑定到 img.onload
.例如:
self.loadSprites = function()
{
var roadSpritesheetImage = new Image();
roadSpritesheetImage.onload = function() {
self.entities.push(new Sprite("testTile",
roadSpritesheetImage,
new Tuple(16, 16),
new Rect(0, 0, 32, 16)));
self.run();
};
roadSpritesheetImage.src = "assets/sprites/player/playerSpriteSheet.png";
};
self.run = function() {
var drawSuccessful = false;
drawSuccessful = self.entities[0].draw(self.context);
self.entities[0].nextFrame();
//if we managed to draw the Sprite successfully without any raised exceptions
if(drawSuccessful) {
setTimeout(self.run, 300);
} else { alert("stopping execution of the game."); }
};
self.start = function()
{
self.loadSprites();
};
这样做会更干净一些,它可以保证你的资源没有任何竞争条件。
我创建的jQuery插件也遇到了类似的问题,该插件用于从源图像绘制N拼图。 我发现这个 MDN 文档当时非常有用,尽管我最终使用了切片div 而不是画布。