2012-04-06 88 views
1

我正在學習HTML5(和OO Javascript)的過程中,並試圖製作一個簡單的遊戲引擎,但渲染到非常奇怪的條件下的畫布作品。 Here是該頁面的鏈接,這是我的index.html:

HTML5帆布渲染奇怪

<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中的例外情況。爲了使其工作:

火狐11.0

  • 選擇在地址欄中的URL和手動按下回車鍵或
  • 單擊刷新按鈕,或
  • 按F5。

Chrome的18.0

  • 選擇在地址欄中的URL和手動按下回車鍵或
  • 單擊刷新按鈕,或
  • 按F5或
  • 按Shift/Ctrl + F5鍵。

我懷疑什麼 - 只是一個猜測,但它似乎像一個或多個.js文件的不可/準備通過它的第一頁加載過程中被調用的時候。在Firebug中經歷了幾次,似乎精靈圖像從未在第一頁請求中加載。

也許一些.js文件仍在下載,因爲Game()的實例化正在進行,然後被緩存,並且只有第二次頁面加載纔可用。

任何想法?我會很感激你的承諾,謝謝!

+0

嗯,我已經做出了Game.js四個包括的第一個,但我似乎得到了相同的行爲(我強制刷新,所以我不打算從緩存副本) – 2012-04-06 03:20:59

回答

3

我在本地複製了你的文件並做了一些測試。它看起來不像你的JavaScript文件不可用,而是你的精靈。

直到致電Game.start,才能加載PNG。當你這樣做時:

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-puzzle的jQuery插件。當時我發現this MDN documentation非常有用,儘管我最終使用了切片div而不是畫布。

+0

非常感謝你!在Chrome時間線功能中查看加載過程後,我開始懷疑同樣的事情。 然而,我只是假設,當你聲明一個新的Image()對象時,它只是等待圖像加載,直到繼續。我現在看到情況並非如此。 這是一個新帳戶,所以我沒有足夠的信譽來upvote您的帖子,但是當我做我會的。再次感謝您爲我節省了數小時的困擾! – 2012-04-06 04:34:51

+1

@AlexAlksne,您可以將其標記爲答案。現在你需要在加載2個精靈的時候考慮到,'self.run()'不應該被調用,直到所有的加載。 – Alexander 2012-04-06 04:44:03

+0

@AlexAlksne沒問題。在這種情況下,可能很難趕上加載時間......特別是當您的精靈只有4K時。 – 2012-04-06 04:50:01