1

我正在学习 HTML5(和 OO Javascript),并且正在尝试制作一个简单的游戏引擎,但渲染到画布在非常奇怪的条件下工作。是该页面的链接,这是我的 index.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 并手动按 Enter 或
  • 单击刷新按钮或
  • 按 F5。

铬 18.0

  • 在地址栏中选择 URL 并手动按 Enter 或
  • 单击刷新按钮或
  • 按 F5 或
  • 按 Shift/Ctrl + F5。

我怀疑- 只是一个猜测,但似乎一个或多个 .js 文件在第一页加载期间被调用时不可用/准备就绪。在 Firebug 中经历了几次之后,精灵图像似乎永远不会在第一页请求中加载。

也许一些 .js 文件仍在被下载,因为正在对 Game() 进行实例化,然后被缓存,并且只有在第二个页面加载时才可用?

有任何想法吗?非常感谢您的采纳,谢谢!

4

1 回答 1

3

我在本地复制了您的文件并进行了一些测试。在我看来,不是你的 JavaScript 文件不可用,而是你的精灵。

在调用Game.start. 当你这样做时:

roadSpritesheetImage.src = "assets/sprites/player/playerSpriteSheet.png";

这将开始异步下载图像。其余代码在图像完全加载之前执行,因此当您对图像进行切片时,您将其切片,就好像 src 属性为空一样。

这就是为什么你可以点击刷新并且一切都按预期工作......图像被缓存。

您可以通过在画布之前添加图像标签来抢占精灵的加载:

<img src="assets/sprites/player/playerSpriteSheet.png" style="display:none;" />

这会起作用,因为在内容(包括图像)完全加载之前不会触发正文加载事件(我相信,我必须查一下)。然后,如果将此图像分配给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();
};

这样做会更干净一些,并且可以保证您的资源没有任何竞争条件。

我为从源图像绘制 N 拼图而创建的 jQuery 插件遇到了类似的问题。当时我发现这个 MDN 文档非常有用,尽管我最终使用了切片 div 而不是画布。

于 2012-04-06T04:23:52.893 回答