Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/476.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML5画布渲染奇怪_Javascript_Html_Canvas_Rendering_Typeerror - Fatal编程技术网

Javascript HTML5画布渲染奇怪

Javascript HTML5画布渲染奇怪,javascript,html,canvas,rendering,typeerror,Javascript,Html,Canvas,Rendering,Typeerror,我正在学习HTML5和OOJavaScript,并试图制作一个简单的游戏引擎,但渲染到画布的工作条件非常奇怪。是指向该页面的链接,这是my index.html: 第一次加载时,它会在Firefox11.0中出现一个NS_错误、DOM_类型、不匹配、错误异常,在Chrome18.0中出现一个TypeError异常。要使其发挥作用: Firefox11.0 在地址栏中选择URL,然后手动按enter或 单击刷新按钮或 按F5。 铬18.0 在地址栏中选择URL,然后手动按enter或 单击刷新

我正在学习HTML5和OOJavaScript,并试图制作一个简单的游戏引擎,但渲染到画布的工作条件非常奇怪。是指向该页面的链接,这是my index.html:

第一次加载时,它会在Firefox11.0中出现一个NS_错误、DOM_类型、不匹配、错误异常,在Chrome18.0中出现一个TypeError异常。要使其发挥作用:

Firefox11.0 在地址栏中选择URL,然后手动按enter或 单击刷新按钮或 按F5。 铬18.0 在地址栏中选择URL,然后手动按enter或 单击刷新按钮或 按F5或 按Shift/Ctrl+F5组合键。 我怀疑的是-只是猜测,但在第一次页面加载期间调用.js文件时,似乎有一个或多个.js文件不可用/未就绪。在Firebug中经过几次之后,sprite图像似乎从未在第一页请求中加载

也许一些.js文件在游戏实例化时仍在下载,然后被缓存,并且只有在第二次页面加载时才可用


有什么想法吗?如果你能接受,我将不胜感激,谢谢

我在本地复制了您的文件并做了一些测试。在我看来,不可用的不是JavaScript文件,而是sprite

在调用Game.start之前,您不会加载PNG。当您这样做时:

roadSpritesheetImage.src = "assets/sprites/player/playerSpriteSheet.png";
这将开始异步下载映像。代码的其余部分是在图像完全加载之前执行的,因此当您对图像进行切片时,就像src属性为null一样对其进行切片

这就是为什么你可以点击刷新,一切都按预期进行。。。图像被缓存

您可以通过在画布前添加一个图像标记来预先加载精灵:

<img src="assets/sprites/player/playerSpriteSheet.png" style="display:none;" />
这样做有点干净,可以保证你的资源没有任何比赛条件


我创建了一个jQuery插件,用于从源图像绘制一个N字谜,我也遇到了类似的问题。当时我发现非常有用,虽然我最终使用了切片div而不是画布。

Hmm,我已经将Game.js作为四个包含中的第一个,但我似乎得到了与强制刷新相同的行为,所以我不会使用缓存副本这太好了,谢谢!在查看Chrome Timeline功能中的加载过程后,我开始怀疑同样的事情。然而,我只是假设,当您声明一个新的图像对象时,它只是等待图像加载,直到继续。我现在明白了,情况并非如此。这是一个新帐户,所以我没有足够的声誉来提升你的帖子,但当我这样做的时候,我会的。再次感谢,你帮我省去了几个小时的困惑@AlexAlksne,你可以把它标记为答案。现在您需要考虑在加载2+精灵时,在所有精灵都加载之前不应调用self.run。@AlexAlksne没问题。在这种情况下,很难掌握装载时间。。。特别是当你的精灵只有4K的时候。@JimSchubert那么,假设你不应该依赖JS来按时加载资源,这样安全吗?我是否应该有一个策略,在加载任何类型的资源音频/视频/等时,总是通过为该资源定义onLoad函数并在完成后调用self.run来暂停执行?@AlexAlksne您必须提供一些方法,以确保在代码中访问资源之前资源可用。您可以执行一些丑陋的onload链接,或者将它们加载到DOM中。您可以使用预加载所有内容,并可能有一个指示加载状态的。。。
<img src="assets/sprites/player/playerSpriteSheet.png" style="display:none;" />
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();
};