Heim > Web-Frontend > H5-Tutorial > Tutorial zur Verwendung von Layered Canvas zur Optimierung des HTML5-Renderings_HTML5-Tutorial-Tipps

Tutorial zur Verwendung von Layered Canvas zur Optimierung des HTML5-Renderings_HTML5-Tutorial-Tipps

WBOY
Freigeben: 2016-05-16 15:46:40
Original
1768 Leute haben es durchsucht

Einführung

Normalerweise müssen Sie beim Spielen von 2D-Spielen oder beim Rendern von HTML5-Canvas Optimierungen durchführen, um mehrere Ebenen zum Erstellen einer zusammengesetzten Szene zu verwenden. Beim Low-Level-Rendering wie OpenGL oder WebGL erfolgt das Rendern durch Bereinigen und Malen der Szene Bild für Bild. Nach der Implementierung des Renderings muss das Spiel optimiert werden, um den Rendering-Aufwand zu reduzieren. Die Kosten variieren je nach Situation. Da es sich bei der Leinwand um ein DOM-Element handelt, können Sie zur Optimierung mehrere Ebenen übereinander legen.
Häufig verwendete Abkürzungen

  • CSS: Cascading Style Sheets
    DOM: Document Object Model
    HTML: HyperText Markup Language

In diesem Artikel werden die Gründe für die Schichtung von Leinwänden untersucht. Verstehen Sie die DOM-Einstellungen zur Implementierung geschichteter Canvases. Für die Optimierung mithilfe von Layering sind verschiedene Vorgehensweisen erforderlich. In diesem Artikel werden auch einige Optimierungsstrategiekonzepte und -techniken untersucht, die den mehrschichtigen Ansatz erweitern.

Sie können den Quellcode für die in diesem Artikel verwendeten Beispiele herunterladen.
Wählen Sie eine Optimierungsstrategie

Die Wahl der besten Optimierungsstrategie kann schwierig sein. Bei der Auswahl einer mehrschichtigen Szene müssen Sie berücksichtigen, wie die Szene zusammengesetzt ist. Die Darstellung stationärer Objekte auf großen Bildschirmen erfordert häufig die Wiederverwendung mehrerer Komponenten und eignet sich hervorragend für Studien. Effekte wie Parallaxe oder animierte Elemente erfordern häufig große Mengen unterschiedlicher Bildschirmfläche. Es ist eine gute Idee, sich dieser Situationen bewusst zu sein, wenn Sie Ihre optimale Optimierungsstrategie erkunden. Während die Optimierung der Canvas-Schichtung mehrere unterschiedliche Techniken erfordert, führen diese Techniken bei korrekter Anwendung häufig zu erheblichen Leistungsverbesserungen.
Ebene festlegen

Beim Layering-Ansatz besteht der erste Schritt darin, die Leinwand auf dem DOM einzurichten. Normalerweise ist dies so einfach wie das Definieren des Canvas-Elements und dessen Platzierung im DOM, aber die Canvas-Ebene erfordert möglicherweise etwas zusätzliches Styling. Es gibt zwei Voraussetzungen für die erfolgreiche Implementierung von Canvas-Layering bei der Verwendung von CSS:

Jedes Canvas-Element muss an derselben Position im Ansichtsfenster nebeneinander vorhanden sein.
Jede Leinwand muss unter einer anderen Leinwand sichtbar sein.

Abbildung 1 zeigt das allgemeine Overlay-Konzept hinter den Ebeneneinstellungen.
Abbildung 1. Beispiel einer Ebene
201558165954791.gif (288×173)
Die Schritte zum Einrichten einer Ebene sind wie folgt:

  • Canvas-Element zum DOM hinzufügen.
    Fügen Sie einen Positionierungsstil für Leinwandelemente hinzu, um die Ebenenbildung zu unterstützen.
    Stilisieren Sie das Canvas-Element, um einen transparenten Hintergrund zu erzeugen.

Leinwandüberlappungsstapel festlegen

Das Erstellen eines Overlay-Stacks in CSS erfordert möglicherweise ein wenig Styling. Es gibt viele Möglichkeiten, HTML und CSS zu überlappen. Die Beispiele in diesem Artikel verwenden ein

-Tag, um die Leinwand einzuschließen. Das
-Tag gibt eine eindeutige ID an, die Stile auf seine untergeordneten HTML5-Canvas-Elemente anwendet, wie in Listing 1 gezeigt.
Liste 1. Stil der Leinwandpositionierung

CSS-CodeInhalt in die Zwischenablage kopieren
  1. #viewport {
  2.  /** 
  3.      * Positionieren Sie relativ, sodass die Leinwandelemente  
  4. sind
  5.      * darin wird relativ zum übergeordneten Element sein  
  6.      */ 
  7. Position: relativ;
  8. }
  9. #viewpoRT-Leinwand {
  10.  
  11. /** 
  12.      * Position absolute stellt Leinwände bereit, um   können
  13.      * übereinander geschichtet werden  
  14.      * Denken Sie unbedingt an einen Z-Index!  
  15.      */ 
  16. Position: absolut;
  17. Container
    erfüllt die Überlappungsanforderung, indem es alle untergeordneten Canvas-Elemente so gestaltet, dass sie die absolute Positionierung verwenden. Sie machen sich zukunftssicher, indem Sie festlegen, dass das #viewport eine relative Positionierung verwendet, sodass absolute Layoutstile, die auf untergeordnete Stile angewendet werden, relativ zum #viewport-Container sind.
Die Reihenfolge dieser HTML5-Canvas-Elemente ist ebenfalls wichtig. Die Reihenfolge kann durch die Reihenfolge verwaltet werden, in der Elemente im DOM angezeigt werden, oder durch Stylen von Z-Index-Stilen in der Reihenfolge, in der die Leinwand angezeigt werden soll. Auch wenn dies nicht immer der Fall ist, können sich andere Stile auf die Darstellung auswirken. Seien Sie vorsichtig, wenn Sie zusätzliche Stile einführen (z. B. jede Art von CSS-Transformation).
Transparenter Hintergrund

Erfüllen Sie die zweite Styling-Anforderung der Ebenentechnik, indem Sie überlappende Sichtbarkeit verwenden. Das Beispiel verwendet diese Option, um die Hintergrundfarbe des DOM-Elements festzulegen, wie in Listing 2 gezeigt.

Listing 2. Stylesheet-Regeln zum Festlegen eines transparenten Hintergrunds




XML/HTML-Code

Inhalt in die Zwischenablage kopieren
Leinwand {
  1. /**  
  2.      * Stellen Sie transparent ein, damit alle anderen Leinwände durch   
  3. gerendert werden können
  4.      */
  5. Hintergrundfarbe: transparent;
  6. }
  7. Gestalten Sie die Leinwand so, dass sie einen transparenten Hintergrund hat, was die zweite Anforderung einer sichtbaren überlappenden Leinwand erfüllt. Nachdem Sie Ihr Markup und Ihre Stile nun so strukturiert haben, dass sie Ihren Ebenenanforderungen entsprechen, können Sie eine Ebenenszene einrichten.
    Überlegungen zur Schichtung

    Bei der Auswahl einer Optimierungsstrategie sollten Sie sich aller Kompromisse bei der Verwendung dieser Strategie bewusst sein. Das Layering von HTML5-Canvas-Szenen ist eine auf den Laufzeitspeicher ausgerichtete Strategie, mit der Laufzeitgeschwindigkeitsvorteile erzielt werden. Sie können dem Browser der Seite mehr Gewicht hinzufügen, um eine schnellere Bildrate zu erzielen. Im Allgemeinen wird die Leinwand als Grafikebene im Browser betrachtet, die eine Grafik-API enthält.

    Durch Tests in Google Chrome 19 und Aufzeichnen der Tab-Speichernutzung des Browsers können Sie klare Trends bei der Speichernutzung erkennen. Dieser Test verwendet ein bereits formatiertes

    (wie im vorherigen Abschnitt besprochen) und generiert ein Canvas-Element, das über dem
    platziert wird und mit einer einzelnen Farbe gefüllt ist. Die Größe der Leinwand wurde auf 1600 x 900 Pixel eingestellt und die Daten wurden vom Task-Manager-Dienstprogramm von Chrome1 erfasst. Tabelle 1 zeigt ein Beispiel.

    Im Task-Manager von Google Chrome können Sie die Menge an Speicher (auch RAM genannt) sehen, die von einer Seite verwendet wird. Chrome stellt auch GPU-Speicher bzw. den von der GPU verwendeten Speicher bereit. Hierbei handelt es sich um allgemeine Informationen wie Geometrie, Texturen oder jede Form von zwischengespeicherten Daten, die der Computer möglicherweise benötigt, um Ihre Canvas-Daten auf den Bildschirm zu übertragen. Je geringer der Speicher, desto weniger Gewicht wird auf den Computer gelegt. Obwohl es noch keine festen Zahlen als Grundlage dafür gibt, sollten Sie dies immer testen, um sicherzustellen, dass Ihr Programm nicht an seine Grenzen stößt und zu viel Speicher verbraucht. Wenn zu viel Speicher verwendet wird, stürzt der Browser oder die Seite aufgrund fehlender Speicherressourcen ab. Die GPU-Verarbeitung ist eine ehrgeizige Programmieraufgabe, die den Rahmen dieses Artikels sprengen würde. Sie können damit beginnen, OpenGL zu erlernen oder die Dokumentation von Chrome zu lesen (siehe Ressourcen).
    Tabelle 1. Speicheraufwand der Canvas-Ebene
    201558170025301.jpg (651×315)

    In Tabelle 1 wird mehr Speicher verbraucht, je mehr HTML5-Canvas-Elemente eingeführt und auf der Seite verwendet werden. Der allgemeine Speicher hat ebenfalls eine lineare Korrelation, aber mit jeder zusätzlichen Schicht wird das Speicherwachstum deutlich reduziert. Während dieser Test die Auswirkungen dieser Ebenen auf die Leistung nicht detailliert beschreibt, zeigt er doch, dass Canvas den GPU-Speicher erheblich beeinträchtigen kann. Denken Sie immer daran, Stresstests auf Ihrer Zielplattform durchzuführen, um sicherzustellen, dass Plattformeinschränkungen nicht dazu führen, dass Ihre Anwendung nicht mehr leistungsfähig ist.

    Berücksichtigen Sie bei der Entscheidung, den Rendering-Zyklus einer einzelnen Leinwand einer mehrschichtigen Lösung zu ändern, die Leistungssteigerungen hinsichtlich des Speicheraufwands. Trotz der Speicherkosten erfüllt diese Technik ihre Aufgabe, indem sie die Anzahl der in jedem Frame geänderten Pixel reduziert.

    Im nächsten Abschnitt wird erläutert, wie Sie Ebenen zum Organisieren einer Szene verwenden.
    Szenen überlagern: Spiele

    In diesem Abschnitt betrachten wir eine mehrschichtige Lösung, indem wir eine Single-Canvas-Implementierung eines Parallaxeneffekts in einem Scrolling-Plattform-Runner-Spiel umgestalten. Abbildung 2 zeigt die Zusammensetzung der Spielansicht, die Wolken, Hügel, Boden, Hintergrund und einige interaktive Elemente umfasst.
    Abbildung 2. Synthetische Spielansicht
    201558170059746.jpg (300×169)

    Im Spiel bewegen sich Wolken, Hügel, Boden und Hintergrund alle mit unterschiedlicher Geschwindigkeit. Grundsätzlich bewegen sich Elemente weiter im Hintergrund langsamer als Elemente davor, wodurch ein Parallaxeneffekt entsteht. Um die Sache noch komplizierter zu machen, bewegt sich der Hintergrund so langsam, dass er nur alle halbe Sekunde neu gerendert wird.

    Normalerweise wäre es eine gute Lösung, alle Frames zu löschen und den Bildschirm neu zu rendern, da der Hintergrund ein Bild ist und sich ständig ändert. Da sich der Hintergrund in diesem Fall nur zweimal pro Sekunde ändert, müssen Sie nicht jedes Bild neu rendern.

    Derzeit haben Sie Ihren Arbeitsbereich definiert, sodass Sie entscheiden können, welche Teile Ihrer Szene auf derselben Ebene liegen sollen. Nachdem die Ebenen organisiert sind, werden wir verschiedene Rendering-Strategien für die Ebenenerstellung untersuchen. Zunächst müssen Sie überlegen, wie Sie diese Lösung mit einem einzigen Canvas implementieren, wie in Listing 3 gezeigt.
    Listing 3. Pseudocode für die Single-Canvas-Rendering-Schleife

    XML/HTML-CodeInhalt in die Zwischenablage kopieren
    1. /**  
    2.  * Render-Aufruf   
    3.  *   
    4.  * @param {CanvasRenderingContext2D} context Canvas context   
    5.  */
    6. Funktion renderLoop(context)
    7. {
    8. context.clearRect(0, 0, width, height);
    9. background.render(context);
    10. ground .render(context);
    11. hills.render(context);
    12. cloud.render(context);
    13. player.render(context);
    14. }

    Wie der Code in Listing 3 hätte diese Lösung eine Renderfunktion, die bei jedem Spielschleifenaufruf oder bei jedem Aktualisierungsintervall aufgerufen wird. In diesem Fall wird das Rendering von den Hauptschleifenaufrufen und Aktualisierungsaufrufen abstrahiert, die die Position jedes Elements aktualisieren.

    Gemäß der „Clear to Render“-Lösung ruft Render den Clear-Kontext auf und verfolgt ihn, indem es die jeweiligen Renderfunktionen der Entitäten auf dem Bildschirm aufruft. Listing 3 folgt einem programmatischen Pfad zum Platzieren von Elementen auf der Leinwand. Obwohl diese Lösung zum Rendern von Entitäten auf dem Bildschirm effektiv ist, beschreibt sie weder alle verwendeten Rendering-Methoden noch unterstützt sie irgendeine Form der Rendering-Optimierung.

    Um die Rendering-Methode von Entitäten besser zu spezifizieren, müssen zwei Arten von Entitätsobjekten verwendet werden. Listing 4 zeigt die beiden Entitäten, die Sie verwenden und verfeinern werden.
    Listing 4. Renderable Entity-Pseudocode

    XML/HTML-CodeInhalt in die Zwischenablage kopieren
    1. var Entity = function() {
    2. /**  
    3.      Initialisierung und andere Methoden   
    4.      **/
    5. /**  
    6.       * Aufruf rendern, um die Entität zu zeichnen   
    7.       *   
    8.       * @param {CanvasRenderingContext2D} Kontext   
    9.       */
    10. this.render = function(context) {
    11. context.drawImage(this.image, this.x, this.y);
    12. }
    13. };


    XML/HTML-CodeInhalt in die Zwischenablage kopieren
    1. var PanningEntity = function() {   
    2.     /**  
    3.      Initialisierung und andere Methoden   
    4.      **/   
    5.     
    6.     /**  
    7.       * Aufruf rendern, um das geschwenkte Element zu zeichnen   
    8.       *   
    9.       * @param {CanvasRenderingContext2D} Kontext   
    10.      */   
    11.     this.render = function(context) {   
    12.         context.drawImage(   
    13.             dieses Bild,   
    14.             this.x - this.width,   
    15.             this.y - this.height);   
    16.         context.drawImage(   
    17.             dieses Bild,   
    18.             this.x,   
    19.             this.y);   
    20.         context.drawImage(   
    21.             dieses Bild,   
    22.             this.x   this.width,   
    23.             this.y   this.height);   
    24.     }   
    25. };  

    Das Objekt in Listing 4 speichert Instanzvariablen für das Bild, x, y, die Breite und die Höhe der Entität. Diese Objekte folgen der JavaScript-Syntax, der Kürze halber wird jedoch nur unvollständiger Pseudocode für die Zielobjekte bereitgestellt. Derzeit sind Rendering-Algorithmen sehr gierig beim Rendern ihrer Bilder auf der Leinwand, ohne Rücksicht auf andere Anforderungen der Spielschleife.

    Um die Leistung zu verbessern, ist es wichtig zu beachten, dass der Panning-Render-Aufruf ein größeres Bild als das gewünschte Bild ausgibt. In diesem Artikel wird diese spezielle Optimierung ignoriert. Wenn jedoch der verwendete Speicherplatz kleiner ist als der, den Ihr Bild bietet, stellen Sie sicher, dass Sie nur die erforderlichen Patches rendern.
    Schichtung festlegen

    Da Sie nun wissen, wie Sie dieses Beispiel mit einer einzelnen Leinwand implementieren, sehen wir uns an, ob es Möglichkeiten gibt, diese Art von Szene zu verfeinern und die Rendering-Schleife zu beschleunigen. Um Layering-Techniken verwenden zu können, müssen Sie die für die Layering erforderlichen HTML5-Canvas-Elemente identifizieren, indem Sie die Rendering-Überlappung von Entitäten ermitteln.
    Bereich neu zeichnen

    Um festzustellen, ob es eine Überlappung gibt, betrachten Sie einen unsichtbaren Bereich, den sogenannten Neuzeichnungsbereich. Der Neuzeichnungsbereich ist der Bereich, in dem die Leinwand beim Zeichnen des Bildes der Entität frei gemacht werden muss. Neuzeichnungsbereiche sind für die Rendering-Analyse wichtig, da sie es Ihnen ermöglichen, Optimierungstechniken zur Perfektionierung Ihrer gerenderten Szene zu finden, wie in Abbildung 3 dargestellt.
    Abbildung 3. Synthetische Spielansicht und Neuzeichnungsbereich
    201558170130006.jpg (300×169)

    Um den Effekt in Abbildung 3 zu visualisieren, verfügt jede Entität in der Szene über eine Überlagerung, die den Neuzeichnungsbereich darstellt, der sich über die Breite des Ansichtsfensters und die Bildhöhe der Entität erstreckt. Szenen können in drei Gruppen unterteilt werden: Hintergrund, Vordergrund und Interaktionen. Die neu gestrichenen Bereiche in der Szene sind farblich überlagert, um zwischen verschiedenen Bereichen zu unterscheiden:

    • Hintergrund – schwarz
      Wolken – rot
      Hügel – grün
      Boden – blau
      Roter Ball – blau
      Gelbes Hindernis – blau

    Bei allen Überlappungen außer Bällen und Hindernissen erstreckt sich der Neuzeichnungsbereich über die Breite des Ansichtsfensters. Bilder dieser Wesen füllen fast den gesamten Bildschirm. Aufgrund ihrer Übersetzungsanforderungen rendern sie die gesamte Breite des Ansichtsfensters, wie in Abbildung 4 dargestellt. Von Bällen und Hindernissen wird erwartet, dass sie durch dieses Ansichtsfenster passieren, und möglicherweise haben sie ihre eigenen Bereiche, die durch die Positionen der Entitäten definiert werden. Sie können die einzelnen Ebenen leicht erkennen, wenn Sie das in die Szene gerenderte Bild entfernen und nur den neu gezeichneten Bereich übrig lassen.
    Abbildung 4. Bereich neu zeichnen
    201558170200050.jpg (300×169)

    Die erste Ebene ist offensichtlich, da Sie die verschiedenen Bereiche erkennen können, die sich überlappen. Da die Ball- und Hindernisbereiche den Hügel und den Boden bedecken, können diese Einheiten in einer Ebene zusammengefasst werden, die als Interaktionsebene bezeichnet wird. Gemäß der Renderreihenfolge der Spielentitäten ist die Interaktionsschicht die oberste Ebene.

    Eine andere Möglichkeit, zusätzliche Ebenen zu finden, besteht darin, alle Bereiche ohne Überlappung zu erfassen. Die roten, grünen und blauen Bereiche, die das Ansichtsfenster einnehmen, überlappen sich nicht und bilden die zweite Ebene, den Vordergrund. Die Bereiche der Wolke und der interaktiven Entitäten überlappen sich nicht, aber da der Ball das Potenzial hat, in den roten Bereich zu springen, sollten Sie erwägen, diese Entität zu einer separaten Ebene zu machen.

    Für den schwarzen Bereich lässt sich leicht ableiten, dass die Hintergrundelemente die letzte Ebene bilden. Jeder Bereich, der das gesamte Ansichtsfenster ausfüllt (z. B. ein Hintergrundelement), sollte so betrachtet werden, dass er diesen Bereich in der gesamten Ebene ausfüllt, obwohl dies nicht für diese Szene gilt. Nachdem wir unsere drei Ebenen definiert haben, können wir damit beginnen, diese Ebene der Leinwand zuzuweisen, wie in Abbildung 5 dargestellt.
    Abbildung 5. Mehrschichtige Spielansicht
    201558170232257.jpg (228×125)

    Da Sie nun Ebenen für jedes gruppierte Element definiert haben, können Sie mit der Optimierung der Leinwandbereinigung beginnen. Das Ziel dieser Optimierung besteht darin, Verarbeitungszeit zu sparen, was durch die Reduzierung der Anzahl der bei jedem Schritt gerenderten Bildschirmgeräte erreicht werden kann. Es ist wichtig zu beachten, dass Bilder mit verschiedenen Strategien möglicherweise besser optimiert werden können. Im nächsten Abschnitt werden Optimierungsmethoden für verschiedene Entitäten oder Ebenen untersucht.
    Rendering-Optimierung

    Die Optimierung von Entitäten ist der Kern der mehrschichtigen Strategie. Durch das Layering von Entitäten können Rendering-Strategien übernommen werden. Typischerweise versuchen Optimierungstechniken, den Overhead zu eliminieren. Wie in Tabelle 1 erwähnt, ist durch die Einführung von Ebenen ein erhöhter Speicheraufwand entstanden. Die hier besprochenen Optimierungstechniken reduzieren den Arbeitsaufwand des Prozessors, um das Spielen zu beschleunigen. Unser Ziel ist es, einen Weg zu finden, den Platz zum Rendern zu reduzieren und so viele Render- und Clean-Aufrufe wie möglich aus jedem Schritt zu entfernen.
    Einzelne Entität löschen

    Die erste Optimierung zielt darauf ab, Speicherplatz freizugeben und die Verarbeitung zu beschleunigen, indem nur die Teilmenge des Bildschirms gelöscht wird, aus der die Entität besteht. Reduzieren Sie zunächst den Betrag des Neuzeichnungsbereichs, der die transparenten Pixel um jedes Element des Bereichs überlappt. Die Verwendung dieser Technik umfasst relativ kleine Objekte, die einen kleinen Bereich des Ansichtsfensters ausfüllen.

    Das erste Ziel sind die Ball- und Hinderniseinheiten. Bei der Löschtechnik für einzelne Entitäten wird die Position gelöscht, an der die Entität im vorherigen Frame gerendert wurde, bevor die Entität an ihre neue Position gebracht wird. Wir werden einen Bereinigungsschritt beim Rendern jeder Entität einführen und den Begrenzungsrahmen des Bildes der Entität speichern. Durch das Hinzufügen dieses Schritts wird das Entitätsobjekt so geändert, dass es den Bereinigungsschritt enthält, wie in Listing 5 gezeigt.
    Listing 5. Entitäten mit Single-Box-Clearing

    XML/HTML-CodeInhalt in die Zwischenablage kopieren
    1. var Entity = function() {
    2. /**  
    3.      Initialisierung und andere Methoden   
    4.      **/
    5. /**  
    6.      * Aufruf rendern, um die Entität zu zeichnen   
    7.      *   
    8.      * @param {CanvasRenderingContext2D} Kontext   
    9.      */
    10. this.render = function(context) {
    11. context.clearRect(
    12. this.prevX,
    13. this.prevY,
    14. this.width,
    15. this.height);
    16. context.drawImage(this.image, this.x, this.y);
    17. thisthis.prevX = this.x;
    18. thisthis.prevY = this.y;
    19. }
    20. };

    Eine Aktualisierung der Renderfunktion führt einen clearRect-Aufruf ein, der vor dem regulären drawImage erfolgt. Für diesen Schritt muss das Objekt den vorherigen Standort speichern. Abbildung 6 zeigt die vom Probanden unternommenen Schritte in Bezug auf die vorherige Position.
    Abbildung 6. Klares Rechteck
    201558170256838.jpg (333×299)

    Sie können diese Rendering-Lösung implementieren, indem Sie für jede Entität, die vor dem Aktualisierungsschritt aufgerufen wird, eine Clear-Methode erstellen (in diesem Artikel wird die Clear-Methode jedoch nicht verwendet). Sie können diese Clearing-Strategie auch in PanningEntity einführen, um Clearing für Boden- und Cloud-Entitäten hinzuzufügen, wie in Listing 6 gezeigt.
    Listing 6. PanningEntity mit Einzelbox-Clearing

    XML/HTML-CodeInhalt in die Zwischenablage kopieren
    1. var PanningEntity = function() {   
    2.     /**  
    3.      Initialisierung und andere Methoden   
    4.      **/   
    5.     
    6.     /**  
    7.      * Aufruf rendern, um das geschwenkte Element zu zeichnen   
    8.      *   
    9.      * @param {CanvasRenderingContext2D} Kontext   
    10.      */   
    11.     this.render = function(context) {   
    12.         context.clearRect(   
    13.             this.x,   
    14.             this.y,   
    15.             context.canvas.width,   
    16.             this.height);   
    17.         context.drawImage(   
    18.             dieses Bild,   
    19.             this.x - this.width,   
    20.             this.y - this.height);   
    21.         context.drawImage(   
    22.             dieses Bild,   
    23.             this.x,   
    24.             this.y);   
    25.         context.drawImage(   
    26.             dieses Bild,   
    27.             this.x   this.width,   
    28.             this.y   this.height);   
    29.     }   
    30. };  

    Da sich die PanningEntity über das gesamte Ansichtsfenster erstreckt, können Sie die Leinwandbreite als Größe des freimachenden Rechtecks ​​verwenden. Wenn Sie diese Räumungsstrategie verwenden, erhalten Sie neu gezeichnete Bereiche, die für Wolken, Hügel und Bodenobjekte definiert wurden.

    Um Cloud-Entitäten weiter zu optimieren, können Wolken in separate Einheiten mit eigenen Neuzeichnungsbereichen unterteilt werden. Dadurch wird der Bildschirmbereich, der innerhalb des Cloud-Neuzeichnungsbereichs frei gemacht werden muss, erheblich reduziert. Abbildung 7 zeigt den neuen Neuzeichnungsbereich.
    Abbildung 7. Wolke mit separaten Neuzeichnungsbereichen
    201558170334513.jpg (300×169)

    Eine Single-Entity-Clearing-Strategie führt zu einer Lösung, die die meisten Probleme in einem mehrschichtigen Canvas-Spiel wie diesem löst, aber dennoch optimiert werden kann. Um die Extremfälle für diese Rendering-Strategie zu finden, gehen wir davon aus, dass der Ball mit dem Dreieck kollidiert. Wenn zwei Entitäten kollidieren, ist es möglich, dass sich die Neuzeichnungsbereiche der Entität überlappen und ein unerwünschtes Rendering-Artefakt entsteht. Eine weitere Bereinigungsoptimierung, die besser für möglicherweise kollidierende Elemente geeignet ist und auch der Schichtung zugute kommt.
    Schmutziges Rechteck klar

    Wenn es keine einzige Reinigungsstrategie gibt, kann die Reinigungsstrategie für schmutzige Rechtecke eine leistungsstarke Alternative sein. Sie können diese Räumungsstrategie bei großen Einheiten anwenden, deren Bereiche neu gestrichen wurden, wie z. B. dichte Partikelsysteme oder Weltraumspiele mit Asteroiden.

    Konzeptionell erfasst der Algorithmus den Neuzeichnungsbereich aller vom Algorithmus verwalteten Entitäten und löscht den gesamten Bereich in einem Clear-Aufruf. Für eine zusätzliche Optimierung entfernt diese Bereinigungsstrategie auch doppelte Bereinigungsaufrufe, die von jeder unabhängigen Entität durchgeführt werden, wie in Listing 7 gezeigt.
    Listing 7.DirtyRectManager

    XML/HTML-CodeInhalt in die Zwischenablage kopieren
    1. var DirtyRectManager = function() {   
    2.     // Stellen Sie den linken und oberen Rand auf den maximal möglichen Wert ein  
    3.     // (die Leinwandbreite) und rechts und unten bis zum am wenigsten   
    4.     
    5.     // „Links“ und „oben“ werden kleiner, wenn weitere Entitäten hinzugefügt werden   
    6.     this.left   = canvas.width;   
    7.     this.top    = canvas.height;   
    8.     
    9.     // Rechts und unten werden größer, wenn weitere Entitäten hinzugefügt werden   
    10.     dieses.richtig  = 0;   
    11.     this.bottom = 0;   
    12.     
    13.     // Dirty-Check, um ein Löschen zu vermeiden, wenn keine Entitäten hinzugefügt wurden   
    14.     this.isDirty = false;   
    15.     
    16.     // Anderer Initialisierungscode   
    17.     
    18.     /**  
    19.      * Andere Dienstprogrammmethoden   
    20.      */   
    21.     
    22.     /**   
    23.      * Fügt die Dirty-Rect-Parameter hinzu und markiert den Bereich als Dirty   
    24.      *    
    25.      * @param {number} x   
    26.      * @param {number} y   
    27.      * @param {number} width   
    28.      * @param {Nummer} Höhe   
    29.      */   
    30.     this.addDirtyRect = function(x, y, width, height) {   
    31.         // Berechnen Sie die Rechteckkanten aus   
    32.         var links   = x;   
    33.         var right  = x   width;   
    34.         var top    = y;   
    35.         var bottom = y   height;   
    36.     
    37.         // Min of left and entity left   
    38.         this.left   = left < this.left      left   : this.left;   
    39.         // Maximales Recht und Entitätsrecht   
    40.         this.right  = right > this.right    right  : this.right;   
    41.         // Min of Top und Entity Top   
    42.         this.top    = top < this.top        top    : this.top;   
    43.         // Max of bottom und entity bottom   
    44.         this.bottom = bottom > this.bottom  bottom : this.bottom;   
    45.     
    46.         this.isDirty = true;   
    47.     };   
    48.     
    49.     /**  
    50.      * Löscht den Rechteckbereich, wenn der Manager verschmutzt ist  
    51.      *   
    52.      * @param {CanvasRenderingContext2D} Kontext   
    53.      */   
    54.     this.clearRect = function(context) {   
    55.         if (!this.isDirty) {   
    56.             zurück;   
    57.         }  
    58.     
    59.         // Löschen das berechnete Rechteck   
    60.         context.clearRect(   
    61.             this.left,   
    62.             this.top,   
    63.             this.right - this.left,   
    64.             this.bottom - this.top);   
    65.     
    66.         // Basiswerte zurücksetzen   
    67.         this.left   = canvas.width;   
    68.         this.top    = canvas.height;   
    69.         this.right  = 0;   
    70.         this.bottom = 0;   
    71.         this.isDirty = false;   
    72.     }   
    73. };  

    将脏矩形算法集成到渲染循环,这要求在进行渲染调用之前调用清单 7中的管理器.将实体添加到管理器,使管理器可以在清除时计算清除矩形的维度.虽然管理器会产生预期的优化,但根据游戏循环,管理器能够针对游戏循环进行优化,如图 8所示。
    图 8.交互层的重绘区域
    201558170548392.jpg (255×195)

    1.  重叠,并被收集到一个脏矩形中.
      帧 4 – 脏矩形被清除.

    2. 图 8显示了由针对在交互层的实体的算法计算出的重绘区域。因为游戏在这一层上包含交互,所以脏矩形策略足以解决交互和重叠的重绘区域问题.
    作为清除的重写


    对于在恒定重绘区域中动画的完全不透明实体,可以使用重写作为一项优化技术.将不透明的位图渲染为一个区域(默认的合成操作),这会将像素放在该区域中,不需要考虑该区域中的原始渲染会覆盖原来的区域.

    通过在之前的渲染的上方重新渲染图像,重写可以加快地面实体.也可以通过相同的方式加快最大的层,比如背景.

    通过减少每一层的重绘区域,您已经有效地为层和它们所包含的实体找到优化策略

    结束语
    对画布进行分层是一个可以应用于所有交互式实时场景的优化策略.如果想利用分层实现优化,您需要通过分析场景的重绘区域来考虑场景如何重叠这些区域.一些场景是具有重叠的重绘区域的集合,可以定义层,因此它们是渲染分层画布的良好候选.如果您需要粒子系统或大量物理对象碰撞在一起, 对画布进行分层可能是一个很好的优化选择。

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage