Ist die Verwendung mehrerer Canvas-Objekte eine gute Vorgehensweise?

11

Wir entwickeln ein Jump-and-Run-Spiel mit HTML5 und JavaScript und müssen dafür ein eigenes Spiel-Framework erstellen. Hier haben wir einige Schwierigkeiten und möchten Sie um Rat fragen:

Wir haben ein "Stage" -Objekt, das die Wurzel unseres Spiels darstellt und ein globaler Div-Wrapper ist. Die Bühne kann mehrere "Szenen" enthalten, die auch Div-Elemente sind. Wir würden eine Szene für die Spielaufgabe, für die Pause usw. implementieren und zwischen ihnen wechseln. Jede Szene kann daher mehrere "Ebenen" enthalten, die eine Leinwand darstellen. Diese Ebenen enthalten "ObjectEntities", die Bilder oder andere Formen wie Rechtecke usw. darstellen. Jede Objectentity verfügt über eigene temporäre Canvas, um Bilder für eine Entität zeichnen zu können, während eine andere ein Rechteck enthält.

Wir haben eine aktive Szene in unserer Bühne festgelegt. Wenn das Spiel gespielt wird, wird nur die aktive Szene gezeichnet. Calling activeScene.draw()ruft alle Unterschichten zum Zeichnen auf, die ihre Entitäten zeichnen (Calling drawImage(entity.canvas)). Aber ist das eine gute Praxis? Haben Sie mehrere Leinwand zum Zeichnen? Jede Spielschleife, jeder Ebenenkontext wird gelöscht und erneut gezeichnet. ZB haben wir nur noch eine Hintergrundebene,… wäre es nicht sinnvoller, diese einmal zu zeichnen und sie nicht jedes Mal zu löschen und neu zu zeichnen? Oder sollten wir zum Beispiel in der Bühne eine globale Leinwand verwenden und diese Leinwand nur zum Zeichnen verwenden? Aber wir dachten, das wäre zu teuer ...

user1818924
quelle
1
Warum genau hast du mehrere Leinwand? Wenn es sich um eine Optimierung handelt, warum testen Sie nicht einfach mit und ohne?
Denys Séguret
1
Sie sollten die "andere Frage" entfernen. Und
poste

Antworten:

6

Diese Seite enthält eine hervorragende Liste von Optimierungen, die an der Leinwand vorgenommen werden können. Im Abschnitt "Verwenden Sie mehrschichtige Leinwände für komplexe Szenen" wird beschrieben, warum es in vielen Fällen besser ist, mehrere Leinwandobjekte zu haben, da Sie große teure Objekte (Hintergrundbilder) nicht so häufig neu zeichnen müssen wie kleinere, sich schnell bewegende ( Projektile). Hier ist ein Tutorial , um Ihnen den Einstieg zu erleichtern. Kurz gesagt, erstellen Sie einfach eine Reihe von Leinwänden für Dinge, die anders gezeichnet werden müssen, und richten Sie sie mit der absoluten Positionierung aus:

position:absolute;
left:0px;
top:0px;

Jedes Canvas-Objekt kann mithilfe des Z-Index benannt und überlagert werden:

<canvas id="layer1" style="z-index: 1;" />
<canvas id="layer2" style="z-index: 2;" />

Zeichnen Sie abschließend auf die verschiedenen Kontexte:

function draw1() {
    context1... // draw background
}

function draw2() {
    context2... // draw character
}

function draw3() {
    context3... // draw bullets
}
CuddleBunny
quelle
2
Es wäre schön, wenn Sie aus diesen Links eine kleine Zusammenfassung machen könnten. Andernfalls wird Ihre Antwort möglicherweise ungültig, wenn die Links nicht mehr funktionieren ...
MartinTeeVarga
Danke, diese Links sind ziemlich gut. Ich habe es geschafft, nur spezielle schmutzige Bereiche neu zu zeichnen, wenn sich ein Objekt zum Beispiel bewegt.
user1818924
@ sm4 Guter Punkt, ich werde etwas hinzufügen.
CuddleBunny
2

Contre Jour macht das tatsächlich. Ich kenne nicht viele Details, aber möglicherweise finden Sie weitere technische Hinweise. Wenn Sie ihr Spiel spielen, glaube ich, dass jede der Landmassen, mit denen Ihr Charakter interagiert, Leinwände sind.

Es scheint eine gute Idee zu sein, Ihre aktiven Teile des Spiels in Leinwände aufzuteilen. Wenn Sie beispielsweise ein RTS erstellen, ist die Befehlsleiste möglicherweise sinnvoll, um eine separate Zeichenfläche zu erstellen, die nur gelegentlich neu gezeichnet werden kann.

Katana314
quelle
Uns zu sagen, dass ein veröffentlichtes Spiel dies tut, ist interessant, sagt uns aber nicht, ob es eine gute Praxis ist. Vielleicht haben die Entwickler die Entscheidung bereut? Auch einige Quellen zum Nachweis ihrer Verwendung wären nett.
MichaelHouse