Was müssen Sie wissen, wenn Sie ein Flash-Spiel in HTML5 konvertieren?
Veröffentlicht: 2022-03-10Mit der zunehmenden Verwendung von HTML5 beginnen viele Unternehmen damit, ihre beliebtesten Titel zu überarbeiten, um veraltetes Flash loszuwerden und ihre Produkte an die neuesten Industriestandards anzupassen. Diese Änderung ist besonders in der Glücksspiel-/Casino- und Unterhaltungsbranche sichtbar und findet bereits seit mehreren Jahren statt, sodass bereits eine ansehnliche Auswahl an Titeln konvertiert wurde.
Leider stößt man beim Surfen im Internet ziemlich oft auf Beispiele für eine scheinbar hastige Arbeit, die zu einer Liebhaberqualität des Endprodukts führt. Aus diesem Grund ist es für Spieleentwickler eine gute Idee, sich mit dem Thema Flash-zu-HTML5-Konvertierung vertraut zu machen und zu lernen, welche Fehler zu vermeiden sind, bevor sie sich an die Arbeit machen.
Einer der Gründe für die Wahl von JavaScript anstelle von Flash ist neben den offensichtlichen technischen Problemen auch die Tatsache, dass die Umstellung Ihres Spieldesigns von SWF auf JavaScript zu einer besseren Benutzererfahrung führen kann, was wiederum zu einem modernen Aussehen führt. Aber wie geht das? Benötigen Sie einen dedizierten JavaScript-Spielkonverter, um diese veraltete Technologie loszuwerden? Nun, die Konvertierung von Flash in HTML5 kann ein Kinderspiel sein – hier ist, wie man sich darum kümmert.
Empfohlene Lektüre : Prinzipien des HTML5-Spieldesigns
So verbessern Sie das HTML5-Spielerlebnis
Das Konvertieren eines Spiels auf eine andere Plattform ist eine hervorragende Gelegenheit, es zu verbessern, seine Probleme zu beheben und das Publikum zu vergrößern. Im Folgenden sind einige Dinge aufgeführt, die einfach durchgeführt werden können und eine Überlegung wert sind:
Unterstützung mobiler Geräte
Die Konvertierung von Flash in JavaScript ermöglicht es, ein breiteres Publikum (Benutzer von Mobilgeräten) zu erreichen; Unterstützung für Touchscreen-Steuerung muss normalerweise auch in das Spiel implementiert werden. Glücklicherweise unterstützen jetzt sowohl Android- als auch iOS-Geräte auch WebGL, sodass ein Rendering mit 30 oder 60 FPS normalerweise problemlos erreicht werden kann. In vielen Fällen werden 60 FPS keine Probleme bereiten, was sich mit der Zeit, da mobile Geräte immer performanter werden, nur verbessern wird.- Verbessernde Leistung
Wenn es darum geht, ActionScript und JavaScript zu vergleichen, ist letzteres schneller als das erste. Abgesehen davon ist das Konvertieren eines Spiels eine gute Gelegenheit, die im Spielcode verwendeten Algorithmen zu überdenken. Mit der JavaScript-Spieleentwicklung können Sie sie optimieren oder ungenutzten Code, der von ursprünglichen Entwicklern hinterlassen wurde, vollständig entfernen. - Behebung von Fehlern und Verbesserung des Gameplays
Wenn neue Entwickler den Quellcode des Spiels untersuchen, kann dies helfen, bekannte Fehler zu beheben oder neue und sehr seltene Fehler zu entdecken. Dies würde das Spielen des Spiels für die Spieler weniger irritierend machen, was dazu führen würde, dass sie mehr Zeit auf Ihrer Website verbringen und dazu ermutigt würden, Ihre anderen Spiele auszuprobieren. - Hinzufügen von Webanalysen
Neben der Verfolgung des Datenverkehrs kann die Webanalyse auch verwendet werden, um Erkenntnisse darüber zu sammeln, wie sich Spieler in einem Spiel verhalten und wo sie während des Spiels stecken bleiben. - Lokalisierung hinzufügen
Dies würde das Publikum vergrößern und ist wichtig für Kinder aus anderen Ländern, die Ihr Spiel spielen. Oder vielleicht ist Ihr Spiel nicht auf Englisch und Sie möchten diese Sprache unterstützen?
Warum das Überspringen von HTML und CSS für die Benutzeroberfläche im Spiel die Spielleistung verbessert
Wenn es um die Entwicklung von JavaScript-Spielen geht, kann es verlockend sein, HTML und CSS für Schaltflächen, Widgets und andere GUI-Elemente im Spiel zu nutzen. Mein Rat ist, hier vorsichtig zu sein. Es ist kontraintuitiv, aber die tatsächliche Nutzung von DOM-Elementen ist bei komplexen Spielen weniger leistungsfähig und gewinnt auf Mobilgeräten an Bedeutung. Möchte man auf allen Plattformen konstant 60 FPS erreichen, dann ist unter Umständen ein Verzicht auf HTML und CSS erforderlich.
Nicht interaktive GUI-Elemente wie Gesundheitsbalken, Munitionsbalken oder Punktezähler können einfach in Phaser implementiert werden, indem reguläre Bilder (die Phaser.Image
-Klasse) verwendet werden, wobei die .crop
Eigenschaft zum Trimmen und die Phaser.Text
-Klasse für die Einfachheit genutzt werden Textetiketten.
Solche interaktiven Elemente wie Schaltflächen und Kontrollkästchen können mithilfe der integrierten Phaser.Button
-Klasse implementiert werden. Andere, komplexere Elemente können aus verschiedenen einfachen Typen zusammengesetzt sein, wie Gruppen, Bilder, Schaltflächen und Textbeschriftungen.
Hinweis: Jedes Mal, wenn Sie ein Phaser.Text- oder PIXI.Text-Objekt instanziieren, wird eine neue Textur erstellt, auf der Text gerendert wird. Diese zusätzliche Textur unterbricht das Vertex-Batching, also achten Sie darauf, nicht zu viele davon zu haben .
So stellen Sie sicher, dass benutzerdefinierte Schriftarten geladen wurden
Wenn Sie Text mit einer benutzerdefinierten Vektorschrift (z. B. TTF oder OTF) rendern möchten, müssen Sie sicherstellen, dass die Schriftart bereits vom Browser geladen wurde, bevor Sie Text rendern. Phaser v2 bietet keine Lösung für diesen Zweck, aber es kann eine andere Bibliothek verwendet werden: Web Font Loader.
Angenommen, Sie haben eine Schriftdatei und binden den Web Font Loader in Ihre Seite ein, dann finden Sie unten ein einfaches Beispiel zum Laden einer Schrift:
Erstellen Sie eine einfache CSS-Datei, die vom Web Font Loader geladen wird (Sie müssen sie nicht in Ihren HTML-Code einfügen):
@font-face { // This name you will use in JS font-family: 'Gunplay'; // URL to the font file, can be relative or absolute src: url('../fonts/gunplay.ttf') format('truetype'); font-weight: 400; }
Definieren Sie nun eine globale Variable namens WebFontConfig
. Etwas so Einfaches wie dieses wird normalerweise ausreichen:
var WebFontConfig = { 'classes': false, 'timeout': 0, 'active': function() { // The font has successfully loaded... }, 'custom': { 'families': ['Gunplay'], // URL to the previously mentioned CSS 'urls': ['styles/fonts.css'] } };
Denken Sie am Ende daran, Ihren Code in den oben gezeigten "aktiven" Callback einzufügen. Und das ist es!
So machen Sie es Benutzern einfacher, das Spiel zu speichern
Um lokale Daten dauerhaft in ActionScript zu speichern, würden Sie die SharedObject-Klasse verwenden. In JavaScript ist der einfache Ersatz die localStorage-API, die es ermöglicht, Zeichenfolgen für den späteren Abruf zu speichern und das Neuladen von Seiten zu überleben.
Das Speichern von Daten ist sehr einfach:
var progress = 15; localStorage.setItem('myGame.progress', progress);
Beachten Sie, dass im obigen Beispiel die progress
, die eine Zahl ist, in eine Zeichenfolge konvertiert wird.
Das Laden ist auch einfach, aber denken Sie daran, dass die abgerufenen Werte Zeichenfolgen oder null
sind, wenn sie nicht existieren.
var progress = parseInt(localStorage.getItem('myGame.progress')) || 0;
Hier stellen wir sicher, dass der Rückgabewert eine Zahl ist. Wenn es nicht existiert, wird der progress
0 zugewiesen.
Sie können auch komplexere Strukturen speichern und abrufen, z. B. JSON:
var stats = {'goals': 13, 'wins': 7, 'losses': 3, 'draws': 1}; localStorage.setItem('myGame.stats', JSON.stringify(stats)); … var stats = JSON.parse(localStorage.getItem('myGame.stats')) || {};
Es gibt einige Fälle, in denen das localStorage-Objekt nicht verfügbar ist. Zum Beispiel bei Verwendung des file://
Protokolls oder wenn eine Seite in einem privaten Fenster geladen wird. Sie können die try- und catch-Anweisung verwenden, um sicherzustellen, dass Ihr Code weiterhin funktioniert und Standardwerte verwendet, wie im folgenden Beispiel gezeigt:
try { var progress = localStorage.getItem('myGame.progress'); } catch (exception) { // localStorage not available, use default values }
Beachten Sie außerdem, dass die gespeicherten Daten pro Domain und nicht pro URL gespeichert werden. Wenn also das Risiko besteht, dass viele Spiele auf einer einzigen Domain gehostet werden, dann ist es besser, beim Speichern ein Präfix (Namespace) zu verwenden. Im obigen Beispiel 'myGame.'
ist ein solches Präfix und Sie möchten es normalerweise durch den Namen des Spiels ersetzen.
Hinweis : Wenn Ihr Spiel in einen Iframe eingebettet ist, bleibt localStorage nicht auf iOS bestehen. In diesem Fall müssten Sie die Daten stattdessen im übergeordneten Iframe speichern .
So nutzen Sie das Ersetzen des Standard-Fragment-Shaders
Wenn Phaser und PixiJS Ihre Sprites rendern, verwenden sie einen einfachen internen Fragment-Shader. Es hat nicht viele Funktionen, weil es auf eine Geschwindigkeit zugeschnitten ist. Sie können diesen Shader jedoch für Ihre Zwecke ersetzen. Sie können es beispielsweise nutzen, um Überzeichnungen zu überprüfen oder mehr Funktionen für das Rendern zu unterstützen.
Unten sehen Sie ein Beispiel dafür, wie Sie Ihren eigenen Standard-Fragment-Shader für Phaser v2 bereitstellen:
function preload() { this.load.shader('filename.frag', 'shaders/filename.frag'); } function create() { var renderer = this.renderer; var batch = renderer.spriteBatch; batch.defaultShader = new PIXI.AbstractFilter(this.cache.getShader('filename.frag')); batch.setContext(renderer.gl); }
Hinweis: Es ist wichtig, sich daran zu erinnern, dass der Standard-Shader für ALLE Sprites sowie beim Rendern in eine Textur verwendet wird. Denken Sie auch daran, dass die Verwendung komplexer Shader für alle Sprites im Spiel die Renderleistung stark reduziert .
So ändern Sie die Tönungsmethode mit einem Standard-Shader
Benutzerdefinierte Standard-Shader können verwendet werden, um die Standard-Tönungsmethode in Phaser und PixiJS zu ersetzen.
Das Abtönen in Phaser und PixiJS funktioniert durch Multiplizieren von Texturpixeln mit einer bestimmten Farbe. Multiplikation verdunkelt Farben immer, was offensichtlich kein Problem ist; es unterscheidet sich einfach von der Flash-Tönung. Für eines unserer Spiele mussten wir eine Tönung ähnlich wie bei Flash implementieren und entschieden, dass ein benutzerdefinierter Standard-Shader verwendet werden könnte. Unten ist ein Beispiel für einen solchen Fragment-Shader:
// Specific tint variant, similar to the Flash tinting that adds // to the color and does not multiply. A negative of a color // must be supplied for this shader to work properly, ie set // sprite.tint to 0 to turn whole sprite to white. precision lowp float; varying vec2 vTextureCoord; varying vec4 vColor; uniform sampler2D uSampler; void main(void) { vec4 f = texture2D(uSampler, vTextureCoord); float a = clamp(vColor.a, 0.00001, 1.0); gl_FragColor.rgb = f.rgb * vColor.a + clamp(1.0 - vColor.rgb/a, 0.0, 1.0) * vColor.a * fa; gl_FragColor.a = fa * vColor.a; }
Dieser Shader hellt Pixel auf, indem er der Tönung eine Grundfarbe hinzufügt. Damit dies funktioniert, müssen Sie ein Negativ der gewünschten Farbe liefern. Um weiß zu werden, müssen Sie daher Folgendes festlegen:
sprite.tint = 0x000000; // This colors the sprite to white Sprite.tint = 0x00ffff; // This gives red
Das Ergebnis in unserem Spiel sieht so aus (beachten Sie, wie Panzer weiß blinken, wenn sie getroffen werden):
So prüfen Sie die Überziehung, um Probleme mit der Füllrate zu erkennen
Das Ersetzen des Standard-Shaders kann auch genutzt werden, um beim Debuggen zu helfen. Unten habe ich erklärt, wie man mit einem solchen Shader Overdraw erkennen kann.
Überzeichnung tritt auf, wenn viele oder alle Pixel auf dem Bildschirm mehrfach gerendert werden. Beispielsweise nehmen viele Objekte denselben Platz ein und werden übereinander gerendert. Wie viele Pixel eine GPU pro Sekunde rendern kann, wird als Füllrate bezeichnet. Moderne Desktop-GPUs haben eine übermäßige Füllrate für übliche 2D-Zwecke, aber mobile GPUs sind viel langsamer.
Es gibt eine einfache Methode, um herauszufinden, wie oft jedes Pixel auf dem Bildschirm geschrieben wird, indem Sie den standardmäßigen globalen Fragment-Shader in PixiJS und Phaser durch diesen ersetzen:
void main(void) { gl_FragColor.rgb += 1.0 / 7.0; }
Dieser Shader hellt verarbeitete Pixel auf. Die Zahl 7,0 gibt an, wie viele Schreibvorgänge erforderlich sind, um Pixel weiß zu machen; Sie können diese Nummer nach Ihren Wünschen einstellen. Mit anderen Worten, hellere Pixel auf dem Bildschirm wurden mehrmals geschrieben, und weiße Pixel wurden mindestens 7 Mal geschrieben.
Dieser Shader hilft auch, sowohl „unsichtbare“ Objekte zu finden, die aus irgendeinem Grund noch gerendert werden, als auch Sprites, die übermäßig transparente Bereiche haben, die entfernt werden müssen (die GPU muss immer noch transparente Pixel in Ihren Texturen verarbeiten).
Das Bild auf der linken Seite zeigt, wie ein Spieler das Spiel sieht, während das Bild auf der rechten Seite den Effekt der Anwendung des Overdraw-Shaders auf dieselbe Szene zeigt.
Warum Physik-Engines Ihre Freunde sind
Eine Physik-Engine ist eine Middleware, die für die Simulation physikalischer Körper (normalerweise Starrkörperdynamik) und deren Kollisionen verantwortlich ist. Physik-Engines simulieren 2D- oder 3D-Räume, aber nicht beides. Eine typische Physik-Engine bietet:
- Objektbewegung durch Einstellen von Geschwindigkeiten, Beschleunigungen, Gelenken und Motoren;
- Erkennen von Kollisionen zwischen verschiedenen Formtypen;
- Berechnen von Kollisionsreaktionen, dh wie zwei Objekte reagieren sollten, wenn sie kollidieren.
Wir bei Merixstudio sind große Fans der Box2D-Physik-Engine und haben sie bei einigen Gelegenheiten verwendet. Es gibt ein Phaser-Plugin, das für diesen Zweck gut funktioniert. Box2D wird auch in der Unity-Game-Engine und GameMaker Studio 2 verwendet.
Während eine Physik-Engine Ihre Entwicklung beschleunigt, müssen Sie dafür einen Preis zahlen: verringerte Laufzeitleistung. Das Erkennen von Kollisionen und das Berechnen von Antworten ist eine CPU-intensive Aufgabe. Sie können auf Mobiltelefonen auf mehrere Dutzend dynamische Objekte in einer Szene beschränkt sein oder mit einer verminderten Leistung sowie einer reduzierten Bildrate tief unter 60 FPS konfrontiert sein.
Der linke Teil des Bildes ist eine Szene aus einem Spiel, während die rechte Seite dieselbe Szene zeigt, wobei die Phaser-Physik-Debug-Überlagerung oben angezeigt wird.
So exportieren Sie Sounds aus einer .fla- Datei
Wenn Sie Soundeffekte eines Flash-Spiels in einer .fla -Datei haben, dann ist es nicht möglich, sie aus der GUI zu exportieren (zumindest nicht in Adobe Animate CC 2017), da die Menüoption für diesen Zweck fehlt. Aber es gibt eine andere Lösung – ein dediziertes Skript, das genau das tut:
function normalizeFilename(name) { // Converts a camelCase name to snake_case name return name.replace(/([AZ])/g, '_$1').replace(/^_/, '').toLowerCase(); } function displayPath(path) { // Makes the file path more readable return unescape(path).replace('file:///', '').replace('|', ':'); } fl.outputPanel.clear(); if (fl.getDocumentDOM().library.getSelectedItems().length > 0) // Get only selected items var library = fl.getDocumentDOM().library.getSelectedItems(); else // Get all items var library = fl.getDocumentDOM().library.items; // Ask user for the export destination directory var root = fl.browseForFolderURL('Select a folder.'); var errors = 0; for (var i = 0; i < library.length; i++) { var item = library[i]; if (item.itemType !== 'sound') continue; var path = root + '/'; if (item.originalCompressionType === 'RAW') path += normalizeFilename(item.name.split('.')[0]) + '.wav'; else path += normalizeFilename(item.name); var success = item.exportToFile(path); if (!success) errors += 1; fl.trace(displayPath(path) + ': ' + (success ? 'OK' : 'Error')); } fl.trace(errors + ' error(s)');
So verwenden Sie das Skript zum Exportieren von Sounddateien:
- Speichern Sie den obigen Code als .jsfl -Datei auf Ihrem Computer;
- Öffnen Sie eine .fla -Datei mit Adobe Animate;
- Wählen Sie „Befehle“ → „Befehl ausführen“ aus dem oberen Menü und wählen Sie das Skript im sich öffnenden Dialog aus;
- Nun erscheint eine weitere Dialogdatei zur Auswahl des Zielverzeichnisses für den Export.
Und fertig! Sie sollten jetzt WAV-Dateien im angegebenen Verzeichnis haben. Was noch zu tun ist, ist sie beispielsweise in MP3s, OGG oder AAC umzuwandeln.
So verwenden Sie MP3s in Flash-zu-HTML5-Konvertierungen
Das gute alte MP3-Format ist zurück, da einige Patente abgelaufen sind und nun jeder Browser MP3s entschlüsseln und abspielen kann. Das erleichtert die Entwicklung etwas, da endlich keine zwei getrennten Audioformate vorbereitet werden müssen. Früher brauchten Sie zum Beispiel OGG- und AAC-Dateien, jetzt reicht MP3 aus.
Nichtsdestotrotz gibt es zwei wichtige Dinge, die Sie bei MP3 beachten müssen:
- MP3's müssen nach dem Laden dekodiert werden, was vor allem auf mobilen Geräten zeitaufwändig sein kann. Wenn Sie eine Pause sehen, nachdem alle Ihre Assets geladen wurden, bedeutet dies wahrscheinlich, dass MP3 decodiert wird.
- Das lückenlose Abspielen von geloopten MP3s ist ein wenig problematisch. Die Lösung ist die Verwendung von mp3loop, über das Sie in dem von Compu Phase veröffentlichten Artikel lesen können.
Also, warum sollten Sie Flash in JavaScript konvertieren?
Wie Sie sehen können, ist die Konvertierung von Flash in JavaScript nicht unmöglich, wenn Sie wissen, was zu tun ist. Mit Wissen und Geschick können Sie aufhören, sich mit Flash herumzuschlagen, und die flüssigen, unterhaltsamen Spiele genießen, die in JavaScript erstellt wurden. Versuchen Sie nicht, Flash zu reparieren – entfernen Sie es, bevor alle dazu gezwungen werden!
Möchten Sie mehr erfahren?
In diesem Artikel habe ich mich hauptsächlich auf Phaser v2 konzentriert. Allerdings ist jetzt eine neuere Version von Phaser verfügbar, und ich empfehle Ihnen dringend, sie auszuprobieren, da sie eine Fülle neuer, cooler Funktionen wie mehrere Kameras, Szenen, Tilemaps oder die Matter.js-Physik-Engine eingeführt hat.
Wenn Sie mutig genug sind und wirklich bemerkenswerte Dinge in Browsern erstellen möchten, dann ist WebGL das Richtige, um von Grund auf zu lernen. Es ist eine niedrigere Abstraktionsebene als verschiedene Spieleentwicklungs-Frameworks oder -Tools, ermöglicht jedoch eine höhere Leistung und Qualität, selbst wenn Sie an 2D-Spielen oder Demos arbeiten. Zu den vielen Websites, die Sie beim Erlernen der Grundlagen von WebGL nützlich finden könnten, gehören WebGL Fundamentals (verwendet interaktive Demos). Um mehr über die Adoptionsraten von WebGL-Funktionen zu erfahren, sehen Sie sich außerdem die WebGL-Statistiken an.
Denken Sie immer daran, dass es nicht zu viel Wissen gibt – besonders wenn es um die Spieleentwicklung geht!