はじめに
通常、2D ゲームをプレイするとき、または HTML5 キャンバスをレンダリングするときは、複数のレイヤーを使用して複合シーンを構築するための最適化を実行する必要があります。 OpenGL や WebGL などの低レベルのレンダリングでは、フレームごとにシーンをクリーニングしてペイントすることによってレンダリングが実行されます。レンダリングを実装した後は、レンダリング量を減らすためにゲームを最適化する必要があり、コストは状況によって異なります。キャンバスは DOM 要素であるため、最適化の方法として複数のキャンバスを階層化できます。
一般的に使用される略語
- CSS: カスケード スタイル シート
DOM: ドキュメント オブジェクト モデル
HTML: ハイパーテキスト マークアップ言語
この記事では、キャンバスをレイヤー化する理論的根拠を説明します。レイヤードキャンバスを実装するための DOM 設定を理解します。階層化を使用して最適化するには、さまざまな実践が必要です。この記事では、階層化アプローチを拡張するいくつかの最適化戦略の概念と手法についても説明します。
この記事で使用されている例のソース コードをダウンロードできます。
最適化戦略を選択します
最適な最適化戦略を選択するのは難しい場合があります。レイヤードシーンを選択するときは、シーンがどのように構成されているかを考慮する必要があります。大画面上で静止したオブジェクトをレンダリングするには、多くの場合、複数のコンポーネントを再利用する必要があり、それらは研究の優れた候補です。視差やアニメーション化されたエンティティなどの効果は、多くの場合、さまざまな画面スペースを大量に必要とします。最適な最適化戦略を検討するときは、これらの状況を認識しておくことをお勧めします。キャンバス レイヤの最適化にはいくつかの異なるテクニックが必要ですが、これらのテクニックを正しく適用すると、多くの場合、パフォーマンスが大幅に向上します。
レイヤーを設定
階層化アプローチを使用する場合、最初のステップは DOM 上にキャンバスを設定することです。通常、これはキャンバス要素を定義して DOM に配置するだけで簡単ですが、キャンバス レイヤーには追加のスタイル設定が必要になる場合があります。 CSS を使用するときにキャンバス レイヤを正常に実装するには、次の 2 つの要件があります。
各キャンバス要素はビューポート内の同じ位置に共存する必要があります。
各キャンバスは別のキャンバスの下に表示される必要があります。
図 1 は、レイヤー設定の背後にある一般的なオーバーレイの概念を示しています。
図 1. レイヤーの例
レイヤーを設定する手順は次のとおりです:
- DOM に Canvas 要素を追加します。
レイヤー化をサポートするために、キャンバス要素の配置スタイルを追加します。
キャンバス要素をスタイル設定して、透明な背景を生成します。
キャンバスのオーバーラップスタックを設定します
CSS でオーバーレイ スタックを作成するには、少量のスタイル設定が必要な場合があります。 HTML と CSS を使用してオーバーラップする方法は数多くあります。この記事の例では、
リスト 1. キャンバスの配置スタイル
- #viewport {
- /**
- * キャンバス要素 となるように相対的に配置します。
- * その内側は 親 との相対になります。
- */
- 位置: 相対; }
- #viewport Canvas {
- /**
- * 絶対位置は、 を可能にするキャンバスを提供します。
- * 相互に重ねて重ねていきます
- * Z インデックスを必ず覚えておいてください。
- */
- 位置: 絶対; }
- Container
可視性の重複を使用して、レイヤー技術の 2 番目のスタイル要件を達成します。この例では、リスト 2 に示すように、このオプションを使用して DOM 要素の背景色を設定します。
リスト 2. 透明な背景を設定するためのスタイルシートのルール
XML/HTML コード
- /**
- * を通じて他のキャンバスをレンダリングできるように 透明 に設定します。
- */
- 背景色: 透明; }
-
背景が透明になるようにキャンバスのスタイルを設定します。これにより、重なったキャンバスが表示されるという 2 番目の要件が満たされます。レイヤー化のニーズを満たすようにマークアップとスタイルを構造化したので、レイヤー化されたシーンをセットアップできます。
レイヤリングに関する考慮事項最適化戦略を選択するときは、その戦略を使用する際のすべてのトレードオフを認識する必要があります。 HTML5 キャンバス シーンの階層化は、実行速度の利点を得るために使用される実行時のメモリに重点を置いた戦略です。ページのブラウザにさらに重みを追加して、フレーム レートを高速化できます。一般に、キャンバスはブラウザ上のグラフィックス プレーンとみなされ、グラフィックス API が含まれます。
Google Chrome 19 でテストし、ブラウザのタブのメモリ使用量を記録することで、メモリ使用量の明確な傾向を確認できます。このテストでは、(前のセクションで説明したように) すでにスタイル設定されている
を使用し、単一の色で塗りつぶされた上に配置される Canvas 要素を生成します。キャンバスのサイズは 1600 x 900 ピクセルに設定され、データは Chrome1 のタスク マネージャー ユーティリティから収集されました。表 1 に一例を示します。Google Chrome のタスク マネージャーでは、ページで使用されているメモリ (RAM とも呼ばれます) の量を確認できます。 Chrome は、GPU メモリ、または GPU によって使用されるメモリも提供します。これは、ジオメトリ、テクスチャ、またはコンピューターがキャンバス データを画面にプッシュするために必要となるあらゆる形式のキャッシュ データなどの一般的な情報です。メモリが少ないほど、コンピュータにかかる重量が減ります。根拠となる明確な数値はまだありませんが、プログラムが限界を超えてメモリを過剰に使用していないことを確認するために、常にテストする必要があります。メモリの使用量が多すぎると、メモリ リソース不足によりブラウザまたはページがクラッシュします。 GPU 処理は野心的なプログラミングの追求ですが、この記事の範囲を超えています。まずは OpenGL を学ぶか、Chrome のドキュメントを確認することから始めてください (「参考文献」を参照)。
表 1. キャンバス層のメモリオーバーヘッド表 1 では、より多くの HTML5 キャンバス要素がページに導入され、使用されると、より多くのメモリが使用されます。一般的なメモリにも線形相関がありますが、層が追加されるたびにメモリの増加は大幅に減少します。このテストでは、これらのレイヤーのパフォーマンスへの影響は詳しく説明されていませんが、キャンバスが GPU メモリに重大な影響を与える可能性があることが示されています。プラットフォームの制限によってアプリケーションが実行できなくなることがないように、ターゲット プラットフォームでストレス テストを必ず実行してください。
階層化ソリューションの単一キャンバスのレンダリング サイクルを変更する場合は、メモリ オーバーヘッドに関するパフォーマンスの向上を考慮してください。メモリのコストは高くなりますが、この技術は各フレームで変更されるピクセルの数を減らすことで効果を発揮します。
次のセクションでは、レイヤーを使用してシーンを整理する方法について説明します。
シーンのレイヤー化: ゲームこのセクションでは、スクロール プラットフォームのランナー スタイル ゲームでの視差効果の単一キャンバス実装をリファクタリングすることにより、多層ソリューションを見ていきます。図 2 は、雲、丘、地面、背景、およびいくつかのインタラクティブなエンティティを含むゲーム ビューの構成を示しています。
図 2. 合成ゲームビューゲームでは、雲、丘、地面、背景はすべて異なる速度で動きます。基本的に、背景の奥にある要素は手前の要素よりも遅く移動するため、視差効果が生じます。状況をさらに複雑にしているのは、背景の動きが 0.5 秒ごとにのみ再レンダリングされるほど遅いことです。
背景は画像であり常に変化するため、通常はすべてのフレームをクリアして画面を再レンダリングするのが良い解決策となります。この場合、背景は 1 秒あたり 2 回しか変化しないため、各フレームを再レンダリングする必要はありません。
現在、ワークスペースが定義されているので、シーンのどの部分を同じレイヤー上に置くかを決定できます。レイヤーを整理したら、レイヤー化のためのさまざまなレンダリング戦略を検討します。まず、リスト 3 に示すように、単一のキャンバスを使用してこのソリューションを実装する方法を検討する必要があります。
リスト 3. 単一キャンバスのレンダリング ループの疑似コード
XML/HTML コードコンテンツをクリップボードにコピー- /**
- * レンダリング呼び出し
- *
- * @param {CanvasRenderingContext2D} context Canvas context
- */
- 関数 renderLoop(context)
- {
- context.clearRect(0, 0, width, height);
- 背景.render(コンテキスト)
- グラウンド .render(context); ヒルズ.レンダー(コンテキスト)
- クラウド.レンダー(コンテキスト)
- player.render(context);
- }
- リスト 3 のコードと同様に、このソリューションには、ゲーム ループ呼び出しごと、または更新間隔ごとに呼び出されるレンダリング関数が含まれます。この場合、レンダリングはメイン ループ呼び出しと各要素の位置を更新する更新呼び出しから抽象化されます。
エンティティのレンダリング方法をより適切に指定するには、2 種類のエンティティ オブジェクトを使用する必要があります。リスト 4 は、使用して調整する 2 つのエンティティを示しています。
リスト 4. レンダリング可能なエンティティの擬似コード
XML/HTML コードコンテンツをクリップボードにコピーvar- エンティティ = 関数() { /**
- 初期化 および その他のメソッド
- **/
- /**
- * エンティティを描画するためのレンダリング呼び出し
- *
- * @param {CanvasRenderingContext2D} context
- */
- this.render
- = 関数(コンテキスト) { context.drawImage(this.image, this.x, this.y);
- }
- };
XML/HTML コードコンテンツをクリップボードにコピー- var PanningEntity = 函數()) /**
- 初始化及其他方法
- **/
- /**
- * 渲染呼叫以繪製平移實體
- *
- * @param {CanvasRenderingContext2D} 上下文
- */
- this.render = 函數(情境) context.drawImage(
- 此.image,
- this.x - this.width,
- this.y - this.height);
- context.drawImage(
- 此.image,
- this.x,
- 此.y);
- context.drawImage(
- 此.image,
- this.x this.width,
- this.y this.height);
- }
- };
-
清單 4中的物件儲存實體的圖像、x、y、寬度和高度的實例變數。這些物件遵循 JavaScript 語法,但為了簡潔起見,僅提供了目標物件的不完整的偽代碼。目前,渲染演算法非常貪婪地在畫布上渲染出它們的圖像,完全不考慮遊戲循環的其他任何要求。
為了提高效能,需要重點注意的是,panning渲染呼叫輸出了一個比所需影像更大的影像。本文忽略這個特定的最佳化,但是,如果使用的空間比您的圖像提供的空間小,那麼請確保只渲染必要的補丁。
確定分層現在您知道如何使用單一畫布實作該範例,讓我們看看有什麼辦法可以完善這種類型的場景,並加快渲染循環。若要使用分層技術,則必須透過找出實體的渲染重疊,識別分層所需的 HTML5 畫布元素。
重繪區域為了確定是否存在重疊,要考慮一些被稱為重繪區域的不可見區域。重繪區域是在繪製實體的影像時需要畫布清除的區域。重繪區域對於渲染分析很重要,因為它們使您能夠找到完善渲染場景的最佳化技術,如圖 3所示。
圖 3. 合成遊戲視圖與重繪區域為了視覺化圖 3中的效果,在場景中的每個實體都有一個表示重繪區域的重疊,它跨越了視區寬度和實體的影像高度。場景可分為三組:背景、前景、互動。場景中的重繪區域有一個彩色的重疊,以區分不同的區域:
- 背景 – 黑色
雲 – 紅色
小山 – 綠色
地面 – 藍色
對於除了球和障礙物以外的所有重疊,重繪區域都會橫跨視區寬度。這些實體的圖像幾乎填滿整個螢幕。由於它們的平移要求,它們將渲染整個視區寬度,如圖 4所示。預計球和障礙物會穿過該視區,並且可能擁有透過實體位置定義的各自的區域。如果您刪除渲染到場景的影像,只留下重繪區域,您可以輕鬆看到單獨的圖層。 圖 4.重繪區域
找到附加層的另一種方法是收集沒有重疊的所有區域。佔據視區的紅色、綠色和藍色區域並沒有重疊,它們組成了第二層——前景。雲和互動實體的區域沒有重疊,但因為球有可能跳躍到紅色區域,所以您應該考慮將該實體作為一個單獨的層。
初始層是顯而易見的,因為您可以注意到互相重疊的各個區域。由於球和障礙物區域覆蓋了小山和地面,所以可將這些實體分組為一層,該層稱為交互層。根據遊戲實體的渲染順序,交互層是頂層。圖 5. 分層的遊戲視圖
現在已經為每個分組的實體定義了圖層,現在就可以開始最佳化畫布清除。此優化的目標是為了節省處理時間,可以透過減少每一步渲染的螢幕上的固定物數量來實現。需要重點注意的是,使用不同的策略可能會使影像獲得更好的最佳化。下一節將探討各種實體或層的最佳化方法。渲染最佳化
最佳化實體是分層策略的核心。將實體分層,使得渲染策略可以被採用。通常,最佳化技術會試圖消除開銷。如表 1所述,由於引入了層,您已經增加了記憶體開銷。這裡討論的最佳化技術將減少處理器為了加快遊戲而必須執行的大量工作。我們的目標是尋找一種減少要渲染的空間量的方法,並盡可能刪除每個步驟中出現的渲染和清除呼叫。
單一實體清除第一個最佳化方法針對的是清除空間,透過只清除組成該實體的螢幕子集來加快處理。首先減少與區域的各實體周圍的透明像素重疊的重繪區域量。使用此技術的包括相對較小的實體,它們填充了視區的小區域。
最初のターゲットはボールと障害物です。単一エンティティのクリア手法には、エンティティを新しい位置にレンダリングする前に、前のフレームでエンティティがレンダリングされた位置をクリアすることが含まれます。各エンティティのレンダリングにクリーンアップ ステップを導入し、エンティティの画像の境界ボックスを保存します。このステップを追加すると、リスト 5 に示すように、エンティティ オブジェクトが変更されてクリーンアップ ステップが組み込まれます。
リスト 5. 単一ボックスのクリアリングを含むエンティティ
XML/HTML コードコンテンツをクリップボードにコピー- var エンティティ = 関数() {
- /**
- 初期化 および その他のメソッド
- **/
- /**
- * エンティティを描画するためのレンダリング呼び出し
- *
- * @param {CanvasRenderingContext2D} コンテキスト
- */
- this.render = 関数(コンテキスト) {
- context.clearRect(
- this.prevX、
- this.prevY、
- this.width、
- この.高さ);
- context.drawImage(this.image, this.x, this.y);
- thisthis.prevX = this.x;
- thisthis.prevY = this.y; }
- };
- レンダリング関数の更新により、通常のdrawImageの前に発生するclearRect呼び出しが導入されました。このステップでは、オブジェクトは以前の場所を保存する必要があります。図 6 は、前の位置に対して被験者がとったステップを示しています。
更新ステップの前に呼び出される各エンティティのクリア メソッドを作成することで、このレンダリング ソリューションを実装できます (ただし、この記事ではクリア メソッドは使用しません)。リスト 6 に示すように、このクリアリング戦略を PanningEntity に導入して、地上および雲のエンティティにクリアリングを追加することもできます。
リスト 6. 単一ボックスをクリアする PanningEntity
XML/HTML コードコンテンツをクリップボードにコピー- var PanningEntity = 函數()) /**
- 初始化及其他方法
- **/
- /**
- * 渲染呼叫以繪製平移實體
- *
- * @param {CanvasRenderingContext2D} 上下文
- */
- this.render = 函數(情境) context.clearRect(
- this.x,
- 此.y,
- context.canvas.width,
- 此.height);
- context.drawImage(
- 此.image,
- this.x - this.width,
- this.y - this.height);
- context.drawImage(
- 此.image,
- this.x,
- 此.y);
- context.drawImage(
- 此.image,
- this.x this.width,
- this.y this.height);
- }
- };
-
因為PanningEntity橫跨了整個視區,所以您可以使用畫布寬度作為清除矩形的大小。如果使用此清除策略,則會為您提供已為雲、小山和地面實體定義的重繪區域。
為了進一步最佳化雲端實體,可以將雲分離為單獨的實體,使用它們自己的重繪區域。這樣做會大幅減少在雲端重繪區域內要清除的螢幕空間量。圖 7顯示了新的重繪區域。
圖 7.具有單獨重繪區域的雲單一實體清除策略產生的解決方案可以解決像本例這樣的分層畫布遊戲上的大多數問題,但仍然可以對它進行最佳化。為了尋找針對該渲染策略的極端情況,我們假設球會與三角形碰撞。如果兩個實體碰撞,實體的重繪區域就有可能發生重疊,並建立一個不想要的渲染構件。另一個清除最佳化,更適合可能會碰撞的實體,它也將有益於分層。
髒矩形清除若沒有單一清除策略,髒矩形清除策略可以是功能強大的替代品。您可以對有重繪區域的大量實體使用這種清除策略,這種實體包括密集的粒子系統,或有小行星的空間遊戲。
從概念上講,演算法會收集由演算法管理的所有實體的重繪區域,並在清除呼叫中清除整個區域。為了增加最佳化,此清除策略也會刪除每個獨立實體產生的重複清除調用,如清單 7所示。
清單 7.DirtyRectManager
XML/HTML Code複製內容到剪貼簿- var DirtyRectManager = 函數())
- //將左邊緣與上方緣設為盡可能大的數值
- //(畫布寬度)由右至下至最小
- // 隨著增加更多實體,左側和頂部將會縮小
- this.left = 畫布 this.top
- = 畫布 //隨著增加更多實體,右邊和底部將會增加
- this.right =
- 0 this.bottom = 0
- ; >0; ; //髒檢查以避免未新增任何實體時清除
- this.isDirty =
- 假; //其他初始化代碼
- /**
- * 其他實用方法
- */
- /**
- * 新增髒矩形參數並將此區域標示為髒
- *
- * @param {number} x
- * @param {number} y
- * @param {number} 寬度
- * @param {number} 身高
- */
- this.addDirtyRect = > //計算出長方形邊
- var 左
- = x = x var 右
- = x = x = x var 上方
- = y var 底部 =
- // 左與實體左的最小值 這個.左
- = 左 左 : this.left;
- // 權利實體權利的最大值
- this.right = 右 //上實體上方的最小值
- this.top = 頂部
- this.top 上方 : this.top; // 底部與實體底部的最大值
- this.bottom = 底部 this.isDirty = true
- ; };
- /** * 若管理器髒了,清除長方形區域
- *
- * @param {CanvasRenderingContext2D} 上下文 */
- this.clearRect =
- 函數 (上下文)🎜>
- 函數(上下文)
- if (!this.isDirty) {
- 返回;
- }
- // 清除所計算的長方形
- context.clearRect(
- 此.left,
- this.top,
- 此.右 - 此.左,
- this.bottom - this.top);
- //重置基本值
- this.left = 畫布
- this.top = 畫布 this.right = this.bottom = 0
- this.isDirty = 假假;
- } }; 將報表邏輯整合到渲染循環,這需要在清單呼叫7中的管理器之前進行渲染呼叫。將實體新增至管理器,使管理器可以在清晰的時候計算出清晰的報表維度。會產生預期的最佳化,但根據遊戲循環,管理器能夠針對遊戲循環進行最佳化,如圖8所示。 圖8.交互層的重繪區域
- 畫格 1 – 實體重繪區域重疊,幾乎重疊。 畫格 2 – 實體重繪區域是重疊的。 畫面 3 – 重繪區域重疊,並收集到一個重疊中。 第 4 章 – 髒版圖形已清晰。
作為清除的重寫
透過在渲染的上方重新渲染先前的影像,重寫可以加速地面實體。也可以透過相同的方式加速最大的層,例如背景。
對於在恆定重繪區域中動畫的完全不透明實體,可以使用重寫作為一個最佳化技術。將不透明的位圖渲染為一個區域(預設的合成操作),這將像素放置在該區域上中,需要考慮該區域中的原始渲染。這個優化消除了渲染調用之前所需的清除調用,因為渲染會覆蓋原來的區域。- 透過減少每一層的重繪區域,您已經有效地找到層及其所包含的實體最佳化策略。
結束語
- 背景 – 黑色

HTML5的關鍵元素包括、、、、、等,用於構建現代網頁。 1.定義頭部內容,2.用於導航鏈接,3.表示獨立文章內容,4.組織頁面內容,5.展示側邊欄內容,6.定義頁腳,這些元素增強了網頁的結構和功能性。

HTML5和H5沒有區別,H5是HTML5的簡稱。 1.HTML5是HTML的第五個版本,增強了網頁的多媒體和交互功能。 2.H5常用於指代基於HTML5的移動網頁或應用,適用於各種移動設備。

HTML5是超文本標記語言的最新版本,由W3C標準化。 HTML5引入了新的語義化標籤、多媒體支持和表單增強,提升了網頁結構、用戶體驗和SEO效果。 HTML5引入了新的語義化標籤,如、、、等,使網頁結構更清晰,SEO效果更好。 HTML5支持多媒體元素和,無需第三方插件,提升了用戶體驗和加載速度。 HTML5增強了表單功能,引入了新的輸入類型如、等,提高了用戶體驗和表單驗證效率。

如何寫出乾淨高效的HTML5代碼?答案是通過語義化標籤、結構化代碼、性能優化和避免常見錯誤。 1.使用語義化標籤如、等,提升代碼可讀性和SEO效果。 2.保持代碼結構化和可讀性,使用適當縮進和註釋。 3.優化性能,通過減少不必要的標籤、使用CDN和壓縮代碼。 4.避免常見錯誤,如標籤未閉合,確保代碼有效性。

H5通過多媒體支持、離線存儲和性能優化提升網頁用戶體驗。 1)多媒體支持:H5的和元素簡化開發,提升用戶體驗。 2)離線存儲:WebStorage和IndexedDB允許離線使用,提升體驗。 3)性能優化:WebWorkers和元素優化性能,減少帶寬消耗。

HTML5代碼由標籤、元素和屬性組成:1.標籤定義內容類型,用尖括號包圍,如。 2.元素由開始標籤、內容和結束標籤組成,如內容。 3.屬性在開始標籤中定義鍵值對,增強功能,如。這些是構建網頁結構的基本單位。

HTML5是構建現代網頁的關鍵技術,提供了許多新元素和功能。 1.HTML5引入了語義化元素如、、等,增強了網頁結構和SEO。 2.支持多媒體元素和,無需插件即可嵌入媒體。 3.表單增強了新輸入類型和驗證屬性,簡化了驗證過程。 4.提供了離線和本地存儲功能,提升了網頁性能和用戶體驗。

H5代碼的最佳實踐包括:1.使用正確的DOCTYPE聲明和字符編碼;2.採用語義化標籤;3.減少HTTP請求;4.使用異步加載;5.優化圖像。這些實踐能提升網頁的效率、可維護性和用戶體驗。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

ZendStudio 13.5.1 Mac
強大的PHP整合開發環境

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),