Dynamische Textboxen mit Phaser erstellen

      0
Phaser - Dynamische Textbox

Ich arbeite in meiner Freizeit viel an meinem Phaser Adventure. Und so ein Adventure besteht natürlich auch aus einer Story mit vielen Texten. Nun stand ich vor dem Problem, eine allgemein gültige Lösung für Textboxen zu finden. Aus dieser Not heraus, entstand letztendlich eine dynamische Textbox Klasse, die ich gerne mit dir teilen möchte.

Demo & Code

Im folgenden CodePen siehst du nicht nur wie das Ganze letztendlich bei mir aussieht, sondern kannst dir auch den JavaScript Code ansehen, den ich dafür entwickelt habe. Im „Babel“ Tab kannst du ganz einfach die Variablen BOX_WIDTH und EXAMPLE_TEXT anpassen, um die dynamische Textbox zu verändern.

Schau dir den Code von Nick (@NickHatBoecker) auf CodePen an.0

Das Problem

Als ich mit der Umsetzung angefangen habe, hatte ich mir zunächst einmal eine statische Textbox Grafik, in einer festen Höhe und Breite, abgelegt. Damit stößt man allerdings ziemlich schnell an seine Grenzen, denn jeder Text beziehungsweise Inhalt muss perfekt auf diese Maße angepasst werden. Am Ende muss man dann den eigentlich stimmig ausgewählten Dialog-Text ändern, statt dass die Box sich einfach an die Länge des Textes anpasst.

Die Lösung

Du willst nicht nur kopieren & einfügen? Dann kommt hier jetzt eine kleine Erklärung zu dem CodePen von oben.

Der Einfachheit halber wollte ich ein Objekt für meine dynamische Textbox, welches ich beliebig in Phaser Szenen einfügen kann. Daher habe ich eine neue Klasse namens DynamicTextbox deklariert.

Container / constructor()

Die neue Klasse erbt ihre Eigenschaften von der Phaser Container Klasse. Das ist hilfreich um die Textbox später inklusive Hintergrund und Text im Canvas zu positionieren.

Im Konstruktor der Klasse wird zunächst der Text generiert. Das ist wichtig, damit die Box ihre Höhe an den bestehenden Text anpassen kann. Erst dann wird der Box-Hintergrund inklusive Rahmen generiert. Danach sind alle Maße der dynamischen Textbox bekannt, sodass sie mittels setPosition und den mitgelieferten Koordinaten positioniert werden kann. Aus Darstellungszwecken überschreibe ich diese Position in der create Methode allerdings, um die Box im Canvas zu zentrieren.

Text / _initText()

Für die Textbox müssen wir zuerst den Text generieren. Das ist wichtig, damit sich der Boxhintergrund und der -Rahmen an den Text anpassen können. Damit der Text nicht direkt am Box-Rahmen klebt, definieren wir ein Padding (das kennst du vllt schon von der Programmierung mit CSS). Deshalb setzen wir die X und Y Koordinaten jeweils auf den Padding-Wert. Als nächstes kümmern wir uns um den automatischen Umbruch. Damit der Text nicht in einer Zeile aus der Box hinaus läuft, geben wir in dem TextStyle Objekt eine Breite namens width mit. Diese gibt an, ab welcher Breite der Text in die neue Zeile übergehen soll. Nun könnte man ja einfach die Breite der gesamten Box nehmen. Dann würde der Text aber im schlimmsten Fall wieder aus der Box heraus laufen, weil in dieser Breite das Padding nicht enthalten ist. Der Text soll also umbrechen, wenn er die Breite der Box; minus das Padding links; minus das Padding rechts erreicht hat. Also width - (padding * 2).

Box / _initBox()

Anders als in der Webentwicklung, wo eine Box nicht mehr als ein div Element ist, dem wir mittels CSS Eigenschaften zuweisen, besteht die umgesetzte Textbox aus mehreren Grafiken/Elementen.

Das erste Element ist ein Rechteck, welches einfach nur als Hintergrundfarbe für unsere Box dient, auf der später der Text zu lesen ist. Dazu kommen insgesamt acht Sprites, die den Textbox-Rahmen formen. In der preload() Funktion habe ich diese Sprites als Spritesheet geladen. Das Spritesheet besteht aus neun 16×16 Sprites, wobei wir den Sprite in der Mitte auslassen. Man hätte ihn aber auch anstelle des Rechtecks als Hintergrund verwenden können.

Die äußeren vier Ecken sind vermutlich selbst erklärend. Die obere linke Ecke ist in der Koordinate 0x0 positioniert. Die rechte obere Ecke wird ans Ende der Box gesetzt. Dazu wird die Breite des Sprites, also 16px, von der Gesamtbreite der Box abgezogen. Also x = boxWidth - (tileSize * 2). Ähnlich ist es mit den beiden verbleibenden Ecken.

Nun zu den dynamischen Parts. Die horizontalen Zwischenräume müssen auf die gesamte Breite minus der beiden Ecken links und rechts gezogen werden. Die vertikalen Zwischenräume auf die gesamte Höhe minus der beiden Ecken oben und unten. Die Höhe haben wir ja im Konstruktor bereits anhand des Textes ermittelt.


And that’s it! Ich hoffe der Beitrag und die Code Ausschnitte haben dir weitergeholfen. Lass es mich gerne hier oder auf Twitter @NickHatBoecker wissen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert