Anzeige
Tutorialbeschreibung

Memoryspiel mit Actionscript - Teil 1

Memoryspiel mit Actionscript - Teil 1

Version: ab Flash MX
Niveau: Einsteiger bis Fortgeschrittene
Vorkenntnisse: Flash Grundlagen (Erstellung von Symbolen, Zeitleisten, Bewegungstweening), Actionscript-Grundkenntnisse (Schleifen, attachMovie, Funktionen, Variablen)
Lernziele: ein einfaches Spielkonzept entwickeln und die zugrunde liegende Spielelogik beschreiben lernen; Stringoperationen kennen lernen; setInterval einsetzen lernen; Arrays kennen lernen

Flash eignet sich hervorragend zur Erstellung von Online-Spielen. Nicht umsonst ist es in diesem Bereich mittlerweile wohl das meistverwendete Tool. Der erste Schritt bei der Entwicklung eines Spiels besteht in der konzeptionellen Darstellung der zugrundeliegenden Idee. Das ist hier einfach, da jeder das Spiel Memory kennt. Es handelt sich um ein Merkspiel, bei dem das Ziel darin besteht, Kartenpare zu finden.

Den Ablauf des Programms kann man in mehrere Phasen unterteilen:

  • Am Anfang werden die Karten zufällig gemischt.
  • Sie werden mit der Rückseite zum Spieler auf der Bühne platziert.
  • Der Spieler kann Karten durch Mausklick auswählen.
  • Dabei lassen sich drei Fälle unterscheiden:
    • Es ist noch keine andere Karte ausgewählt. Dann wird die angeklickte Karte aufgedeckt.
    • Es wurde bereits vorher auf dieselbe Karte geklickt. Das Programm soll darauf nicht reagieren. Alternativ wäre es auch möglich, eine Meldung auszugeben, z.B.: „Diese Karte wurde bereits ausgewählt“ oder „Bitte klicken Sie auf eine andere Karte“.
    • Es wurde vorher schon eine andere Karte angeklickt. Das Programm deckt die neue Karte auf und vergleicht sie mit der vorherigen. Um dem Spieler ebenfalls die Möglichkeit des Vergleichs zu geben, legt das Programm eine kurze Pause ein, in der keine andere Kartenwahl möglich ist. Bei der Auswertung gibt es zwei Möglichkeiten:
      • Die Karten sind identisch, es liegt also ein Pärchen vor. Es wird von der Bühne entfernt, so daß eine erneute Auswahl nicht mehr möglich ist. Diesen Schritt muß sich das Programm merken, um feststellen zu können, wann alle Kartenpaare gefunden wurden. Eine alternative Siegbedingung könnte auch sein, innerhalb einer vorgegebenen Zeit möglichst viele Karten aufzudecken.
      • Die Karten sind nicht identisch. Sie werden verdeckt und der Spieler kann erneut wählen.
  • Ist das Spiel zu Ende, erfolgt ein entsprechendes Feedback, i.d.R. eine Auswertung (Highscore), sowie die Möglichkeit, das Spiel neu zu starten.

Aus Gründen der Vereinfachung wollen wir weitere Spielelemente (Intro, Hilfe, Konfiguration, Startbildschirm, etc.) an dieser Stelle nicht näher erläutern. Sie sollen Teil eines anderen Workshops sein.

Die Einteilung in Phasen ist wichtig, da sie oft hilft, die Spielelogik unmittelbar in Sourcecode zu übersetzen. Bei komplexen Anwendungen behilft man sich zunächst gerne mit sogenanntem Pseudocode, der in einer halb formalisierten Sprache anstatt in korrekter Skriptsyntax den Ablauf möglichst exakt Schritt für Schritt formuliert. Sinnvoll ist auch ein Programmablaufplan, der allerdings im Gegensatz zum Pseudocode mit vollständig genormten Symbolen arbeitet und die Programmlogik visualisiert.

  1. Erstellen Sie einen neuen Film (800x600, Hintergrund schwarz, 18 Bps).
  2. Die Memorykarten bestehen aus einem MovieClip, der eine Animation für das Auf- und Zudecken enthält. Erstellen Sie ein Rechteck mit abgerundeten Ecken (dazu beim Aufziehen auf Pfeiltaste nach unten klicken; Größe 60 x 85, hellblau).
  3. Wandeln Sie es in einen MovieClip (Bibliotheksname „mc_karte“, Registrierungspunkt links oben) um. Da wir die Instanz nicht per Actionscript ansprechen, braucht sie keinen Namen.
  4. Während der MovieClip noch auf der Bühne liegt und markiert ist, verwandeln Sie ihn erneut in einen MovieClip (Bibliotheksname „mc_ani1“, Registrierungspunkt mittig). Daraus wird unsere Animation erstellt.
  5. Doppelklicken Sie auf den MovieClip („mc_ani1“), um in dessen Symbolbearbeitungsmodus zu gelangen.
  6. Dort benennen Sie die Ebene, auf der sich die Grafik befindet, um in „karte“.
  7. Fügen Sie darüber eine zweite Ebene namens „bild“ ein.
  8. Das Drehen besteht aus einen simplen Bewegungstween, der die Karte zusammenstaucht und sie anschließend wieder auf die Originalgröße skaliert. Fügen Sie daher in Frame 5 auf beiden Ebenen ein Schlüsselbild ein.
  9. Mit Hilfe des Skalieren-Werkzeugs bzw. des Frei transformieren-Tools stauchen Sie die Karte in horizontaler Richtung händisch bis auf ca. 10% der Ausgangsgröße. In der Höhe bleibt die Grafik unverändert.
  10. Anschließend weisen Sie dem ersten Schlüsselbild der Ebene „karte“ ein Bewegungstween zu.
  11. In Frame 9 fügen Sie ebenfalls auf jeder Ebene ein Schlüsselbild ein.
  12. Die Kartengrafik skalieren Sie in diesem Frame wieder auf die Ausgangsgröße zurück. Achten Sie darauf, nicht die Position zu verändern, sonst „springt“ die Karte später beim Auf- und Zudecken.
  13. Weisen Sie dem Schlüsselbild in Frame 5, Ebene „karte“ ein Bewegungstween zu.
  14. Fügen Sie in Frame 9, Ebene „bild“ die Grafik ein, die auf der Karte beim Aufdecken zu sehen sein soll. Die Grafik muß entweder als Gruppe oder als MovieClip (Registrierungspunkt mittig, Bibliotheksname beliebig) vorliegen, da Sie im nächsten Schritt ebenfalls per Tweening gestaucht werden muß.
  15. Kopieren Sie diese Grafik und fügen Sie auf derselben Ebene in Frame 5 ein.
  16. Stauchen Sie die Grafik, bis Sie fast unsichtbar ist. Wie bei der Karte erfolgt die Stauchung nur horizontal.
  17. Wenn Sie nun noch Frame 5 der Ebene „bild“ ein Bewegungstweening zuweisen, ist die Animation abgeschlossen. Folgende drei Abbildungen zeigen Frame 1, 5 und 9 des Kartenmovieclips:

Bilder
 

Bilder
 

Bilder

Beim Testen sehen Sie (hoffentlich) eine Karte, die permanent gedreht wird und dabei jeweils das Bild freigibt. Das Zudecken realisieren wir nicht per Tweening, sondern wird einfach geskriptet, indem wir die Animation rückwärts laufen lassen. Gleiches gilt für das Stoppen im ersten Bild, das ebenfalls per Skripting gesetzt wird, so daß erst ein Mausklick die Animation auslöst.

  1. Weil das einfach war, erstellen Sie bitte gleich ein komplettes Set, so daß wir insgesamt über 8 verschiedene Karten verfügen. Das geschieht am einfachsten durch Duplizieren der MovieClips in der Bibliothek, Öffnen des Duplikats im Symbolbearbeitungsmodus und Ersetzen des Bildes auf der Ebene „bild“ durch das gewünschte neue Motiv. Die MovieClips sollen „mc_ani1“ bis „mc_ani8“ heißen.

Bei solchen Übungen empfiehlt es sich, mit Dummies zu arbeiten, falls nicht direkt die richtigen Bilder zur Verfügung stehen. Dazu eignen sich die Symbole, die unter den Schriftarten Webdings und Wingdings 1 bis 3 befinden, hervorragend. Sie wurden auch im vorliegenden Beispiel verwendet.

  1. Wenn das Set fertig ist, weisen Sie jedem der eben erstellten MovieClips einen Exportnamen zu („mc_k1“ bis „mc_k8“).
  2. Löschen Sie eventuell auf der Bühne in der Szene 1 vorhandene Objekte und ändern den Namen der einzigen vorhandenen Ebene in „actions“ um.

Bei 8 verschiedenen Bildern müssen 16 Karten eingeblendet werden, um jeweils Paare bilden zu können. Wollten wir Sie geordnet einblenden, wäre das kein Problem.

  1. Schreiben Sie im Skripteditor folgendes Skript für Frame 1:

var tiefe = 1;
var anzahl = 8;
var zeilen = 4;
var spalten = (anzahl*2)/zeilen;
for (var i = 0; i < zeilen; i++){
          for(var j = 0; j < spalten; j++){
                    this.attachMovie(“mc_k”+tiefe, “k”+tiefe,tiefe);
                    var obj = this[“k”+tiefe];
                    obj._x = j * (obj._width+2);
                    obj._y = i * (obj._height + 2) ;
                    tiefe++;
          }
}

Beim Testen sollten Sie jetzt 8 Karten in vier Spalten, beginnend in der linken oberen Ecke, sehen.

 

Bilder

Die ersten 4 Zeilen des Codes definieren Variablen: die Tiefe für die einzublendenden MovieClips, die Anzahl der unterschiedlichen Bilder, die Anzahl der Zeilen sowie die errechnete Spaltenzahl. Die Formel für die Spalten ist simpel: es wird einfach die Gesamtanzahl der Karten, die sich aus der Multiplikation der verschiedenen Karten mit 2 (es handelt sich ja jeweils um Pärchen), ergibt, durch die gewünschten Zeilen dividiert. Wenn wir 16 Karten haben und diese in 4 Zeilen anordnen wollen, ergeben sich so auch 4 Spalten.

Die äußere for-Schleife sorgt für das Einblenden der Zeilen, die innere für das Anzeigen der Spalten. Welche Schleife wozu verwendet wird, hängt von der Zuweisung der x- und y-Position der Objekte ab. Die Addition von 2 führt dazu, daß zwischen den Karten sowohl horizontal wie vertikal ein Abstand von 2 Pixeln eingehalten wird.

Die for-Schleife legt fest, wie oft ein Prozeß auszuführen ist. Dabei kontrolliert die Zählvariable – in unserem Beispiel sowohl i wie auch j – die Durchläufe. Da es sich um eine verschachtelte Schleife handelt, ergeben sich folgende Abläufe:

Gestartet wird in der äußeren Schleife i mit dem Wert 0. Dann weist Flash in der inneren Schleife j ebenfalls den Wert 0 zu und führt die nachfolgenden Anweisungen (Einblenden und Positionieren) aus. Anschließend wird j auf 1 erhöht. Da dann die Bedingung in der inneren Schleife noch zutrifft (1 ist kleiner als spalten, d.h. hier: 4), werden erneut die folgenden Befehle ausgeführt. Wiederum erhöht Flash j um 1 usw. Das geschieht solange, bis die innere Schleifenbedingung nicht mehr zutrifft, also j = 4 ist. Dann geht Flash zurück zur äußeren Schleife, erhöht i um 1 auf den Wert 1 und j startet wieder mit 0. Dieser gesamte Prozeß wiederholt sich solange, bis auch die Bedingung in der äußeren Schleife nicht mehr zutrifft. Dann gilt die Schleife als beendet und Flash führt den Code aus, der nach der letzten schließenden Klammer der Schleife auftritt. Da dort in unserem Beispiel nichts mehr steht, ist das Programm zu Ende.

Der Code führt also 4 mal die äußere und bei jedem dieser Durchläufe 4 mal die innere Schleife aus, ergibt 4x4=16 Durchläufe. In beredter Prosa: 16 mal wird die attachMovie-Methode aufgerufen. Daß trotzdem nur 8 Bilder zu sehen sind, liegt an der Variablen tiefe, die nach jedem Einblenden um 1 inkrementiert (das klingt sehr professionell!), d.h. um 1 hochgezählt wird. Da sich der Exportname der einzufügenden MovieClips aus dem Kürzel „mc_k“+tiefe zusammensetzt, ist spätestens bei „mc_k8“ Schluß. Der letzte in der Bibliothek zugewiesene Exportname lautet nämlich „mc_k8“. Wenn der Name „mc_k9“ ermittelt wird, will Flash zwar weiterhin etwas einfügen, aber das betreffende Objekt existiert nicht. Ein ziemliches Manko des Skripteditors ist es übrigens, daß er nicht darauf hinweist, daß per Code auf ein nicht existierendes Objekt zugegriffen wird. Andere IDEs beherrschen so etwas schon längst, und das erspart bei komplexen Projekten so manche verzweifelte Suche nach Bugs!

Um dennoch 16 Karten zu erhalten, gibt es mehrere Möglichkeiten. Da wir später noch eine Zufallsverteilung brauchen, packen wir einfach alle Kartennamen zweimal in ein Array und blenden sie dann ein.

  1. Das benötigte Array läßt sich leicht generieren, denn wir haben in kluger Vorahnung die Exportnamen durchnummeriert. Schreiben Sie unmittelbar vor die bestehende, verschachtelte Schleife, aber nach der Initialisierung der Variablen spalten :

aTempNums = [];
for(var i = 1; i <= anzahl; i++){
for(var j = 1; j <= 2; j++){
          aTempNums.push(i);
          }
}

Zunächst wird aTempNums als leeres Array, d.h. als eine Variable, die mehrere Werte aufnehmen kann, definiert. Anschließend wird es durch eine erneute verschachtelte Schleife gefüllt, wobei wir lediglich Zahlen zuweisen. Da wir 8 verschiedene Karten haben, wird über die äußere Schleife von 1 bis 8 hochgezählt. Und da wir jede Karte zweimal haben wollen, sorgt die innere Schleife bei jedem äußeren Durchlauf zweimal dafür, daß Flash die Zählvariable i, also 1 bis 8, in das Array schreibt.

  1. Heraus kommt 1,1,2,2,3,3 usw. Das können Sie testen, indem Sie nach der letzten schließenden Klammer der eben erstellten Schleife den Inhalt des Arrays auslesen:

trace( aTempNums );

Um nun 16 Karten einzublenden, muß lediglich die attachMethode abgeändert werden. Anstatt den Namen über die Variable tiefe festzulegen, wollen wir ihn mit Hilfe der Zahlen, die im Array aTempNums enthalten sind, zusammensetzen.

  1. Ändern Sie daher die attachMovie-Zeile und die nachfolgende Zeile wie folgt:

this.attachMovie(„mc_k“+aTempNums[tiefe], “k”+tiefe+“_“+aTempNums[tiefe], tiefe);
var obj = this[“k”+tiefe+“_“+aTempNums[tiefe]];

Halt, noch nicht testen, auch wenn der Finger schon juckt! Falls es bereits zu spät ist: Der Platz für die letzte Karte bleibt leer, es sind also nur 15 statt der erwarteten 16 Karten zu sehen. Die erste Karte wird nur einmal angezeigt, alle anderen liegen doppelt vor.

Der Grund liegt in der Variablen tiefe, die mit 1 initialisiert wird. Das ist insofern problematisch, als wir in der neuen attachMovie-Zeile damit auf das Array zugreifen. Das erste Element in einem Array besitzt den Index 0, nicht jedoch 1. Um also auch das erste Element erfassen zu können, muß tiefe mit 0, nicht 1 initialisiert werden.

  1. Korrigieren Sie die entspechende Zuweisung für tiefe:

tiefe = 0;

Wenn tiefe mit 0 beginnt, greift Flash beim ersten Schleifendurchlauf auf den Index 0 des Arrays aTempNums zu, d.h., Flash nimmt das erste Element. In unserem Fall ist das die Zahl 1. Das Array hatte ja folgenden Inhalt: 1,1,2,2,3 usw. Beim nächsten Durchlauf ist tiefe um eins inkrementiert und hat auch den Wert 1. Der Index 1 entspricht im Array dem zweiten Element, in unserem Fall wiederum der 1. Beim dritten Schleifendurchlauf ist tiefe = 2, es wird damit auch der Index 2, also das dritte Element im Array ausgelesen usw.

Die so ermittelten Verknüpfungsnamen für unsere Karten lauten „mc_k1“, „mc_k1“, „mc_k2“, „mc_k2“, „mc_k3“ etc. Jeder Name taucht zweimal auf, und jetzt werden auch 16 Karten angezeigt, wenn Sie testen.

  1. Damit nicht dauernd die Animation abgespielt wird, fügen Sie nach der Zuweisung für obj folgende Zeile ein:

obj.gotoAndStop(obj._totalframes);

Jede Karte springt direkt zum letzten Frame, in dem sie völlig aufgedeckt ist. Für unsere Tests ist es momentan wichtig, daß wir die Bilder der Karten sehen können. Natürlich hätte man auch statt (obj._totalframes) auch (9) schreiben können, da die Zeitleiste des in der Variablen obj erfassten MovieClips 9 Frames umfasst. Der Nachteil dabei wäre aber, daß wir bei einer Änderung der Animation, z.B. wenn wir einige Frames hinzufügen, um sie zu verlängern, auch den Programmcode anpassen müssten. Wenn wir dagegen mit der Eigenschaft _totalframes arbeiten, springt Flash immer zum letzten Frame, egal, ob das nun die 9, 12 oder irgendeiner anderer Wert ist.

Die AttachMovie-Methode übergibt als zweiten Parameter den Instanznamen des eingeblendeten Objektes. Der muß in unserem Fall zwei verschiedenen Kriterien genügen:

  • er muß eindeutig sein, es darf also kein Name doppelt vorkommen. Das erreichen wir, indem einfach die Variable tiefe in den Namen aufgenommen wird: „k“+tiefe. Damit lauten die Namen „k1“ bis „k16“.
  • Allerdings benötigen wir auch irgendein Merkmal, das bei genau zwei Karten identisch ist, um später die Pärchen identifizieren zu können. Leider können wir Flash nicht anweisen, es soll einfach nachschauen, von welchem MovieClip die jeweilige Instanz abstammt. Daher speichern wir genau diese Information im Instanznamen: aTempNums[tiefe].

Schauen wir uns noch einmal den Ablauf an: beim ersten Schleifendurchlauf wird der MovieClip mit dem Exportnamen „mc_k1“ eingefügt. Er erhält den Instanznamen „k1_1“. Dann folgt erneut der MovieClip „mc_k1“, diesmal mit dem Exportnamen „k2_1“. Als drittes Objekt fügt Flash „mc_k2“ mit dem Exportnamen „k3_2“ ein, gefolgt von „mc_k2“ mit dem Instanznamen „k4_2“. Alle Instanznamen kommen nur einmal vor, aber nach dem „_“ folgt eine Zahl, die derjenigen entspricht, die auch im Verknüpfungsnamen des exportierten MovieClips enthalten ist. Wenn also zweimal dasselbe Objekt exportiert wird, dann findet sich in dessen Instanznamen auch jeweils dieselbe Zahl.

  1. Das können wir testen, indem wir uns den Instanznamen der Objekte bei Mausklick ausgeben lassen. Fügen Sie nach der Definition der var obj folgende Zeilen ein:

obj.onPress = function(){
          trace(this._name);
}

Das vollständige Skript sieht momentan so aus:

Bilder
 

Jetzt gibt jede Karte bei Mausklick ihren Instanznamen im Nachrichtenfenster aus. Wenn Sie zwei gleiche Karten anklicken, werden Namen angezeigt, deren Ziffern nach dem Unterstrich identisch sind.

Momentan werden alle Karten ab der linken oberen Ecke eingeblendet. Um sie anders zu positionieren, könnten wir innerhalb der Schleife jeweils zur x- und y-Position einen beliebigen Wert addieren. Es gibt jedoch noch eine andere Möglichkeit, die erheblich mehr Flexibilität bietet. Wir machen uns die Tatsache zunutze, daß jedes Symbol in Flash ein eigenes Koordinatensystem besitzt. Dann brauchen wir alle Karten nur in ein anderes Symbol einzufügen und ändern ihre Position, indem wir das übergeordnete Symbol an eine andere Stelle setzen. Innerhalb der Schleife können wir dann die x- und y-Koordinaten unverändert lassen.

  1. Fügen Sie ganz am Anfang des Skriptes folgendes ein:

this.createEmptyMovieClip(„box“,1);
box._x = 100;
box._y = 100;

  1. Und innerhalb der for-Schleife, die das attachMovie enthält, ersetzen Sie this durch box (hier Fettdruck):

box .attachMovie("mc_k"+aTempNums[tiefe], "k"+tiefe+"_"+aTempNums[tiefe], tiefe);
var obj = box["k"+tiefe+"_"+aTempNums[tiefe]];

Beim Testen werden die Objekte nicht mehr links oben, sondern um jeweils 100 Pixel nach rechts und unten versetzt angezeigt. Mit createEmptyMovieClip haben wir einen leeren MovieClip erzeugt, der uns als Behälter dient. Da die Karten ihm und nicht wie vorher direkt der Szene 1 zugeweisen werden, bezieht sich die Positionsangabe für obj._x und obj._y auf das lokale Koordinatensytem des leeren MovieClips. Relativ zum MovieClip box wird die erste Karte auf der Position x = 0 und y = 0 abgelegt. Trotzdem ist sie um 100 Pixel nach rechts und unten verschoben, weil sich ja box an dieser Stelle befindet. Das ist genauso, als wenn Sie etwas in eine Kiste hineinlegen und anschließend die Kiste an eine andere Stelle schieben. Dann wird auch ihr Inhalt notwendigerweise an die andere Stelle verschoben.

Diese Arbeitsweise hat noch einen weiteren Vorteil: wenn wir beispielsweise alle Karten auf einmal los werden wollen, müssen wir sie nicht mühsam Stück für Stück löschen, sondern es reicht aus, den übergeordneten MovieClip, also box, zu löschen.

  1. Testweise erweitern Sie das onPress-Ereignis von obj nach der trace-Anweisung:

this._parent.removeMovieClip();

Sobald Sie eine Karte anklicken, wird box, der _parent der Karte, gelöscht – und damit verschwinden natürlich alle Elemente, die sich in diesem MovieClip befinden.

  1. Löschen Sie die Zeile mit removeMovieClip wieder, da sie nicht mehr weiter benötigt wird.

Last not least bietet die Verwendung eines Behälters die Möglichkeit, unsere Anwendung sauberer zu strukturieren. Wir können ihm nämlich alle Elemente zuweisen, die von der Logik her mit den Karten zusammenhängen. Damit sind nicht nur die visuell wahrnehmbaren Karten gemeint, sondern auch Variablen und gegebenenfalls Funktionen. Darin spiegelt sich rudimentär die aus der Softwareentwicklung her bekannte Idee des objektorientierten Designs wider.

Stellen Sie sich vor, das Spiel wäre Teil einer größeren Anwendung. Wenn der User es gespielt hat und sich anderen Screens zuwendet, dann wäre es unnötig, weiterhin diejenigen Funktionen und Variablen im Arbeitsspeicher zu behalten, die sich nur auf das Spiel beziehen. Diese sollten stattdessen gelöscht werden, um nicht unnötig Ressourcen zu blockieren. Das ist auch in den Zeiten von Trillahertz-Prozessoren und Trilobyte-RAM ein Argument, denn die Flash-Engine ist leider recht langsam und erreicht selbst heute noch nicht die Performance, die seinen einstigen großen Bruder Director schon vor Jahren auszeichnete.

Zudem erleichtert es die Wartung des Programms, wenn seine Elemente unmittelbar den Objekten zugeordnet sind, auf die sie sich beziehen.

In unserem konkreten Fall bedeutet das, alle spielerelevanten Variablen direkt dem MovieClip box zuzuweisen.

  1. Führen Sie die nachfolgend hervorgehobenen Änderungen am bisherigen Skript durch:

this.createEmptyMovieClip("box", 1);
box._x = 100;
box._y = 100;
box. tiefe = 0;
box. anzahl = 8;
box. zeilen = 4;
box. spalten = (box.anzahl*2)/ box.zeilen;
box. aTempNums = [];
for (var i = 1; i<= box.anzahl; i++) {
          for (var j = 1; j<=2; j++) {
                    box.aTempNums.push(i);
          }
}
trace(box.aTempNums);
for (var i = 0; i< box.zeilen; i++) {
          for (var j = 0; j< box.spalten; j++) {
                    box.attachMovie("mc_k"+ box.aTempNums[box.tiefe], "k"+ box.tiefe+"_"+ box.aTempNums[box.tiefe], box.tiefe);
                    var obj = box["k"+ box.tiefe+"_"+ box.aTempNums[box.tiefe]];
                    obj.onPress = function() {
                              trace(this._name);
                              this._parent.removeMovieClip();
                    };
          obj.gotoAndStop(9);
          obj._x = j*(obj._width+2);
          obj._y = i*(obj._height+2);
          box. tiefe++;
          }
}

Wenn Sie alles korrekt geändert haben, werden Sie zwar beim testen keinen Unterschied feststellen, doch wären jetzt neben den Karten auch alle Variablen (mit Ausnahme der Zählvariablen i und j) verschwunden, sobald wir den MovieClip box löschen würden.

Das sind erst 3.100 Wörter und wir haben schon fast den ersten Punkt unserer Spielekonzeption „Am Anfang werden die Karten zufällig gemischt“ abgearbeitet – wir liegen also gut im Rennen ;-)

Die Reihenfolge der Karten, die sortiert vorliegen, wird durch das array aTempNums vorgegeben. Hätten wir an dessen Stelle ein unsortiertes Array mit beliebigen Zahlen zwischen 1 und 8, dann wäre unser Problem bereits gelöst. Leider verfügt Flash nicht über eine Array-Methode schüttelSchüttel(). Wir müssen uns daher mit einem kleinen Trick behelfen.

  1. Fügen Sie nach der Schleife, die aTempNums vollständig füllt, ein:

box.aKarten = [];
while(box.aTempNums.length > 0){
          var zufall = Math.floor(Math.random()*box.aTempNums.length);
          box.aKarten.push(box.aTempNums[zufall]);
          box.aTempNums.splice(zufall,1);
}

  1. Innerhalb der nachfolgenden for-Schleife ersetzen Sie jeweils aTempNums durch aKarten. Wenn Sie testen, werden nun die Karten in zufälliger Reihenfolge angezeigt.

Das Skript sieht jetzt so aus:

Bilder
 

In beredter Prosa: wir richten ein neues Array ein, in das wir zufällig aus dem Array aTempNums ermittelte Zahlen einfügen. Damit diese Zahl nicht noch mal gezogen wird, müssen wir sie in aTempNums löschen. Das wiederholen wir solange, bis aTempNums leer ist.

Schauen wir uns den Vorgang an einem konkreten Beispiel an. Das Array aTempNums enthält folgende Zahlen: 1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8. In der Variablen zufall wird eine Zufallszahl ermittelt. Der kleinstmögliche Wert ist 0 und der größtmögliche Wert entspricht der Gesamtanzahl der Elemente, die sich in aTempNums befinden, minus 1, also 15. Da wir diese Zahl als Indexzugrif verwenden, muß sie mindestens 0 und höchstens 15 betragen (Sie erinnern sich: Programmier beginnen mit der 0, nicht wie normale Menschen mit der 1). Nehmen wir an, es würde sich um die 5 handeln. Dann würde das Element, das sich auf dem Index 5 in aTempNums befindet, also das 6. Element, in aKarten eingetragen. In unserem Fall wäre das die Zahl 3. Gleichzeitig wird dieses Element in aTempNums gelöscht. Das ist einerseits notwendig, damit genau dieses Element nicht noch einmal ermittelt werden kann. Zum anderen muß die Länge von aTempNums bei jedem Durchlauf verkürzt werden, sonst entsteht eine Endlosschleife: while wird ja solange ausgeführt, wie die Länge von aTempNums größer als 0 ist.

Angenomen, beim nächsten Durchlauf wird als Zufallswert die 7 ermittelt. Index 7 entspricht in aTempNums der 5. Diese wird an aKarten drangehängt, so daß aKarten nun die Werte 3,5 enthält. Anschließend erfolgt wieder das Löschen in aTempNums.

Nun könnte z.B. die Zufallszahl 1 lauten, was als Indexnummer in aTempNums ebenfalls der Zahl 1 entspricht. Nach dem Speichern in aKarten gespeichert und dem Löschen in aTempNums sehen beide Arrays nun folgendermaßen aus:

aTempNums = [1,2,2,3,4,4,5,6,6,7,7,8,8]

aKarten = [3,5,1]

Die drei Grafiken verdeutlichen diesen Vorgang.

Bilder

Bilder

Bilder

Da attachMovie nicht mehr auf eine geordnete, sondern auf eine willkürlich zusammengewürfelte Liste zugreift, besitzen auch die Exportnamen der einzublenden Objekte keine geordnete Reihenfolge mehr. Sie würden jetzt für die ersten drei Karten lauten: „mc_k3“, „mc_k5“ und „mc_k1“.

Runter mit dem Red Bull und weiter zu Teil 2!


Kommentare
Achtung: Du kannst den Inhalt erst nach dem Login kommentieren.
Portrait von Leyla_Arduc
  • 14.06.2012 - 22:14

Nabend,

ich versuche das Memoryspiel nachzumachen, doch leider tritt folgende Fehlermeldung auf:

Szene=Szene 1, Ebene=actions, Bild=1: Zeile 7: Syntaxfehler.
this.attachMovie(“mc_k”+tiefe, “k”+tiefe, tiefe);

Szene=Szene 1, Ebene=actions, Bild=1: Zeile 8: Syntaxfehler.
var obj = this[“k”+tiefe];

Eigentlich ist es 1:1 übernommen worden. Ein kurzes Feedback würde mir sehr viel weiterhelfen. Danke vorab!

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 31.10.2011 - 20:13

bin schon gespannt, ob ich es hin bekomme

Portrait von gundleyG
  • 30.12.2010 - 23:27

... na das ist doch mal richtig was! Gefällt mir wirklich gut.

Portrait von daaabi
  • 15.12.2010 - 21:39

verwende cs4 und bei mir kommt beim 1. skript ne fehlermeldung:

TypeError: Error #1006: attachMovie ist keine Funktion.

Kann mir jemand helfen?

Portrait von kleine_miss
  • 13.10.2010 - 08:40

für einsteiger ist es glaub ich etwas zu schwer...aber wenn man etwas übung hat klappt's

Portrait von ichwillnurlernen
Portrait von 4Pixel
  • 04.08.2010 - 09:31

Das erste Script (Punkt 21) funktioniert bei mir leider nicht - ich arbeite mit CS4 - kann mir jemand helfen?

Portrait von Lord_of_Hate
  • 10.07.2010 - 12:36

zwar ein paar probs gehabt aber dennoch geschafft
danke für das gute tut

Portrait von womanisery
  • 03.05.2010 - 21:08

Super, wir haben in Flash am Donnerstag die Prüfung und das ist genau das, was ich brauchte ;)))

Portrait von Nadine77
  • 23.09.2009 - 22:08

Klasse! Habe das Memory mit eigenen Bilder nachgebaut - echt super!
Danke nochmal - war genau das, was ich haben wollte!

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 14.09.2009 - 15:53

huhu hab das problem das ich immer noch 8 karten statt 16 hab, wie gehört das mit den "" kann mir wer da helfen

zb:
his.attachMovie(„mc_k“+aTempNums[tiefe], “k”+tiefe+“_“+aTempNums[tiefe], tiefe);
var obj = this[“k”+tiefe+“_“+aTempNums[tiefe]];

welche gehörn jez die was so stehn “k” schreibt der compiler nen error wie gehörn denn die "" richtig???

bitte um hilfe :D

Portrait von SaLue85
  • 26.05.2009 - 14:45

Ich danke dir vielmals für das Tutorial... Habs selber versucht, aber leider nicht hinbekommen!

Portrait von schmidalov
  • 23.03.2009 - 15:12

wenn es allein schon klappen würde, wär dieses Tutorial toll! aber noch dazu in einzelnen Schritten sehr gut erklärt, was will man mehr!
einzig allein der letzte Array mit push, splice random, etc. könnte für einen ganz anfänger noch etwas verwirrend sein, trotzdem perfekt! vielen dank

Portrait von brot41
  • 29.01.2009 - 09:17

ganz tolles tutorial, super erklärt, habe viel gelernt. Vielen Dank h_seldon!

Portrait von tata1986
  • 15.09.2008 - 16:20

Hab das komplette Spiel nachgebaut! Funktioniert einwandfrei! Hoffentlich gibts noch mehr davon!

Portrait von schlumpfiii
  • 24.04.2007 - 08:43

vielen dank für das TUT, werd mich gleich mal damit beschäftigen und sehen ob ich es damit hinbekomme :))

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 06.03.2007 - 11:13

Habe mir selbst den Kopf zerbrochen wie ich das lösen könnte und hab´s ganz ehrlich nicht geschafft. Daher, vielen Dank, großartiges Tutorial

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 29.12.2006 - 13:17

Danke h_seldon für Deinen tollen Workshop!

Habe von Anfang an Deinen Workshop benutzt, um meine eigenen Ideen von einem Memory zu verwirklichen!

Beim Expertnamen musste ich auch tüffteln, da ich den Befehl nicht kannte:

Ach ja... habe zunächst die einzelnen Scripts mit Copy und Paste eingebaut, hatte dann aber Fehlermeldungen, da die Anführungszeichen "" nicht kompatibel waren. (Bin halt ein Lie ... und habe diese Feinheit erst nicht bemerkt :-(

Aber noch mal vielen, vielen Dank für Deine Mühe!!!

Barbara

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 10.12.2006 - 20:23

Das hat mit wirklich weitergeholfen! Ich hab das Tutorial mehrheitlich gebrauch um mir èberlegungen zu machen, wie ich das memory selbt aufbauen könnte.

Alternative Portrait
-versteckt-(Autor hat Seite verlassen)
  • 26.11.2006 - 16:47

Endlich habe ich einen leicht verständliches Tutorial gefunden. Da wird sich meine Schwester aber freuen.

x
×
×