workshop07

Top  Zurück  Weiter

Workshop 07: Strings, Texte und Fonts

Wir haben gelernt, wie wir man Panels, Ziffern und jede Menge schicke Panel-Elemente darstellt. Wenn wir nun einen Text anzeigen müssen (z. B. den Spielernamen, eine Nachricht usw.), brauchen wir sogenannte "String"s und "Text"e. Wollen wir außerdem, dass unsere Texte aus der Masse herausragen, müssen wir auch gut aussehende "Font"s benutzen. In dieser Lektion werden wir außerdem lernen, wie Panels, Texte oder sonstwas dynamisch während der Laufzeit verändern können.

Strings

Ein String ist eine Abfolge von Schriftzeichen: Buchstaben, Zahlen, Symbolen. Hier ein paar Beispiele für Strings:

STRING* player_str = "Johnny Bravo";
STRING* my_very_own_string = "Ich bin noch viel cooler, als der Coolste!"
STRING* player_meets_monster = "Stirb jetzt! Später hab' ich dafür keine Zeit!";
STRING* crypto1234 = "a#45@123--//";
STRING* test_string = ""; // leerer String
STRING* riddle = "#100"; // String der bis zu 100 Leerzeichen bereithält

Allein indem wir uns die obigen Definitionen anschauen, können wir ein paar Dinge lernen:

1. Jeder String muss mit dem Schlüsselwort STRING* definiert werden und zwar bevor er verwendet wird.

2. Der Inhalt (so es einen gibt) des Strings muss zwischen Anführungszeichen "" stehen.

3. In seiner Definition können wir dem String eine Folge von Schriftzeichen zuweisen oder einen leeren String, der später erst mit Zeichen gefüllt wird, erstellen.

4. Ein String hat eine bestimmte Länge. STRING riddle = "#100"; generiert einen String namens "riddle" der bis zu 100 Schriftzeichen beinhalten kann.

5. Jede lite-C-Zeile endet mit einem Semikolon; vergessen Sie also nicht, auch Ihre String-Definitionen jeweils mit einem Semikolon zu beenden.

6. Auch hier gelten dieselben Namenskonventionen wie bei den Variablen. Ich füge meinen String-Namen gerne noch ein _str hinzu aber das ist natürlich kein Muss.

Die Strings selbst können auf dem Bildschirm leider gar nichts anzeigen. Dazu müssen sie erst in einer TEXT-Definition gesetzt werden.

Texte

Ein "Text" ist ein Objekt, das einen oder mehrere Strings auf dem Bildschirm anzeigen kann. Hier eine einfache Text-Definition:

TEXT* first_txt =
{
    pos_x = 300;
    pos_y = 250;
    layer = 3;

    font = some_font; // vorher definierter Font
    string (my_string);
    flags = SHOW;
}

Sieht aus wie ein Panel, nicht? Die gute Nachricht ist die, dass seine Definition wirklich einfach ist:
- pos_x und pos_y bestimmen den Abstand (in Pixeln) zur oberen, linken Bildschirmecke.
- layer bestimmt welche Elemente auf dem Bildschirm vom Text verdeckt werden;
- font gibt den Namen des vorher definierten FONTs, der für den Text benutzt wird. Wird dies weggelassen, wird unser _a4font verwendet.
- string definiert den Namen des Strings, der angezeigt werden soll. Wie bei den Digits oder Buttons eines Panels kann ein Text beliebig viele Strings enthalten. Und genauso wie bei BMAPs und PANELs können Sie entweder den Namen eines vorher definierten Strings angeben oder Sie geben in Anführungszeichen direkt einen Sting ein.
- flags = SHOW macht den Text sichtbar.

Das ist wahrlich einfach! Ich kann es kaum erwarten, einen Text auf dem Bildschirm zu sehen!

Öffnen Sie script07 - der Teil, auf den es ankommt, sollte dann so aussehen:

////////////////////////////////////////////////////////////////////
#include 
#include 

////////////////////////////////////////////////////////////////////

STRING* aloha_str = "Welcome to Paradise Island!";

TEXT* greetings_txt =
{
	pos_x = 300;
	pos_y = 250;
	string (aloha_str);
	flags = SHOW;
}

////////////////////////////////////////////////////////////////////

function main()
{
  screen_size.x = 800;
screen_size.y = 600;
screen_color.blue = 150; }

Sie sehen, wir haben einen String namens aloha_str definiert.

STRING* aloha_str = "Welcome to Paradise Island!"; // Willkommen auf der Paradies-Insel!

Denken Sie dran, Sie können auch alles andere (Schriftzeichen, Zahlen, Symbole) zwischen die beiden Anführungszeichen setzen. Unsere Textdefinition ist wirklich einfach. Starten wir unsere Skript-Datei!

w07_02

Dynamisches Verändern von Objekten

Bereit, etwas Neues zu lernen? Fügen der Main-Funktion ein paar Zeilen hinzu, so dass Ihre Skript-Datei nun so aussieht (grün = geänderte Codezeilen):


STRING* aloha_str = "Welcome to Paradise Island!";

TEXT* greetings_txt =
{
	pos_x = 300;
	pos_y = 250;
	string (aloha_str);
	flags = SHOW;
}

////////////////////////////////////////////////////////////////////

function main()
{
  screen_size.x = 800;
screen_size.y = 600;
screen_color.blue = 150; wait (-3); greetings_txt.pos_x = 500; wait (-3); greetomgs_txt.flags = 0; }

Starten Sie die Datei script07.c noch einmal und Sie sehen, der Text hat sich zur rechten Seite des Bildschirms bewegt, dort bleibt er für ein paar Sekunden und dann verschwindet er. Der Code, der all das bewerkstelligt befindet sich, Sie haben es geahnt, innerhalb der Funktion main. Besprechen wir den also gleich einmal

wait (-3);
greetings_txt.pos_x = 500;

wait (-3);
greetings_txt.flags = 0;

Zuallererst: wait(-3); ist eine vordefinierte Engine-Funktion, die das Programm instruiert, 3 Sekunden zu warten.

Aufgepasst, denn jetzt kommt der vielleicht wichtigste Satz, den ich bisher geschrieben habe: Mit der 'Punkt-Methode' können wir auf (fast) jede Eigenschaft / jedes Feature eines Objekts zugreifen; und das sieht so aus:

object.property

In unserem Beispiel ist die erste Codezeile, in der die Punkt-Methode benutzt wird, diese:

greetings_txt.pos_x = 500;

Unser Textobjekt hat eine Eigenschaft namens pos_x, welche seine Position auf der X-Achse festsetzt. Diese Zeile setzt einfach nur einen neuen pos_x-Wert für den Text und positioniert ihn 500 Pixel vom linken Bildschirmrand entfernt. Sie finden alles über vordefinierte Objekte und ihre Eigenschaften im Referenzhandbuch. Werfen wir jetzt einen Blick auf die letzte Codezeile:

greetings_txt.flags = 0;

Diese Zeile setzt eine andere, vordefinierte Eigenschaft namens "flags" auf Null. Dadurch werden sämtliche Flags unseres Textes zurückgesetzt inklusive des Flags SHOW (der einzige, den wir gesetzt haben). Somit verschwindet unser Text vom Bildschirm. Fragen Sie sich nun, welche anderen Eigenschaften unseres Textes sich noch per Punkt-Methode verändern lassen? Die Antwort ist einfach: fast alles. Wir können für unseren Text einen neuen String setzen, seine x- und y-Position verändern, wir können ihn sichtbar oder unsichtbar machen.... jede Menge Zeugs!

Ein so guter Schüler wie Sie sollte wissen, wie man ein Panel mit zwei Knöpfen erstellt, die zwei kleine Funktiönchen starten, welche pos_x und pos_y Ihres Texts "greetings_txt" verändern, gell? Warum unterbrechen Sie diesen Workshop nicht mal kurz und schreiben gleich jetzt dieses kleine Stückchen Code?

Wie? sie müssen nach Ihrer Katze schauen und sie würden Ihre ganze Energie verlieren, schrieben Sie das Programm? Na gut, machen wir eben mit dem Workshop weiter...

Die Punkt-Methode läßt sich zum Steuern von Panels, Texten, Entities (nur Geduld, dahin kommen wir auch noch).....verwenden. Okay, ich gebe Ihnen ein noch paar Beispiele:

  display_pan.flags = 0; // setzt alle Flags im Panel namens "display_pan" zurück  
  test_pan.flags |= SHOW; // zeigt das Panel namens "test_pan"
  (hi_txt.pstring)[0] = newstring_str; // gespenstisch, werden wir später aber enträtselnsetzt für "hi_txt" einen neuen String
  error_pan.pos_y = 300; // setzt einen neuen "pos_y"-Wert für das Panel namens "error_pan"
  wizard.z = 200; // setzt die Höhe für eine Entity namens “wizard” auf 200  

Vielleicht ist Ihnen aufgefallen, dass meine Text-Definition keine Code-Zeile für "font = some_font;" beinhaltet. Wenn Sie das vergessen, nimmt die Engine den internen Font und genau das ist auch hier geschehen. Bestimmt wollen Sie aber einen neuen Font verwenden! 

Fonts

Unter Font versteht man einen Satz von Schriftzeichen, die wir für unsere Texte verwenden können. Die Engine kann 2 Arten von Fonts verwenden:
- True Type-Fonts, wie sie auch von Windows benutzt werden.
- Bitmap-Fonts; einen Satz von Schriftzeichen, die aus einer Grafik-Datei gelesen werden.

True Type-Fonts

Auf Ihrem PC sind vermutlich viele True type-Fonts installiert. Öffnen Sie den Ordner namens \fonts in Ihrem Windows-Verzeichnis: dort müssten Sie sie sehen:

w07_07

Per Doppelklick auf einen solchen Font, sehen Sie seinen gesamten Satz an Schriftzeichen sowie einige Textbeispiele:

w07_08

Das ist Ihr üblicher True type-Font und wie Sie sehen, sind die Schriftzeichen nicht auf eine bestimmte Breite festgelegt: "i" ist sehr viel dünner als "m". Betrachten wir uns eine true type-Font-Definition:

FONT* my_font_name = "font_name_in_windows#height(type)"; // true type font

- my_font_name ist der Name, den Sie für den Font (z.B. 'arial_font') ausgesucht haben.
- font_name_in_windows ist der Name unter dem der Font im '\fonts-Ordner von Windows erscheint. Sie können hier 'Arial', 'Times' (Times New Roman) und 'Courier' nehmen, denn diese Fonts sind garantiert auf jedem PC mit Windows vorhanden.
- height bezeichnet die Höhe der Schriftzeichen in Punkten auch das genauso wie in Ihrem Textverarbeitungsprogramm.

- type kann weggelassen werde (normal), b (fett), i (kursiv) oder bi (fett + kursiv) sein.

Und jetzt betrachten wir das Beispiel für einen True type-Font:

FONT* arial_font = "Arial#20b"; // Arial, fett, ein Schriftzeichen hat eine Höhe von 20 Punkten

Bitmap-Fonts

Wenn Sie sich dafür entscheiden, einen Bitmap-Font zu nehmen, sind "i" und "m" gleich breit, Ihr Text wird also so ähnlich aussehen:

 

Diese roten Kästchen tauchen auf Ihrem Bildschirm nicht auf, die habe ich gezeichnet, damit Sie sehen, dass alle Schriftzeichen tatsächlich gleich breit sind. Und so sieht derselbe Text ohne rote Kästchen aus:

 

Betrachten wir die Definition für einen Bitmap-Font:

FONT* my_font_name = "bitmap_name"; // fixed width font

- my_font_name ist der Name, den Sie für den Font (z.B. 'adventure_font') ausgesucht haben.
- bitmap_name heißt die Bitmap, die den Font enthält, mit entweder 11 Ziffern oder 32x4 oder 32x8 Zeichen.

Betrachten wir das Beispiel eines Bitmap-Fonts:

FONT adventure_font = "adventure.pcx"; // benutzt eine Bitmap namens adventure.pcx

Sieht alles ganz gut aus, aber wie muss die Bitmap beschaffen sein? Nun, wenn Sie einen eigenen Bitmap-Font verwenden wollen, müssen Sie sämtliche Schriftzeichen eigenhändig erstellen. Hierzu generieren Sie ein schwarzes (R,G, B = 0, 0, 0) Rechteck und malen Ihre Zeichen da hinein. Die Abfolge der alphanumerischen Zeichen Ihrer Bitmap muss dem vom Skript verwendeten Zeichensatz entsprechen. Hier ein Beispiel (die grünen Rechtecke oben können Sie entweder ignorieren oder Sie fügen Ihrem Font noch andere Schriftzeichen hinzu):

w07_11

Die Schriftzeichen sollten in 32 Zeichen pro Reihe in vier Reihen (in meinem Beispiel 32 Zeichen x 4 Reihen = 128 Zeichen) oder in acht Reihen (256 Zeichen) angeordnet sein. Wenn Sie keine Buchstaben brauchen, können Sie auch eine kleinere Font-Bitmap (11 Zeichen x 1 Reihe: 0...9 und Leerzeichen) erstellen:

Wichtiger Hinweis: Die Bitmap muss exakt 11 mal, (11 x 1), 128 mal (32 x 4) oder 256 mal (32 x 8) so so gros's sein wie das einzelne Schriftzeichen. Falls Sie diese Regel missachten, werden Sie keinen brauchbaren Font zustande bringen.

Die Bitmaps für solche Fonts fester Breite sind zugegebenermaßen ziemlich schwierig zu gestalten. Bevor Sie jetzt anfangen, sich die Haare auszureissen: Auf Conitec's "Links"-Seite finden Sie ein Werkzeug namens "font generator". Mit dessen Hilfe wählen Sie den Namen eines Fonts, bestimmen seine Größe und drücken einen Knopf und die Bitmap wird automatisch generiert.

Betrachten wir einmal Für und Wider dieser beiden Font-Typen:
Font Erstellen Pro Kontra Sonstiges
True Type Nicht nötig Variable Breite Einfarbig Lediglich ein paar True-Type-Fonts (Arial, Times, Courier)
sind auf allen PCs dieser Welt installiert.
Bitmap Zeitaufwändig Vielfarbig Festgelegte Breite Kann zum Darstellen aller Arten von Symbolen (z. B. Ausserirdischen-Alphabet) verwendet werden.

Stellt sich also die Frage, welchen Font-Typus Sie verwenden wollen. Mit einem True type-Font sehen die Texte wirklich gut aus, allerdings können Sie es sich nicht leisten, einen Font zu nehmen, der nicht auf allen PCs vorhanden ist. Ein Bitmap-Font kann auf jedem PC dargestellt werden, denn Sie liefern die Bitmap mit Ihrem Spiel mit.

Schauen wir uns einmal an, wie diese Fonts aussehen und dann sollten Sie in der Lage sein, den für Ihre Projekte passende Font-Art zu wählen. Ich rate Ihnen, wenn's gebraucht wird, ruhig auch beide Typen in ein und demselben Projekt zu benutzen.

Starten Sie LIte-C und laden Sie die Datei script07_2

////////////////////////////////////////////////////////////////////
#include 
#include 

////////////////////////////////////////////////////////////////////

STRING* test_str = "I like to write programs!";

FONT* system_font = "system.pcx"; // auf 10 x 12 Pixel pro Zeichen festgelegt
FONT* arial_font = "Arial#25b"; // True Type, Arial, Größe = 25, fett
TEXT* fixed_width_txt =
{
	pos_x = 200;
	pos_y = 250;
	font = system_font;
	string(test_str);
	flags = SHOW;
}

TEXT* true_type_txt =
{
	pos_x = 200;
	pos_y = 280;
	font = arial_font;
	string(test_str);
	flags = SHOW;
}

////////////////////////////////////////////////////////////////////
Dieses Skript beinhaltet zwei Font-Definitionen und zwei Texte, die verschiedene Fonts und denselben test_str-String verwenden. Starten wir das Skript script7_2:

Wenn Sie nun wissen wollen, wie diese Bitmap namens system.pcx aussieht, finden Sie sie im Ordner \workshop07 (wo auch sonst?) und können Sie dort öffnen. Oder Sie werfen einen Blick auf die folgende Abbildung:

 

system.pcx= die für den Bitmap-Font benutzte Bitmap
 
Wie ich bereits erwähnt habe, ist es der Engine egal, ob Sie nun Zahlen und Buchstaben in einen Font malen oder ob Sie "text"e und "digit"s zur Darstellung von Bildchen, abgehobenen Symbole etc. verwenden. Hier ein Beispiel aus einem von Alain Brégeons Multiplayer-Workshops, die man von der AU Resource-Webseite herunterladen kann:

Hieße der Font icons.bmp, sähe seine Definition folgendermaßen aus:

FONT* icons_font = "icons.bmp";

Definieren wir ein Panel für diesen Font und ein "Digit":

PANEL some_pan

{
   pos_x = 0;
   pos_y = 0;
   digits (410, 200, 1, icons_font, 1, picture);
   flags = OVERLAY | SHOW;
}

Wenn die Variable namens picture = 2 ist, gibt das "digit" eine weiße Rakete aus, ist picture = 3, sehen wir ein kleines rotes Herz, bei picture = 4 wird eine rote Rakete angezeigt usw. haben Sie's? Anstatt solcher Bildchen können Sie natürlich irgendwelche anderen Symbole nehmen und so z. B. ein Außerirdischen-Alphabet oder was in der Art erstellen.

Bereit für die nächste Herausforderung? Versuchen Sie den Code zu schreiben, der , wie unten zu sehen, drei Sekunden nach Laden des Levels die Fonts der beiden Texte vertauscht:

w07_16
drei Sekunden später...
w07_17

Lösung: fügen Sie in die main-Funktion 3 Code-Zeilen ein:

function main()
{
    ...
     wait(-3); // wait for 3 seconds
     fixed_width_txt.font = arial_font; // switch the fonts
     true_type_txt.font = system_font; // for the 2 texts
}

Weiter: Position, Winkel und Maßstab


Mehr zum Thema: Gamestudio Handbuch ► STRING, TEXT, FONT