28.052014

Internationalisierung von Flash-Anwendungen

Das nächste "Hacky Bird" ist geschrieben und jetzt soll alle Welt der Sucht deines neuen Flashgames unterliegen! Währe es nicht genial, wenn es neben der Englischen Fassung des Startmenüs auch noch eine Deutsche, eine Französische oder gar eine Finnische gäbe?

Heute stellen wir einige nette Funktionen vor, die es erlauben Texte in Flash-Anwendungen, die in Actionscript 3 geschrieben sind, zu internationalisieren. Wer mit Adobe Flash arbeitet kennt sicherlich die Klasse Locale im Packet fl.lang, die wir uns heute anschauen.

Beim Laden der Anwendung lesen wir die Sprachressourcen aus einer XML-Datei. Diese wird von Adobe Flash beim Veröffentlichen der Anwendung selbständig erzeugt und enthält neben einigen Metainformationen alle Text-IDs und deren Übersetzungen. Wen es interessiert, die Datei folgt dem XLIFF-Format ( siehe Wikepedia ). Wie laden wir nun eine solche Datei? Zunächst einmal muss diese Datei aus Flash heraus lesbar sein. Entweder ihr legt sie mit dem Flashobjekt auf einen Webserver oder aber ihr embedded die Datei direkt in Flash. Danach braucht ihr den Pfad und den Sprachcode (beispielsweise "de"). Ladet im Konstruktor eures Haupscriptes ein- oder mehrere Sprachressourcen:

import fl.lang.Locale;
// Im Konstruktor
function MyGame() {
  [...]
  Locale.addXMLPath(lang, path);
  Locale.loadLanguageXML(lang, onLocaleLoad);
  [..]
}

Im CallbackHandler onLocaleLoad kümmern wir uns um alles weitere:

private function onLocaleLoad(success:Boolean):void {
  if (success) {
    // Sicherstellen, dass die Funktion nicht mehrfach aufgerufen wird!
    Locale.setLoadCallback(null);

    // Hier können wir nun alle globalen Texte setzen!
    [...]
  }
}

Nun müssen wir natürlich zusehen, dass unsere Texte auch über die Locale-Klasse geladen werden. Hierzu bietet es sich an, das Laden durch eine kurze Wrapper-Funktion zu schleifen, damit nichts passiert, sollten wir keinen Eintrag finden:

public class SafeLocale {
  public static function loadString(id:String):String {
    var ret:Object = Locale.loadString(id);
    if(ret == null) {
      return id;
    } else {
      return String(ret);
  }
}

Im Code würde man dann schreiben:

var text:String = SafeLocale.loadString("ID_MY_FIRST_STRING");

Um eine Übersetzung in einer anderen Sprache zu laden könnt ihr entweder anstelle von Locale.loadString einfach Locale.loadStringEx mit dem Sprachcode nutzend oder ihr ändert die Standardsprache:

Locale.setDefaultLang("de");

Zu beachten sind nun Platzhalter im lokalisierten String etwa "Du hast einen Punktestand von X Punkten erreicht.". Wenn ihr nicht auf zusätzliche Klassen zum String-Formatieren zurückgreifen wollt setzt einfach einen Platzhalter ein und ersetzt diesen mittels String.replace:

// Textfragment "Du hast einen Punktestand von ##SCORE## Punkten erreicht."
SafeLocale.loadString("ID_SCORE_ACHIEVED").replace("##SCORE##", score);

Besonders flexible könnt ihr eure Sprachressourcen gestalten, indem ihr sie von einem PHP-Script auf dem Server erzeugen lasst. Für Flash ist dann die Quelle vollständig transparent, ob nun CSV-Datei auf dem Webserver, Datenbankeinträge oder aber ganz exotisch. Der Phantasie sind hier keine Grenzen gesetzt.

So bleibt mir nur noch euch viel Erfolg bei eurem nächsten multilingualem Minigame zu wünschen