HTML5-Spiel (Canvas) - UI-Techniken?

23

Ich bin dabei, mit PhoneGap ein JavaScript / HTML5-Spiel (mit Canvas) für Handys (Android / iPhone / WebOS) zu erstellen. Ich versuche gerade herauszufinden, wie die Benutzeroberfläche und das Spielbrett aufgebaut werden sollen und wie sie interagieren sollen, aber ich bin mir nicht sicher, welche Lösung die beste ist. Folgendes kann ich mir vorstellen:

Erstellen Sie die Benutzeroberfläche direkt im Erstellungsbereich, indem Sie z. B. drawImage und fillText verwenden. Erstellen Sie Teile der Benutzeroberfläche außerhalb des Erstellungsbereichs mit regulären DOM-Objekten und schweben Sie dann ein Div über den Erstellungsbereich, wenn Benutzeroberflächenelemente den Erstellungsbereich des Spielbretts überlappen müssen. Gibt es andere mögliche Techniken, mit denen ich die Benutzeroberfläche des Spiels erstellen kann, an die ich nicht gedacht habe? Und welche davon würden als "Standard" bezeichnet werden (ich weiß, dass HTML5-Spiele nicht sehr beliebt sind, also gibt es wahrscheinlich noch keine "Standard" -Methode)? Und zu guter Letzt, welchen Weg würdest DU empfehlen / benutzen?

Vielen Dank im Voraus!

Jason L.
quelle
Denken Sie daran, dass Canvas im IE noch nicht unterstützt wird (IE9 wird dies angeblich tun). Es gibt einen JavaScript-Patch, mit dem versucht wird, ihn im IE zum Laufen zu bringen, aber er funktioniert nicht gut (SLOW as Hell ... das ist es nicht wert).
1
@Adam - Siehe flashcanvas: flashcanvas.net
ehsanul
Ich benutze dom-Elemente als GUI, mehrere schwebende Divs als "Windows" mit einem Fenster, das Canvas-Elemente enthält (eigentliches Spiel). Und es gibt immer diese Option: developer.mozilla.org/en-US/docs/HTML/Canvas/… :)
Kikaimaru

Antworten:

18

Beide Lösungen (Zeichnen auf der Leinwand im Vergleich zu herkömmlichem HTML / CSS) sind vollständig gültig und funktionieren einwandfrei. Einige Dinge zu beachten:

  • Wenn Sie bereits eine Canvas-basierte Bibliothek verwenden, wird Ihr Code möglicherweise übersichtlicher, wenn Sie weiterhin Canvas verwenden, anstatt zusätzliche (DOM-basierte) Methoden für die Benutzeroberfläche zu verwenden.
  • Wenn Ihre Benutzeroberfläche extrem textintensiv ist (mit Dialogen usw.), ist es möglicherweise einfacher, sie über HTML / CSS zu implementieren. Zum Beispiel ist es ziemlich trivial, dass Text in einem DOM-Element fließt (mit Umbruch und Absatzabstand) und vergleichsweise schwierig in Canvas zu implementieren ist.
  • Abhängig von der verwendeten Bibliothek ist es möglicherweise viel einfacher, die Klickbehandlung für DOM-Elemente zu implementieren, als in Ihrer Zeichenfläche. Wenn Sie beispielsweise einen Klick auf die Schaltfläche "Ok" erkennen möchten, ist dies in der HTML / JS-Welt eine triviale Aufgabe. Im Canvas-Bereich müssen Sie jedoch den Klick auf ein anderes Element anhören und dessen Koordinaten überprüfen, um festzustellen, wo der Klick stattgefunden hat.
  • Einige Benutzerprogramme (insbesondere mobile Geräte) können bei der Verwendung von DOM-Elementen, die Text enthalten, schwierig sein. Beispielsweise möchte Mobile Safari möglicherweise ein Modal mit den Tools zum Kopieren / Einfügen öffnen. Das Verhindern dieses Verhaltens ist möglicherweise schwierig und im Canvas-Bereich wahrscheinlich einfacher.

Einige davon werden subjektiv sein; Ein Entwickler, von dem ich weiß, dass er es immer bevorzugt, Canvas zu verwenden, da DOM für ihn nur hässlich und wortreich ist. Da beide Lösungen problemlos funktionieren, würde ich einen einfachen Bildschirm in Ihrer App auswählen, ihn mit beiden Methoden schnell separat entwickeln und feststellen, welcher sich einfacher / besser anfühlt.

Viel Glück!

richtaur
quelle
Danke für deine Antwort! Sehr gute Punkte. Ich baue gerade meinen eigenen Motor. Begann es mit Canvas, werde es aber ein wenig modifizieren, um CSS3 / WebKit-Zeug zu testen. Der einzige Grund, warum ich mein eigenes baue, ist, dass das Spiel für eine echte Engine zu einfach ist. Wir haben nicht einmal wirklich eine Hauptspielrunde. Der einzige Grund, warum es überhaupt Animation gibt, aber wenn man bedenkt, wie selten diese vorkommen, könnten wir wahrscheinlich die Timer nach Bedarf starten / stoppen :)
Jason L.
5

Ich habe easeljs für meine Canvas-Interaktion verwendet.

Es ist ziemlich gut und erleichtert solides Design. Eines der Hauptmerkmale, für das ich mich entschieden habe, war die Möglichkeit, die Position Ihrer Canvas-Objekte und dom-Elemente zu synchronisieren.

Dies macht es einfach, CSS-Sprechblasen und statische UI-Elemente wie den Hud-Frame und dergleichen zu erstellen.

Der Vorteil, den dies für Browser hat, ist, dass Sie die reiche Leinwand erhalten, aber die kleineren und statischen Dinge an den Dom verpfänden können, um die Leistung in Schach zu halten.

G. Davids
quelle
4

Canvas ist auf mobilen Plattformen langsam, zumindest auf mobilen Safaris. Daher sollten Sie die CSS-basierte Positionierung von Objekten auf diesen Plattformen verwenden. Verwenden Sie speziell "translate3d", um das hardwarebeschleunigte Rendern von Objekten zu aktivieren.

Schauen Sie sich die CAAT-Bibliothek für Canvas an, sie ist schnell und Sie können CSS-gestützte "Akteure" verwenden, ohne die Spiellogik zu ändern.

Ich kann noch keine Links posten, aber hier sind einige Pseudolinks http://labs.hyperandroid.com/animation

einTagwirdnunmachen
quelle
Ich denke, der Repo-Link auf der CAAT-Seite verweist auf den alten, also stellen Sie sicher, dass Sie diesen stattdessen verwenden! repo: github.com/hyperandroid/CAAT
onedayitwillmake
(Entschuldigung, ich kann derzeit nur einen Link pro Beitrag hinzufügen.) Hier ist eine von mir erstellte Demo, die eine Hallo-Welt-Vorlage für CAAT enthält - onedayitwillmake.com/CAATCirclePack
onedayitwillmake
Danke für die Links, ich werde auf jeden Fall. Hör zu. Ich habe gehört, dass Canvas langsam rumort, aber normalerweise muss ich die Dinge selbst sehen :) Ich sollte auch beachten, dass das Spiel, das ich erstelle, SEHR hell auf den Animationen ist. Niemals mehr als ein oder zwei gleichzeitig und in Abständen von jeweils 5-10 Sekunden für eine Minute laufen. Nichts verrücktes. Schlagen Sie zur Überprüfung vor, überhaupt keine Canvas-Objekte zu verwenden, sondern nur einfache alte DOM-Objekte mit CSS / translate3d?
Jason L.
Um ehrlich zu sein, kann ich für Ihr spezifisches Szenario nichts sagen oder nicht. Wenn Sie jedoch speziell auf Mobile-Safari abzielen möchten, sollten Sie CSS mit divs verwenden. Das geht sehr schnell, verglichen mit meiner Erfahrung beim Neuzeichnen der Leinwand. Ich konnte mit 'translate3d' problemlos 45 bildbasierte Sprites mit 30 fps bewegen, um sie an ihren Platz zu bringen. Stellen Sie sicher, dass Sie dies im CSS für die Objekte platzieren, die Sie mit 'transform3d' verschieben möchten. Andernfalls animiert das Webkit diese Objekte an der angegebenen Stelle, anstatt sie zu platzieren. -Webkit-Übergang: transform3d 0s linear;
onedayitwillmake
2

Muss über Leinwand Langsamkeit auf dem iPhone 4 zustimmen. Ziemlich sicher, Safari Leinwand wird nicht von GL unterstützt. Mein freudiges Spiel läuft schnell auf dem iPhone 3GS und Android, aber auf dem iPhone 4 hat das Retina-Display meiner Meinung nach zu viele Pixel, oder wenn die Leinwand nicht auf GL läuft, würde dies erklären, warum es schleppt. Ich mag das Canvas-Entwicklungsmodell, habe die Option css translate3d noch nicht ausprobiert. Insbesondere habe ich GWT und den Canvas-Wrapper gwt-g2d (Optimierung / Verschleierung) verwendet. http://www.photonjunky.com/shootout.html


quelle
1

Ich würde vorschlagen, Ihre Steuerelemente als HTML-Elemente wie menuund commandaus Gründen der Barrierefreiheit beizubehalten. Mit ein bisschen CSS können Sie Elemente über einer Zeichenfläche anzeigen , ohne die vorgefertigten Funktionen von HTML zu verlieren.

zzzzBov
quelle
1

Ich weiß, dass dies eine alte Frage ist, aber heute (März 2013) wissen wir es besser. Ich entschloss mich zu antworten, falls jemand anders hier herein stolperte, wie ich es tat. Ich muss mit den meisten anderen Antworten nicht einverstanden sein. Sie gelten wahrscheinlich für die Entwicklung von Webbrowsern, jedoch nicht für mobile Geräte. Es macht einen großen Unterschied, welchen Pfad Sie wählen (DOM- oder Canvas-Animation). Die Android-Webansicht ist an sich völlig nutzlos (langsam, stotternd), was Phonegap für die Entwicklung von Android-Spielen nutzlos macht, es sei denn, Sie können die Hardwarebeschleunigung anwenden, die derzeit nur mithilfe von Canvas-Animation und einem geeigneten Framework möglich ist. Weitere Informationen finden Sie in dieser Antwort .

Per Quested Aronsson
quelle
0

Sie können es auf millionenfache Weise tun. Sie fühlen sich jedoch am wohlsten und Ihre Ingenieure fühlen sich am sichersten.

Wenn Sie Inspiration oder ein Codebeispiel suchen, ist hier eine Möglichkeit, wie ich es mache. Ich habe eine Funktion, die wiederholt ein Menü zeichnet, bis eine Taste gedrückt wird. Wenn der Knopf gedrückt wird, wird das Spiel geladen und die alten Klickereignis-Listener des Menüs werden entfernt und neue Klickereignis-Listener des Spiels werden hinzugefügt. Ich beende auch die alte Draw-Schleife des Menüs und starte eine neue Game Draw-Schleife. Hier sind einige ausgewählte Ausschnitte, die Ihnen einen Eindruck davon geben, wie es gemacht wird:

Game.prototype.loadMenu = function() {
  var game = this;
  var can = this.canvas;

  // now we can use the mouse for the menu
  can.addEventListener('click', game.menuClickEvent, false);
  can.addEventListener('touchstart', game.menuClickEvent, false);

  // draw menu
  this.loop = setInterval(function() { game.drawMenu() }, 30);
};

Game.prototype.drawMenu = function() {
  // ... draw the menu
}

Game.prototype.loadLevel = function(levelstring) {
  // unload menu
  var can = this.canvas;
  var game = this;
  can.removeEventListener('click', game.menuClickEvent, false);
  can.removeEventListener('touchstart', game.menuClickEvent, false);

  if (this.loop) clearInterval(this.loop);

  // ... other level init stuff


  // now we can press keys for the game
  //can.addEventListener('click', game.gameClickEvent, false);
  can.addEventListener('touchstart', game.gameClickEvent, false);
  can.addEventListener('keydown', game.gameKeyDownEvent, false);

  this.loop = setInterval(function() { game.tick() }, 30);
}

// called from tick()
Game.prototype.draw = function(advanceFrame) {
  // ...
}

Auf diese Weise kann ich Spielzeichnen und Spielereignisse von Menüzeichnen und Menüereignissen trennen. Außerdem habe ich die Möglichkeit, Spiel- / Animationselemente in meinen Menüs zu verwenden, wenn ich möchte, dass sie wirklich hübsch aussehen.

Simon Sarris
quelle