Anzeige
Tutorialbeschreibung

Textzwirbler in Actionscript

Textzwirbler in Actionscript

Version: ab Flash MX
Niveau: Einsteiger bis Fortgeschrittene
Vorkenntnisse: Flash (Symbole, Zeitleisten), Grundlagen Actionscript (Arrays, Schleifen, Math.random)
Lernziele: aus Strings einzelne Wörter sowie Zeichen extrahieren lernen.

Vor einiger Zeit geisterte durch das Internet die Meldung über sensationelle Ergebnisse einer englischen Studie. Derzufolge können Menschen auch dann noch die meisten Wörter richtig lesen, wenn sich ihre Buchstaben mit Ausnahme des ersten und des letzen Buchstabens an einer falschen Position befinden. Wir wollen daher im Dienste der Wissenschaft mit Hilfe von Flash herausfinden, ob das tatsächlich möglich ist.

Leider fehlt in Flash eine Methode zwirbeln, die einfach die Buchstaben durcheinander wirbeln würde. Da müssen wir also selbst Hand anlegen.

Wir wollen ein Eingabetextfeld für den vom User einzugebenden Text, ein Ausgabetextfeld mit dem verzwirbelten Text und einen Button für die Ausführung der Textveränderung anlegen.

  1. Erstellen Sie einen neuen Flashfilm (beliebige Größe, beliebige Hintergrundfarbe, 18 Bps).
  2. Fügen Sie der Zeitleiste der Szene 1 zwei neue Ebenen namens „txt“ sowie „btn“ hinzu.
  3. Benennen Sie die „Ebene 1“ in „actions“ um und verschieben sie in der Ebenenreihenfolge ganz nach oben.
  4. Erstellen Sie auf der Ebene „txt“ ein Eingabetextfeld (Verdana, 12 pt, schwarz, bold, mehrzeilig, Rahmen um Text, Instanzname „input“).
  5. Positionieren Sie es mittig am oberen Bühnenrand.
  6. Erstellen Sie auf derselben Ebene ein dynamisches Textfeld (Verdana, 12 pt, schwarz, bold, mehrzeilig, Rahmen um Text, Instanzname „output“) in derselben Größe wie das Eingabetextfeld. Achtung: ändern Sie die Größe in Pixel weder über das Eigenschaftsfenster noch mit Hilfe des Skalierenwerkzeugs. Das führt nämlich dazu, daß das Textfeld und damit der später angezeigte Text skaliert werden. Die gleiche Größe erhalten Sie einfach, indem Sie das Eingabetextfeld duplizieren (<alt> und gleichzeitig ziehen oder <strg><c> und <strg><v>). Anschließend ändern Sie es über das Eigenschaftsfenster entsprechend der oben gemachten Angaben.
  7. Positionieren Sie das dynamische Textfeld unterhalb des Eingabetextfeldes. Halten Sie dabei mindestens 40 Pixel Abstand ein, um zwischen beiden einen Button einfügen zu können.
  8. Erstellen Sie auf der Ebene „btn“ einen MovieClip (75x30, drei Ebenen für blaue Füllung, schwarzer Rahmen und statischer Text, 12 pt, Verdana) mit drei verschiedenen Zuständen, den wir als Button einsetzen wollen. Wie das im Einzelnen funktioniert, können Sie im Workshop „MovieClip als Button verwenden“ nachlesen (shameless self-promotion würde da der Engländer sagen). Die Buttonbeschriftung lautet „Zwirbeln“ (ohne Anführungszeichen).
  9. Weisen Sie dem MovieClip den Instanznamen „b_zwirbeln“ zu und positionieren ihn mittig zwischen den beiden Textfeldern.

Die Bühne der Szene 1 müßte jetzt so aussehen:

Bilder
 

  1. Damit unser zum Button umfunktionierter MovieClip nicht dauernd alle drei Zustände (Normal, Rollover, Mausklick) anzeigt, stoppen Sie die Animation durch einen Befehl in einem Skript, das Sie dem ersten frame der Ebene „actions“ zuweisen:

b_zwirbeln.stop();

  1. Darunter schreiben Sie:

b_zwirbeln.onPress = function() {
          ergebnis = zwirbeln(input.text);
          output.text = ergebnis;
};

Damit wird bei Mausklick auf den Button b_zwirbeln in die Variable ergebnis das Ergebnis der Ausführung einer noch nicht definierten Funktion namens zwirbeln geschrieben. Vom Ablauf her führt Flash an dieser Stelle alles aus, was wir in der Funktion zwirbeln festlegen wollen. Dabei übergeben wir als Parameter den Inhalt des textfeldes input. Das Ergebnis der dortigen Berechnung wird dann mit einem besonderen Befehl, nämlich der return-Anweisung, von der Funktion direkt in die Variable ergebnis hineingeschrieben. Die return-Anweisung wird dabei von uns an die letzte Stelle innerhalb der Funktion zwirbeln geschrieben. Abschließend weisen wir dem dynamischen Textfeld die Variable ergebnis zu. Wir hätten natürlich auch kürzer output.text = zwirbeln(input.text) schreiben können, aber üblicher ist die Verwendung einer Variablen gewissermaßen als Zwischenspeicher für die Berechnung durch unsere zwirbeln-Funktion.

Wenn Sie jetzt schon testen, werden Sie enttäuscht feststellen, daß sich nichts tut – kein Wunder, denn es fehlt ja noch die Funktionsdefinition.

  1. Schreiben Sie daher nach dem bisherigen Skript:

function zwirbeln(was){
          return was ;
}

Testen Sie, indem Sie in das Eingabetextfeld ein Wort eingeben (z.B. „Textzwirbler“, natürlich ohne Anführungszeichen) und auf den Button klicken.

Immerhin: das eingegebene Wort wird jetzt unverändert im Ausgabetextfeld angezeigt.

Beim Klick auf den Button wird die Funktion zwirbeln aufgerufen. Sie erhält den Parameter „Textzwirbler“. Der wird mit return an das aufrufende Skript, d.h. den Mausklick des Buttons, zurückgegeben. Da dort die Funktion zwirbeln der Variablen ergebnis zugewiesen wurde, steht in ergebnis „Textzwirbler“. Abschließend schreibt Flash den Inhalt von ergebnis in das Textfeld output und wir lesen auch dort „Textzwirbler“.

Von zwirbeln allerdings kann noch nicht die Rede sein. Dazu müssen wir uns zunächst den ersten und den letzten Buchstaben des übergebenen Wortes merken und alles dazwischen kräftig durchschütteln.

  1. Fügen Sie in der Funktion zwirbeln unmittelbar vor return folgende Zeilen ein:

gleich = [was.charAt(0), was.charAt(was.length-1)];
trace(gleich);

Beim erneuten Testen mit „Textzwirbler“ erscheinen im Nachrichtenfenster die Buchstaben t,r.

Das neu eingerichtete Array gleich speichert aus dem Begriff, den wir beim Funktionsaufruf übergeben, mit charAt(0) den Buchstaben an der ersten Position und mit charAt(was.length-1) den Buchstaben an der letzten Position. Beachten Sie dabei, daß charAt auf den Index zugreift, dieser aber beim ersten Zeichen wie bei einem Array mit 0 beginnt und daher das letzte Zeichen der Gesamtlänge minus 1 entspricht. Immer dann, wenn wir später das erste und letzte Zeichen benötigen, können wir also das Array gleich verwenden. Der Trace-Befehl dient uns nur zur Kontrolle, ob die ermittelten Buchstaben auch korrekt sind.

Das zwirbeln selbst gestaltet sich etwas komplizierter (es gibt andere Varianten, z.B. mit einer direkten Bearbeitung des Satzes als Array; wir wollen hier aber nur eine Möglichkeit vorstellen).

  1. Fügen Sie zwischen dem trace- und dem return-Befehl folgende Zeilen ein:

was = was.substring(1, was.length-1);
var gezwirbelt= "";
while (was.length>=1) {
          var i = Math.floor(Math.random()*was.length);
          gezwirbelt+= was.substring(i, i+1);
          was = was.substring(0, i)+ was.substring(i+1);
}
gezwirbelt= String(gleich[0])+ gezwirbelt+String(gleich[1]);
trace(gezwirbelt);

Wichtig: Achten Sie darauf, daß sich dieser Codeblock innerhalb der Funktion zwirbeln() befindet. Ansonsten erzeugen Sie eine Endlosschleife und das Skript kann nicht korrekt ausgeführt werden.

Beim Testen mit unserem Standardwort (man beachte: Standard, bitte googeln Sie mal nach „Standart“) enthält jetzt die Variable gezwirbelt, die im Nachrichtenfenster ausgegeben wird, wunderbar verwirbelte Buchstaben.

Anders als beispielsweise in Director ist es in Flash nicht möglich, direkt Buchstaben in einem String zu löschen. Daher extrahieren wir mit der String-Methode substring aus der Variablen was, die „Textzwirbler“ enthält, einfach alles zwischen dem ersten und dem letzten Buchstaben. Da wir substring auf was anwenden und gleichzeitig das Ergebnis in derselben Variable abspeichern, kürzen wir den Inhalt von was faktisch um den ersten und letzten Buchstaben. Substring benötigt als Parameter den Index des ersten Zeichens, das wir erhalten wollen, und den Index des ersten Zeichens, das wir nicht mehr erhalten wollen. Alles, was dazwischen liegt, wird als substring extrahiert.

In der Variablen gezwirbelt sollen zuerst die durcheinander gewirbelten Buchstaben gespeichert und anschließend der erste und letzte Buchstabe hinzu gefügt werden.

Die while-Schleife sorgt schließlich dafür, daß die Buchstaben vertauscht werden. Sie wird solange ausgeführt, wie die Länge des Strings in der Variablen was größer als 0 ist, also der String nicht vollständig gelöscht ist. In der lokalen Variablen i ermitteln wir eine Zufallszahl, die zwischen 0 und der Gesamtzahl der Stringlänge in was minus 1 liegt. Diese Zahl verwenden wir, um mit der substring-Methode ein zufälliges Zeichen aus dem String in die Variable gezwirbelt zu speichern (alternativ könnte man auch die Methode String.charAt(Index) verwenden). Gleichzeitig muss in was dasselbe Zeichen gelöscht werden, um es nicht versehentlich ein zweites Mal zu verwenden. Da substring wie ein Array mit Index arbeitet, muß die kleinste Zahl 0 sein, denn Index 0 entspricht in einem String dem ersten Zeichen. Das letzte Zeichen entspricht dann der Gesamtlänge des Strings minus 1. So befindet sich bei „extzwirble“ das letzte Zeichen auf Index 9, die Gesamtlänge des Strings beträgt dagegen 10 Zeichen.

Beim Zuweisen des Buchstabens zur Variablen gezwirbelt ist wichtig, daß wir eine Konkatenation (klingt toll!) mit Hilfe des Plus-Operators durchführen. Dadurch wird an den bereits existierenden Inhalt einfach der neue Inhalt angehängt. Würden wir lediglich eine Zuweisung (=) anstelle einer Konkatenation (+=) verwenden, dann würde der komplette Inhalt in der Variablen durch den neuen Inhalt überschrieben. Übrig bliebe in der Variablen am Schluß nur ein einziger Buchstabe.

Auch das Löschen des ermittelten Buchstabens geschieht mit Hilfe der substring-Methode. Allerdings ist der Vorgang etwas komplizierter. Da wir Flash nicht einfach anweisen können: „Lösche den Buchstaben an der Position X“, müssen wir erst den Substring vor und den nach dem ermittelten Buchstaben nehmen. Wenn wir beide Substrings wieder in die Variable was zurückschreiben, haben wir faktisch einen Buchstaben gelöscht.

Dieser gesamte Prozeß – Ermitteln einer Zufallszahl, Speichern des Buchstabens an der Position entsprechend der Zahl in gezwirbelt, Löschen des Buchstabens in was – findet solange statt, bis der gesamte String in was gelöscht ist. Dann haben wir alle Buchstaben in vertauschter Reihenfolge in einer anderen Variablen gespeichert.

Folgende drei Grafiken veranschaulichen den Prozeß an fiktiven Zufallszahlen:

Bilder
 

Bilder
 

Bilder

Abschließend muß nur noch der erste und der letzte urspünglich gespeicherte Buchstabe an das gezwirbelte Wort angehängt werden, und schon liegt der fertige Begrifff vor. Auch hier hilft eine Konkatenation, bestehend aus dem ersten Element im Array gleich (entspricht dem ersten Buchstaben), dem gezwirbelten String und dem letzten Element im Array gleich (entspricht dem letzten Buchstaben).

  1. Die Übergabe des Ergebnisses an das Textfeld ist simpel. Ersetzen Sie die Anweisung return was; durch:

return gezwirbelt;

Beim Testen erscheint nun das gezwirbelte Wort auch im Ausgabetextfeld unterhalb des Buttons.

Wenn Sie alles korrekt gemacht haben, funktioniert es primstens – aber nur solange, wie Sie einen einzelnen Begrifff eingeben. Sobald mehr als ein Wort oder Satzzeichen wie etwa ein Punkt eingegeben werden, sieht das Ergebnis bestenfalls suboptimal aus. Denn ohne Änderung des Programmcodes werden von Flash einfach alle Elemente des Strings, also auch die zur Trennung von Wörtern verwendeten Leerzeichen und Satzzeichen, als Buchstaben gewertet, die ein einziges Wort bilden.

Daher müssen wir dafür sorgen, daß Flash die einzelnen Wörter aus dem String extrahiert und darüber hinaus die Satzzeichen unverändert übernimmt. Wie beim Löschen von Buchstaben haben wir auch beim Ermitteln ganzer Wörter keine fertige Methode, mit der wir diese Aufgabe einfach erledigen könnten. Eine mögliche Lösung besteht darin, aus dem Text ein Array zu erstellen, in dem die Wörter als einzelne Elemente gespeichert sind.

  1. Ersetzen Sie im onPress-Ereignis die Zeile ergebnis = zwirbeln(input.text); durch die fettgedruckten Zeilen:

b_zwirbeln.onPress = function() {
          ergebnis = "";
          aText = (input.text).split(" ");
          for (var i = 0; i<aText.length; i++) {
                    if (i<aText.length-1) {
                              ergebnis += zwirbeln(aText[i])+" ";
                    } else {
                              ergebnis += zwirbeln(aText[i]);
                    }
          }
          output.text = ergebnis;
};

Testen Sie, indem Sie mehrere Wörter hintereinander (ohne Leerzeichen) eingeben, z.B. „Gleich ist unser wunderbarer Textzwirbler vollendet“. Im Ausgabetextfeld erscheint dann jedes Wort, das mindestens 4 Zeichen lang ist, gezwirbelt.

Da wir im Ausgabefeld eine Zeichenfolge ausgeben müssen, die aus mehreren Wörtern besteht, benötigen wir eine Variable zum Zusammensetzen dieses Textes. Dazu richten wir ergebnis ein, initialisiert als leerer String („“). Die einzelnen Wörter des Satzes im Eingabetextfeld speichern wir als Elemente eines Strings über die Methode split() ab. Damit Flash erkennt, welches Zeichen die Wörter voneinander trennt, übergeben wir als Parameter in den Klammern einfach ein Leerzeichen. Mit split() kann jeder beliebige String in einem Array gespeichert werden, wobei auch jedes beliebige Zeichen als Trennzeichen verwendbar ist. Wenn wir also nach jedem Wort eine Raute verwenden (z.B.: „Gleich#ist#unser#wunderbarer#Textzwirbler#vollendet“) und die Split-Methode mit der Raute als Parameter („#“) aufrufen würden, dann könnte Flash ebenfalls jedes Wort als einzelnes Element in einem Array abspeichern – lediglich der Satz wäre etwas schwerer lesbar.

Was wir anfangs mit einem einzelnen Wort gemacht haben, muß nun mit jedem Wort des eingegebenen Satzes durchgeführt werden. Da die Wörter im Array aText als einzelnes Element gespeichert sind, gehen wir aText mit einer Schleife durch und rufen jedesmal die zwirbeln-Funktion auf. Als Parameter wird ihr das über die Zählvariable i ermittelte aktuelle Element übergeben. Die Funktion selbst kann zunächst unverändert übernommen werden. Die if-Abfrage innerhalb der Schleife sorgt dafür, daß die gezwirbelten Worte hintereinander in ergebnis geschrieben und um ein Leerzeichen ergänzt werden. Lediglich wenn wir auf das letzte Element des Arrays zugreifen – hier der else-Fall – verzichten wir auf das Hinzufügen eines Leerzeichens.

Das funktioniert alles solange wunderbar, bis Sie ein Satzzeichen verwenden. Also müssen wir noch dafür sorgen, daß Flash die Satzzeichen nicht als Teil eines Wortes interpretiert.

  1. Fügen Sie nach b_zwirbeln.stop(); folgende Zeile ein:

aZeichen = [";", ",", ":", ".", "?", "!"];

Damit teilen wir Flash mit, welche Zeichen als Satzzeichen gelten. Natürlich können Sie das Array aZeichen beliebig erweitern.

Die Suche nach den Satzzeichen kann sowohl innerhalb des onPress-Ereignisses wie innerhalb der zwirbeln-Funktion erfolgen. Wir entscheiden uns für letzteres.

  1. Ändern Sie die zwirbeln-Funktion wie folgt (Fettdruck):

function zwirbeln(was) {
          var gleich = "";
          f or (e in aZeichen) {
                    if (was.charAt(was.length-1) == aZeichen[e]) {
                              gleich = [was.substring(0, 1), was.substring(was.length-2)];
                              was = was.substring(1, was.length-2);
                              break;
                    }
          }
          if (gleich == "") {
                    gleich = [was.charAt(0), was.charAt(was.length-1)];
                    was = was.substring(1, was.length-1);
          }
          var gezwirbelt = "";
          while (was.length>=1) {
                    var i = Math.floor(Math.random()*was.length);
                    gezwirbelt += was.substring(i, i+1);
                    was = was.substring(0, i)+ was.substring(i+1);
          }
          gezwirbelt = String(gleich[0])+gezwirbelt+String(gleich[1]);
          return gezwirbelt;
}

Testen Sie ausführlich mit einem und auch mit mehreren Sätzen. Wenn Ihre Begeisterung nach einigen Stunden abgeklungen ist, lseen Sie die foegnlde Ekärunrlg druch.

Da bei unserer Verwendung von split() die Satzzeichen als Teil eines Wortes erfasst werden, ist es nicht mehr möglich, in der Variablen gleich einfach das letzte Zeichen des übergebenen Begrifffs zu speichern. Stattdessen initialisieren wir sie als leeren String und unterscheiden anschließend zwei Fälle (auch hier sind mehrere Vorgehensweisen möglich, wir entscheiden uns aber einfach für die vorliegende):

- der übergebene Begriff enthält ein Leerzeichen. Das können wir herausfinden, indem wir mit einer for in-Schleife nachschauen, ob das letzte Zeichen des Parameters identisch mit einem der in aZeichen enthaltenen Elemente ist. Zur Erinnerung: in aZeichen hatten wir all jene Elemente aufgenommen, die wir als Satzzeichen verwenden. Wenn also diese Bedingung wahr ist, speichern wir in gleich das erste Zeichen und die beiden letzten Zeichen, also den letzten Buchstaben und das Satzzeichen. In was wird alles zwischen dem ersten und dem vorletzten Zeichen gespeichert. Anschließend brechen wir die Schleife ab, da wir ja bereits ein Satzzeichen gefunden haben.

- der Begriff enthält kein Satzzeichen. Das ist dann der Fall, wenn die Variable gleich unverändert einen leeren String enthält. Dann können wir so vorgehen wie sonst auch, nämlich einfach das erste und letzte Zeichen speichern und was um diese beiden Zeichen verkürzen.

Wenn Sie beim Testen möglichst „normale“ Sätze wählen, werden Sie feststellen, daß sie durchaus lesbar bleiben. Und es funktioniert auch, solange Sie – entgegen meiner Gepflogenheit – keinen Spiegelstrich verwenden (einmal davon abgesehen, daß mein Spiegelstrich nicht den Regeln des Dudens entspricht – sorry!). Wenn Sie aber auf längere Zitate aus der Merian-Bibel in der letzen Luther-Übersetzung oder Kants Kritik der Reinen Vernunft zurückgreifen, dürfte Ihr Lesefluß nach dem Zwirbeln merklich ins Stocken geraten.

Der Grund ist einfach: Texte, die aus unserer unmittelbaren Lebenserfahrung stammen, werden von uns beim Lesen automatisch ergänzt. Wir lesen nicht Buchstabe für Buchstabe, sondern erfassen gleich ganze Wörter oder Wortcluster. Sind einzelne Buchstaben falsch angeordnet, können wir aus den angrenzenden Wörtern trotzdem auf den korrekten Sinn schließen. Und unser Zufallsalgorithmus führt dazu, daß eben nur einzelne Buchstaben, nicht aber komplett alles Buchstaben falsch positioniert werden. Außerdem bleiben alle Wörter mit drei Buchstaben unverändert, bei denjenigen mit 4 Buchstaben besteht immerhin noch eine Chance von 50%, daß auch sie unverändert übernommen werden.

Da weder Kant noch Luther zu unserem täglichen Lesebrot gehören, fällt es uns hier erheblich schwerer, aus dem Kontext selbst dann auf den richtigen Satz zu schließen, wenn einige Worte nicht verändert wurden. Damit bleibt leider von dem behaupteten Lesephänomen nicht mehr viel übrig – und noch viel schader ist die Tatsache, daß es sich bei der eingangs erwähnten Studie offenbar um einen jener ganzjährigen Aprilscherze handelte, um die uns das Internet so oft bereichert: http://www.heise.de/tp/r4/artikel/15/15701/1.html.

Wer trotzdem Spaß am Zwirbeln hat, sollte sich mal die anderen Programme anschauen, die in Javascript und weiß nicht was noch alles munter Buchstaben schütteln. Links findet man genügend, wenn man „textzwirbler“ googelt. Und vielleicht, wenn den politischen Parteien eines Tages die Worte ausgehen, nehmen sie sich einen Zwirbler zur Hand, schicken ihr Parteiprogramm hindurch und haben flugs ein neues für die nächste Wahl!

Der gesamte Code sieht so aus:

b_zwirbeln.stop();
aZeichen = [";", ",", ":", ".", "?", "!"];
b_zwirbeln.onPress = function() {
          ergebnis = "";
          aText = (input.text).split(" ");
          for (var i = 0; i<aText.length; i++) {
                    if (i<aText.length-1) {
                              ergebnis += zwirbeln(aText[i])+" ";
                    } else {
                              ergebnis += zwirbeln(aText[i]);
                    }
          }
          output.text = ergebnis;
};
function zwirbeln(was) {
          var gleich = "";
          for (e in aZeichen) {
                    if (was.charAt(was.length-1) == aZeichen[e]) {
                              gleich = [was.substring(0, 1), was.substring(was.length-2)];
                              was = was.substring(1, was.length-2);
                              break;
                    }
          }
          if (gleich == "") {
                    gleich = [was.charAt(0), was.charAt(was.length-1)];
                    was = was.substring(1, was.length-1);
          }
          var gezwirbelt = "";
          while (was.length>=1) {
                    var i = Math.floor(Math.random()*was.length);
                    gezwirbelt += was.substring(i, i+1);
                    was = was.substring(0, i)+was.substring(i+1);
          }
          gezwirbelt = String(gleich[0])+gezwirbelt+String(gleich[1]);
          return gezwirbelt;
}


DVD-Werbung
Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Alternative Portrait

-versteckt-(Autor hat Seite verlassen)

  • 03.04.2008 - 12:49

Jap ist wirklich ein super script. Danke!!

Portrait von freakk1985
  • 11.05.2006 - 00:06

nettes tut, werd ich mal ausprobieren , wenn ich zeit habe ;)

Portrait von moskito23
  • 09.03.2006 - 09:32

sehr gut erklärt nett gemacht und sieht super aus!
TOP !

x
×
×