簡體   English   中英

優化html5畫布游戲

[英]Optimizing html5 canvas game

現在我在我正在制作的游戲中有兩個游戲循環。 一個繪制循環,循環通過屏幕上的對象數組和一個執行游戲邏輯的邏輯循環。 我的邏輯循環比draw循環運行大約10幀。 我有這樣的設置,因為做游戲邏輯可能需要更長時間,我不希望它干擾繪制循環。

我有這樣的邏輯循環設置:

vs.logicloop = function(){
    vs.Gameloop();
    //do the updating of object scripts
    if(vs.windowActive){
        var l = vs.scenegraph.length;
        var i = 0;
        while(i < l){
            vs.scenegraph[i].logicScript();
            i++;
        }
    }
    //restart loop
    setTimeout(vs.logicloop, 1000/(vs.fps+10));
};

和這樣的繪制循環:

vs.drawloop = function(){
    //clear the screen
    vsd.clr();
    //goes through everything in the scene
    //graph and draws it and runs each object's
    //personal draw code
    if(vs.windowActive){
        var l = vs.scenegraph.length;
        var i = 0;
        while(i < l){
            vs.ctx.save();
            vs.scenegraph[i].update();
            vs.scenegraph[i].draw();
            vs.scenegraph[i].drawScript();
            vs.ctx.restore();
            i++;
        }
    }
    //restart loop
    setTimeout(vs.drawloop, 1000/vs.fps);
};

我正在使用setTimeout,因為我聽說如果還沒有完成,setInterval會導致循環重疊。 我有什么優化可以真正獲得一些速度嗎? 特別是優化游戲循環。

我聽說過一些javascript引擎一次在屏幕上獲得數千個對象。 我無法想象他們是如何做到這一點的,至多我可以在一台非常舊的計算機屏幕上獲得多達100個對象,在合理庫存的計算機上可以獲得大約700個對象。 而且在我完成像素完美碰撞檢測和物理學之前,沒有很多游戲代碼在后台運行。

我的過程是在畫布上繪制每個繪制循環的背景顏色fillRect,然后循環遍歷所有對象並繪制它們的繪制代碼。 此外,它不會嘗試從視圖中繪制對象。

這是我的第一份工作,我真的很想留下深刻的印象。 此外,一旦我完成游戲,我就可以保留引擎的所有權。

非常感謝

  • 如果您對精靈坐標使用浮動值,請嘗試將它們轉換為整數。 這將花費你失去子像素渲染,但你會獲得很多速度。
  • 不要使用奇數寬度的圖像。 始終使用寬度為2的冪。
  • 這個在某些情況下很難實現,但如果你的游戲合適,不要清除屏幕並重新繪制每一幀的所有內容。 相反,繪制更改的部分。
  • 如果必須清除畫布,請不要繪制空白矩形。 嘗試使用相同的大小再次設置畫布寬度/高度。 應該比矩形繪圖更快地重置像素。

我可以建議的其他方法不依賴於HTML5畫布,但一般主題如使用位移,反循環和運算符而不是模數,如果可能,預先計算等。

哦,geez,如果你發布了所有的代碼,我可能會在這里給你寫一個完整的十四行詩。 這是一個快速的概述:

閱讀埃米爾的回答。 所有這些都很好,除了最后一個非常依賴於這種情況。 在某些瀏覽器上設置canvas.width = canvas.width以清除畫布可能會更快,但它也會破壞所有畫布狀態(即最后設置的填充和字體),這會降低速度,因為設置這些屬性實際上非常緩慢。

閱讀我關於Canvas性能的文章: http//simonsarris.com/blog/tag/performance

我在私人文件中保存了很多其他提示,我正在寫一本小型電子書。 如果你想盡早訪問它,我可能會允許它。

選擇Zakas的高性能JavaScript並閱讀它。

除非必須,否則不要像引用代碼一樣使用save()和restore()。 他們只是放慢了速度。

有關計時器,請參閱http://paulirish.com/2011/requestanimationframe-for-smart-animating/

前景 - 背景 - 中間地帶的多個畫布絕對有幫助。 在內存畫布上緩存內容肯定會有所幫助。 這一切都取決於你畫的是什么。

許多性能問題是由於千次切割造成的死亡。 例如:

        vs.scenegraph[i].update();
        vs.scenegraph[i].draw();
        vs.scenegraph[i].drawScript();

        var scene = vs.scenegraph[i];
        scene.update();
        scene.draw();
        scene.drawScript();

將幫助一分鍾 你有多少機會獲得微量的東西我不知道 - 我們需要看到更多的代碼。

我聽說如果還沒有完成,setInterval會導致循環重疊。

這是錯誤的,JavaScript是單線程的。 這意味着如果您的第一個間隔在到達下一步時仍在運行,則下一步將延遲,直到第一步完成計算。 這也意味着如果您開始進行大量計算,則不能依賴setInterval來准確。

我會回應其他人說的很多。 整數值,使用請求動畫幀等。如果繪制文本要小心,您設置字體的頻率。 如果每幀創建大量臨時對象,您可能會發現使用對象池可能會有所幫助。

作為游戲循環的一般閱讀,我推薦這個: http//www.koonsolo.com/news/dewitters-gameloop/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM