はじめに
通常、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的div元素默认一行不可以放两个。div是一个块级元素,一个元素会独占一行,两个div默认无法在同一行显示;但可以通过给div元素添加“display:inline;”样式,将其转为行内元素,就可以实现多个div在同一行显示了。

html5中列表和表格的区别:1、表格主要是用于显示数据的,而列表主要是用于给数据进行布局;2、表格是使用table标签配合tr、td、th等标签进行定义的,列表是利用li标签配合ol、ul等标签进行定义的。

固定方法:1、使用header标签定义文档头部内容,并添加“position:fixed;top:0;”样式让其固定不动;2、使用footer标签定义尾部内容,并添加“position: fixed;bottom: 0;”样式让其固定不动。

html5中不支持的标签有:1、acronym,用于定义首字母缩写,可用abbr替代;2、basefont,可利用css样式替代;3、applet,可用object替代;4、dir,定义目录列表,可用ul替代;5、big,定义大号文本等等。

HTML5中画布标签是“<canvas>”。canvas标签用于图形的绘制,它只是一个矩形的图形容器,绘制图形必须通过脚本(通常是JavaScript)来完成;开发者可利用多种js方法来在canvas中绘制路径、盒、圆、字符以及添加图像等。

html5废弃了dir列表标签。dir标签被用来定义目录列表,一般和li标签配合使用,在dir标签对中通过li标签来设置列表项,语法“<dir><li>列表项值</li>...</dir>”。HTML5已经不支持dir,可使用ul标签取代。

3种取消方法:1、给td元素添加“border:none”无边框样式即可,语法“td{border:none}”。2、给td元素添加“border:0”样式,语法“td{border:0;}”,将td边框的宽度设置为0即可。3、给td元素添加“border:transparent”样式,语法“td{border:transparent;}”,将td边框的颜色设置为透明即可。

因为html5不基于SGML(标准通用置标语言),不需要对DTD进行引用,但是需要doctype来规范浏览器的行为,也即按照正常的方式来运行,因此html5只需要写doctype即可。“!DOCTYPE”是一种标准通用标记语言的文档类型声明,用于告诉浏览器编写页面所用的标记的版本。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具

Atom編輯器mac版下載
最受歡迎的的開源編輯器

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

Dreamweaver Mac版
視覺化網頁開發工具