Flash

Flashgalerie oder wie tickt Actionscript 2.0 (Flash Tutorial)

Tutorial erstellt von Ulli H., letzte Änderung am 30.05.2008

Flashgalerie oder: Wie tickt Actionscript 2.0?

Hallo. In diesem Tutorial möchte ich euch ActionScript 2.0 näher bringen bzw. aufzeigen, wie ähnlich diese schöne Programmiersprache den anderen ist und was man damit anstellen kann. Dieses Tutorial richtet sich hierbei ausschließlich an erfahrene Programmierer, die sich AS anschauen bzw. in AS einsteigen möchten. - Außerdem lernt ihr hier, wie Flash arbeitet.

Der Aufhänger für dieses Tutorial war eine Diskussion hier im Forum bzgl. einer Flashgalerie. Also werde ich auch eine solche für dieses Tutorial verwenden. Anschauen unter http://www.der-webdesigner.net/forum/flash-f34/flashgalerie-fuer-euch-t7441.html

Aufbau dieses Tutorials:


1.) Kurze Erklärung wie Flash arbeitet
2.) Grobe Erklärung der Sprache Actionscript 2.0
3.) Abarbeitung des Galeriecodes mit kleinen Kommentaren zur Verdeutlichung

Wie arbeitet Flash?


Die Zeitleiste

Wie ihr sicher schon wisst, ist das Herzstück von Flash die so genannte Zeitleiste (Timeline). Stellt euch diese Zeitleiste als Filmrolle mit vielen,  vielen einzelnen Bildern vor. Da unbegrenzt Ebenen (Layer) erstellt werden können, sind wir sogar in der Lage unsere Filmrolle in Spuren aufzuteilen. Ähnlich wie zum Beispiel bei Photoshop richtet sich die Sichtbarkeit nach der Reihenfolge, d.h. die oberste Ebene verdeckt die unterste usw.
Wer mit diesem Beispiel nichts anfangen kann, mag sich die Ebenen bitte als Spielkarten vorstellen. Bei der Draufsicht sieht man die oberste zuerst, dann die nächste, dann die unter dieser liegende, ... .

Um unsere Filmrolle zu steuern (abspielen, stoppen, zu Bild springen, etc.) verwenden wir die wenigen Actionscriptbefehle, die es tatsächlich nicht in anderen Programmiersprachen gibt, nämlich:

stop();
play();
gotoAndStop(Bildzahl);
gotoAndPlay(Bildzahl);


stop() und play() erklären sich von selbst. gotoAndStop() lässt unseren Bildzeiger auf das angegebene Bild springen und unseren Film dort anhalten. gotoAndPlay() lässt unseren Bildzeiger auf das angegebene Bild springen und unseren Film von dort abspielen.

Wir steuern damit die Zeitleiste. Nicht die Ebenen

D.h. play() spielt die ganze Filmrolle (Zeitleiste) ab, und nicht nur die Ebene, auf der das AS platziert wurde. Was uns zum nächsten Schritt bringt, nämlich der Ordnung: Für Actionscript empfiehlt es sich generell immer, eine eigene Ebene zu erstellen, welche wirklich nur die Schlüsselbilder enthält, die programmiert wurden. Kleines Beispiel:

Eine Zeitleiste mit der Länge von 10 Bildern und 3 Ebenen.

Ebene 1 (Name AS) enthält 10 Schlüsselbilder mit Actionscript, z.B. play()
Ebene 2 (Name Bilder) enthält 10 Schlüsselbilder mit Bildern
Ebene 3 (Name Background) enthält 10 Schlüsselbilder mit Grafiken für den Background

Natürlich reicht pro Ebene auch jeweils ein Schlüsselbild, das eben auf die 10 Bilder verlängert wurde. Muss ich aber, glaube ich, nicht erklären, denn jeder, der sich mit AS beschäftigen möchte, sollte die Grundoptionen und Arbeitsmöglichkeiten schon kennen.
Zur eigentlichen Zeitleiste können wir selbstverständlich auch weitere Movieclips in unseren Zeitleistenbildern platzieren. Movieclips haben auch wieder eine eigene Zeitleiste, die ganz genauso wie unsere Hauptzeitleiste funktioniert.
Wir können so eigentlich unbegrenzt viele Filmrollen abspielen, und deren Abspielverlauf von jeder Zeitleiste und jedem MC aus steuern. Wir können jedem Bild unserer Filmrolle also eine neue Filmrolle zuordnen und diese abspielen. Besser geht es nicht einmal in Hollywood.
Trotzdem sollte man natürlich eines beachten: Wenn wir beispielsweise auf Bild 10 einen Movieclip (oder besser Film) abspielen möchten, so muss unbedingt der Film bei Bild 10 gestoppt werden. Da ja logischerweise bei Bild 11 (sofern Bild 10 nicht verlängert wurde) der Movieclip nicht mehr vorhanden ist. Leuchtet ein, oder?

MovieClips

Movieclips gibt es übrigens in 3 verschiedenen Formen: Als Movieclip selbst (die häufigste Form), als Grafik (seltenst) und als Schaltfläche.
Der Movieclip "Schaltfläche" unterscheidet sich dahingehend von den anderen, dass dessen Zeitleiste nur über vier Bilder verfügt und nicht verlängert oder verkürzt werden kann. Auch können diese vier Bilder nicht explizit programmiert werden. Tatsächlich sind diese Bilder nämlich schon mit Flashbordmitteln ausgestattet. Nämlich mit den Situationen

Standard (Ohne Interaktion oder MouseOut)
MouseOver (Wenn Maus darüber)
MouseDown (Wenn die Maus gedrückt wurde)
MouseAktiv (Wenn der Link aktiv ist)

(Um's zu versuchen, setzt einfach einmal verschiedene Grafiken auf die jeweiligen Bilder.)
Somit ist bei dem MovieClip "Schaltfläche" natürlich auch die Programmierbarkeit auf ein Minimum reduziert:

Code:
on(press)
{
   trace("Maus gedrückt");
}

on(release)
{
   trace("Maus losgelassen");
}

on(rollOver)
{
   trace("Maus darüber");
}

on(rollOut)
{
   trace("Maus weg");
}

Es sind also nur vier vorinstallierte Funktionen erlaubt, denen man Anweisungen zuteilen kann. Nicht funktionieren und eine Fehlermeldung ausgeben bei Schaltflächen würde eine Programmierung, die außerhalb dieser vier Funktionen etwas abarbeiten sollte.

ActionScript

Es gibt drei Möglichkeiten AS anzuwenden:

1.) Im Schlüsselbild ( Aktionsfenster zeigt "Aktionen – Bild")
2.) Den MovieClip direkt ( Aktionsfenster zeigt "Aktionen – Movieclip")
3.) Die Schaltfläche direkt( Aktionsfenster zeigt "Aktionen – Schaltfläche")

Die heutzutage am häufigsten verwendete Möglichkeit ist aber Möglichkeit 1 (im Schlüsselbild), da hier jeder Movieclip von einer Position aus angesprochen und programmiert werden kann. Deshalb werde ich in diesem Tutorial auch nur diese Programmierweise vorstellen.

Um nun aber programmiertechnische Aktionen auf unsere Movieclips zu übertragen, müssen diese erstmal Flash bekannt gemacht werden, sofern wir sie nicht dynamisch erstellen. Kurzum: die Grafik mit F8 in Symbol (Movieclip) umzuwandeln, reicht zwar aus, um diesen Movieclip direkt zu programmieren (anklicken), nicht aber um ihn vom Schlüsselbild in der Zeitleiste aus anzusprechen. Hierfür müssen wir an unserem Movieclip noch einen Instanznamen vergeben (MC anklicken, Eigenschaftsfenster, Instanznamen eingeben).

Wenn wir z.B. ein Quadrat aufziehen, dieses in einen MovieClip verwandeln und den Instanznamen ("square") vergeben, könnten wir diesen so programmieren:

Code:
square.onRollOver = function()
{
   this._x = Math.random(Stage.width);
   this._y = Math.random(Stage.height);
}

Effekt: Unser Quadrat wechselt seine Position, wenn wir mit der Maus darüberfahren. Bei diesem Beispiel haben wir schon die ersten Ähnlichkeiten zu anderen Programmiersprachen.

Code:
square.onRollOver

Wenn man also mit der Maus über unseren "square" fährt, wird die hinter dem Gleichzeichen definierte Funktion ausgeführt. Die Syntax für eine Funktion gleicht der in vielen anderen Sprachen. Auch vordefinierte Funktionen wie  Math.random() beispielsweise stehen zur Verfügung; random() liefert für einen Zufallswert, erzeugt durch einen oder mehrere Parameter. Flash benötigt nur einen, hier ist das Stage.width (Breite der sichtbaren Bühne in Pixeln) bzw. Stage.height  (Höhe der sichtbaren Bühne in Pixeln).
this steht in diesem Fall für "dieses" und bezeichnet das Objekt, welches diese Funktion initiiert. Wir haben also unseren MovieClip "square" selbst programmiert, indem wir seinen Instanznamen voran gesetzt haben: "square.onRollOver = ..."

Genauso könnten wir auch die Zeitleiste von "square" beeinflussen, sofern diese mehr als nur ein Bild enthält:

Code:
square.onRelease = function()
{
   this.gotoAndStop(3);
}

Bisher noch alles klar?

Hätten wir nun im ersten Bild unseres Movieclips "square" ein Quadrat, im dritten aber einen Kreis, würden wir also beim Klicken und Verlassen der Maus von "square" einen Kreis anstelle unseres Quadrates sehen.
Angenommen wir hätten jetzt im Movieclip "square" einen weiteren Movieclip mit dem Instanznamen "circle", so könnten wir natürlich auch nur den
Movieclip "circle" befehligen, ohne hierfür extra in den Movieclip "square" zu gehen.

Code:
square.circle.onPress = function()
{
   trace(this + "wurde gedrückt");
}

Natürlich kann man unbegrenzt viele Movieclips ineinander verschachteln und wie in unserem Beispiel programmieren. Entsprechend lang wäre allerdings der Pfad vor der eigentlichen Programmierung:

"square.circle.triangle.roogt.cyclet.Befehl"

Beachte: Pfade müssen explizit und pedantisch absolut oder relativ aufgeführt werden

trace ist übrigens ein Befehl, der ausschließlich für die Entwickler erdacht wurde. In diesem Bespiel würde beim Testen des Filmes im Ausgabefenster "_level0.square.circle wurde gedrückt" stehen. So kann der Entwickler jederzeit seine Programmzeilen auf Funktionalität testen. Der spätere Betrachter des Werkes sieht diese Traceaktionen natürlich nicht.

Level und Ebenen


Abgesehen von der manuellen Ebenenerstellung gibt es auch noch Unterschiede im dynamischen Bereich.

_level0 z.B. steht für _root, was wiederum Wurzel bedeutet. Also Fundament, Fuß oder wie auch immer man es nennen möchte. In jedem Fall aber steht alles auf _root, womit diese Ebene unverzichtbar und das wichtigste Element in der Flashprogrammierung ist.
Nehmen wir z.B. mal das umgekehrte Beispiel. Wir wollen im Movieclip "square" einen Movieclip namens "Testmc" im _root programmieren. Nun hier gibt es zunächst mal den absoluten Pfad.

Möglichkeit 1:
Code:
_root.Testmc.onRelease = function()
{
   trace("Gedrückt");
}


Dies funktioniert, da "Testmc" ja direkt im _root liegt. Es würde aber nicht funktionieren, wenn "Testmc" in einem  Movieclip mit Namen "halter" im _root liegen würde. In diesem Falle wäre es dann
Code:
_root.halter.Testmc.onRelease = function()
{
   trace("Gedrückt");
}


Oder wir verwenden den relativen Pfad - Möglichkeit 2:
Code:
_parent.Testmc.onRelease = function()
{
   trace("Gedrückt");
}

_parent steht für "eine Ebene darunter" und funktioniert, da "Testmc" ja auf der selben Ebene wie unser programmierter "square" Movieclip steht. Dennoch muss _parent verwendet werden, da wir zwar sinnbildlich nicht eine Ebene tiefer gehen, jedoch trotzdem aus unserem Movieclip heraussteigen. Vermutlich wäre es sinnvoller gewesen, hierfür einen eigenen Befehl einzuflechten, da gerade mit diesen Pfadangaben schon öfters Stolperfallen für junge Actionscriptler gelegt wurden.
Mit dem Befehl _parent kann man im Gegensatz zu _root auch eine Kette bilden die bis zum _root führen würde. Je nach Position z.B.:
Code:
_parent._parent._parent...     usw. usw.


So etwas kann mit _root natürlich nicht gehen, da _root absolut in die unterste und somit erste Ebene führt.

Wir werden im Laufe dieses Tutorials auch MovieClips (MC) dynamisch erstellen. Hier ist zu beachten, dass im Gegensatz zum manuellen Erstellen von MCs unbedingt immer nur eine Ebene (level) für diesen MC verbraucht wird.

Beispiel: Wir erstellen MC "square" auf Level 0, so müsste MC "Testmc" auf Level 1 oder höher stehen. Andernfalls würde "Testmc" schlicht und einfach MC "square" löschen und das Level 0 einnehmen. Auch diese Level sind den manuell erstellten Ebenen visuell ähnlich. Und: MCs auf Level 10 verdecken die auf weiter unten liegenden MCs.

Desweiteren ist zu beachten, dass diese Levelregelung immer für den jeweiligen MC anzuwenden ist:
Im _root werden beispielsweise 2 MCs erstellt ("mc1" auf Level 0 und "mc2" auf Level 1), so kann dennoch im "mc1" wiederum ein MC auf Level 0 erstellt werden, da dieser MC in sich wieder eine neue Levelhierarchie zulässt.
Sollte nun aber der MC in "mc1" auf Level 1000 stehen, so wird er doch wie auch sein ummantelnder "mc1" von "mc2" verdeckt, da dieser im Gesamten auf einer höheren Ebene steht.

MovieClips dynamisch erstellen

Im folgenden Galeriescript werden wir auch MCs dynamisch erstellen. Hierfür verwenden wir den Befehl Code:
createEmptyMovieClip()


Der Befehl ist wie folgt aufgebaut:

1.) Position (wo erstellen wir den Befehl)
2.) Der Befehl selbst(bzw. die Klasse die uns Flash schon als Bordmittel liefert)
3.) Der Name des MCs (Instanzname)
4.) Das Level des MCs

Also:

Code:
_root.createEmptyMovieClip("meinmc",1);

Hier erstellen wir also im _root einen MovieClip namens "meinmc" auf Level 1. Da wir ja auch im _root  programmieren, können wir uns die Anführung von _root auch sparen und einfach
Code:
createEmptyMovieClip("meinmc",1);

verwenden. Allerdings wird bei dieser Variante der Befehl createEmptyMovieClip() nicht blau markiert und könnte somit beim Entwickler für Verwirrung sorgen. Aber funktionieren tut es auch so.

Wir können auch in bestehenden MCs mit diesem Befehl neue MCs erstellen:

Code:
square.createEmptyMovieClip("meinmc",1);

Oder in mcs dieses mcs usw.:

Code:
square.circle.createEmptyMovieClip("meinmc",1);

Natürlich können wir unseren bisher noch unsichtbaren MCs auch visuelle Formen dynamisch verpassen.

Code:
createEmptyMovieClip("meinmc", 0);

meinmc.beginFill(0xFFFFFF,100);
meinmc.moveTo(Wert xPosition links oben im Verhältnis zur Bühne, Wert yPosition links
oben im Verhältnis zur Bühne);
meinmc.lineTo(Wert xPosition links oben, Wert yPosition links oben);
meinmc.lineTo(Wert xPosition rechts oben, Wert yPosition rechts oben);
meinmc.lineTo(Wert xPosition unten rechts, Wert yPosition unten rechts);
meinmc.lineTo(Wert xPosition unten links, Wert yPosition unten links);


beginFill() erstellt also eine Fläche mit folgenden Parametern (Farbwert, Alphawert). Der Alphawert stellt im Übrigen die Transparenz dar. 100 steht für nicht transparent, 0 für unsichtbar. Die Werte dazwischen logischerweise den Transparenzwert. 50 wäre also halbdurchsichtig.

Natürlich kann man die hier erstellte Fläche auch noch mit einer Linie umranden. Hierfür bietet uns Flash den Befehl lineStyle() an, welcher mit 3 Parametern - zum einen die Dicke der Linie, die Farbe und der Alphawert der Linie - eine Linie gemäß den Koordinaten von moveTo() und lineTo() erstellt.

onEnterFrame-Schleifen


Wie gesagt läuft Flash wie eine Filmrolle oder ein Film ab, nicht umsonst sagt man ja "Flashfilm". D.h. würden wir jetzt 10 Bilder erstellen und den Film testen würde der Film immer bis Bild 10 abspielen und dann wieder bei 1 anfangen usw. Der Film läuft also in einer Endlosschleife, wenn wir kein stop() setzen.
Wir könnten jetzt durch unseren Loop eine Zahl hochzählen lassen, indem wir im ersten Bild eine Variable auf 0 setzen Code:
test=0;
und diese im Bild 10 um eins erhöhen Code:
test++;

Leider würden wir den Erfolg nicht sehen, da wir ja immer wieder bei Bild 1 anfangen, wo ja die Variable "test" wieder auf 0 gesetzt wird. Würden wir jetzt aber zusätzlich den Code auf Bild 10 so erweitern  
Code:
test++;
gotoAndPlay(2);

würde unser Experiment funktionieren, da unser Bildzeiger nicht mehr auf Bild 1, sondern gleich auf Bild 2 springt und abspielt. Die Variable "test" würde sich also erhöhen und erhöhen und erhöhen usw.

Jetzt könnte man so ja nicht nur Zahlen hochzählen lassen. Man könnte ja auch Situationen überprüfen, die sich vielleicht während des Abspielens verändert haben. Vielleicht möchte man ja wissen, ob ein Bild schon vollständig geladen ist. Also könnte man doch obiges Beispiel nehmen und anstelle des Hochzählens einfach eine Abfrage erstellen, die den Ladestatus überprüft. Wenn das Bild dann komplett geladen ist, könnte man den Film ja dann anhalten, da man die eigentliche Schleife (Loop) ja nicht mehr braucht.
Da es aber ziemlich zeitaufwendig wäre, hier extra eine 10 Bilder lange Zeitleiste in einem MC zu erstellen, nur um solange eine Schleife zu durchlaufen, bis ein Ereignis eingetroffen ist, bietet uns Flash hier eine weitere Möglichkeit die, Actionscript von anderen Sprachen unterscheidet - die onEnterFrame-Schleife. Dazu folgendes Beispiel:

Code:
test = 0;
square.onEnterFrame = function()
{
   test++;
   trace(test);
   if(test == 100)
   {
      delete this.onEnterFrame;
   }
}

Hier würden wir also die Zeitleiste in unserem MC "square" (egal ob dynamisch oder manuell erstellt) mehr oder weniger zum steten Abspielen bewegen. Wir haben natürlich keine Bilder in der Zeitleiste definiert. Dadurch würde also lediglich das erste Bild (Frame) ständig abgerufen bzw. abgespielt. onEnterFrame könnte man also so übersetzten: "Wenn Bild betreten wird". Da hier das Bild aber ständig betreten wird, hört unsere Schleife erst dann auf, wenn wir sie löschen. Ein einfaches stop() geht hier nicht.

Code:
delete this.onEnterFrame;


Der Ordnung halber könnte man sich auch angewöhnen anstelle "this" gleich den Instanznamen des einleitenden mcs zu verwenden.

Code:
delete square.onEnterFrame;

Kurzum: Auch hier wird "test" hochgezählt. Wenn "test" 100 entspricht, wird die Schleife unterbrochen (gelöscht).  - Bis jetzt doch noch recht einfach und nachvollziehbar, oder?

LoadVars - Verbindung mit der Außenwelt


Die wichtigste Funktion in unserem Tutorial heute ist aber die Funktion "LoadVars"

Flash muss irgendwie mit der Außenwelt kommunizieren. Es müssen Daten geladen und Daten versendet werden. Hierfür bietet sich die loadVars-Klasse an, welche uns Flash ebenfalls als Bordmittel zur Verfügung stellt. Wie bei jeder  Klasse müssen wir eine Instanz mit "new" erzeugen weisen diese der Variablen "lv" zu, zum Beispiel so:

Code:
lv = new LoadVars();
lv.onLoad = function(ok)
{
   if(ok)
   {
       daten=this.daten.split("|");
   }
}
lv.sendAndLoad("meine.php",lv,"POST");

Ich denke, der Aufbau erinnert euch an alle anderen Klassenaufrufe anderer Programmiersprachen und muss daher nicht näher erläutert werden. Lediglich sendAndLoad() dient als weitere Flashfunktion, die mit den Parametern für die Zieldatei, die Klasseninstanz und die Art des Versandes (POST oder GET) verwendet wird. this.daten fängt die Werte von unserer Quelle vergebenen Variable ab, sofern diese "daten" heißt. (In PHP etwa: echo "&daten=Wert1 2 3 4 5 6 ")

Soweit die allgemeine Einführung. Für tiefergehendes Wissen bitte ich euch entsprechende Fachliteratur zu erwerben. - Nun gehen wir zur Praxis über.

AS in der Praxis


Da es hier eigentlich um AS geht und ich davon ausgehe, dass ihr PHP schon entsprechend beherrscht, werde ich auf den PHP-Teil nicht eingehen, sondern diesen lediglich zum Kopieren darstellen.

Das PHP-Script zur Galerie

Das folgende PHP-Script sollte als Datei "galout.php" gespeichert werden. Außerdem sollte ein Verzeichnis mit dem Namen "gallery" bereitgestellt werden. In das Verzeichnis "gallery" könnt ihr später per FTP eure Verzeichnisse mit Bildern verschieben, wobei die Namen dieser Unterverzeichnisse dann den Linknamen entsprechen.

Code:
<?php
$type = array("jpg", "JPG", "PNG", "png", "gif", "bmp");

$ordnerCheck = opendir("gallery");
while($dirs = readdir($ordnerCheck))
{
   if($dirs != "."  &&  $dirs != "..")
   {  $dir_array[] .= $dirs;  }
}

if(isset($_POST['chosen']))
{ $dir = $_POST['chosen']; }
else
{ $dir = $dir_array[0];    }

$piccheck = opendir("gallery/".$dir);
while($pic = readdir($piccheck))
{
   if($pic != "."  &&  $pic != "..")
   {
      $typefinder = explode(".", $pic);
      for($i=0; $i<count($type); $i++)
      {
         if($typefinder[1] == $type[$i])
         {  $pictures[] .= "gallery/".$dir."/".$pic; }
      }
   }
}

echo "&dirs=".implode("|", $dir_array);
echo "&pics=".implode("|", $pictures);
?>

Ich merke hier lediglich kurz an, dass die echo-Ausgabe der Datenübergabe dient, da Flash alle Strings, denen ein  kaufmännisches "&" Zeichen vorangestellt ist, bis zum = Zeichen als Variablenbezeichner erkennt. Der String nach dem Gleichzeichen wird dann als Wert der Variablen verarbeitet. Wichtig hierbei:

Flash arbeitet wie andere Sprachen auch mit Arrays. Dennoch müssen Arrays von anderen Sprachen vor der Übergabe zunächst in einen String umgewandelt werden. Trennzeichen wie die Pipe "|" oder "~" bieten sich hierfür an.

Die Erklärung der Notwendigkeit von $_POST['chosen'] erfolgt im AS Part.

Der Aufbau des Flash/AS in kurzen Worten


Wählt zunächst eine Filmgröße von 800 auf 600 Pixel und die Hintergrundfarbe Schwarz (000000).
Es soll nun eine Flashgalerie erstellt werden, die wie folgt aufgebaut ist:

a) links oben die Navigation der Bilderkategorien
b) links darunter die Thumbnailliste
c) rechts oben das eigentliche Hauptbild

Außerdem soll ein schöner Bildwechsel durch Verringern und Erhöhen des Alphawerts erfolgen.

Der Preloader soll aus kleinen Rechtecken bestehen, welche ähnlich einer Lichtspielorgel nacheinander ein- und wieder ausfaden sollen. - Soweit der Plan.

Der Scriptaufbau

Wie auch in anderen Programmiersprachen empfiehlt es sich hier, soviel wie möglich in Funktionen zu packen, da man diese dann immer wieder aufrufen kann. Beachte: Flash kann im übrigen Funktionen schon am Anfang eines Scriptes verwenden, obwohl die eigentliche Funktion erst am Ende des Scriptes definiert wurde.

Zunächst legen wir ein paar Parameter fest, mit denen unser Flash zu arbeiten hat. Da wir diese im Laufe der Zeit vielleicht anpassen oder ändern wollen, stellen wir diese an den Anfang des Scriptes, um dann später nicht suchen zu müssen.
Wie auch bei JS oder PHP können Kommentare bis zum Zeilenende per // eingeleitet werden. Mit Sternklammern /* schließt man auch mehrzeiligen Text * / in einen Kommentarblock ein:

Code:
//Parameter zum Einstellen
rows = 3;                 // Wieviele Reihen
weite = 120;              // Thumbnailbreite
abstand = 2;              // Abstand zwischen den Thumbs
vAbstand = 10;            // Abstand von oben
loaderboxes = 10;         // Anzahl der Preloaderblinkboxen
loaderboxes_abstand = 2;  // Abstand zwischen den Preloaderblinkboxen
loaderboxhoehe = 20;      // Höhe der Preloaderblinkboxen
loaderboxweite = 10;      // Breite der Preloaderblinkboxen
rahmenbreite = 10;        // Breite des Rahmens um das Hauptbild
pfad = "";                // Wenn du es offline testen willst dann pfad="http://deineseite.de/";
php = "galout.php";


//Aus obigem resultierende Dimensionen
thm_weite = (weite + abstand)*rows;
mainpicweite = Stage.width - thm_weite - vAbstand;
picx = thm_weite;
startBild = 0;
createEmptyMovieClip("framer", 8);
createEmptyMovieClip("thframer", 16);

Ich denke, das erklärt sich von selbst. Kurzum funktioniert unsere Galerie so, dass sie aus den von uns definierten Parametern alle Elemente selbstständig passend anordnet, selbst wenn man eine andere Filmgröße wählt. Natürlich auch nur bis zu einem bestimmten Grad. Ihr werdet es verstehen, wenn ihr euch den Rest des Scriptes angesehen habt.

Jetzt folgt die Funktion der Preloaderanimation (Ein- und Ausfaden der Rechtecke, die später erstellt werden):

Code:
//Preloader Kaestchenfadeoutprototyp
MovieClip.prototype.blink = function(fadestart, MC)
{
   this._alpha = fadestart;
   this.up = true;
   this.onEnterFrame = function()
   {
      if (this.up)
      {
         this._alpha += 10;
         if (this._alpha >= 100)
         { this.up = false; }
      }
      else
      { this._alpha -= 10; }
      
      if (this._alpha <= 0)
      {
         delete this.onEnterFrame;
         if(this == 2){ removeMovieClip(this); }
        
         this.up = true;
      }
   };
};

Im Prinzip kann man fast alle AS-Befehle "wörtlich übersetzen". Wie ihr seht, unterscheidet dieser Block sich kaum von anderen Programmiersprachen. Lediglich einzelne Dinge wie beispielsweise die MovieClip.prototype Einleitung sind einzigartig. Tatsächlich dient das Ganze aber der Vereinfachung. Denn:
Später werden wir für jedes Kästchen im Preloader einen eigenen MC erstellen. Jeder dieser MCs müsste obige Funktion beinhalten und ausführen. Bevor wir jetzt aber jedem MC eine eigene Funktion in die Timeline schreiben, verwenden wir doch lieber die Prototypeklasse, um mit ihr diese Funktion mehr oder weniger an den jeweiligen MC anzuhängen. So können wir die Funktion dann für jeden einzelnen MC aufrufen. Und das nur, indem wir die Funktion mit dem Instanznamen des MCs einleiten.

Seid mir nicht böse, dass ich nicht noch näher darauf eingehe, aber ich bin jetzt schon bei Seite 13 und wir haben gerade mal den Anfang des Galeriescriptes. Dieses Tut richtet sich ja auch an erfahrenere Programmierer, die sicher etwas mit Aufbau und Sinn des Ganzen etwas anfangen können.

Also bitte lest euch den Code auch aufmerksam durch und ihr werdet sehen (und vor allem lernen), wie einfach AS zu verstehen ist. Weiter im Text ;)

Code:
//Preloader erstellen (Reservierte Ebene = 1006)
build_loader = function ()
{
   createEmptyMovieClip("loader",1006);
   for (i=0; i<loaderboxes; i++)
   {
      loader.createEmptyMovieClip("box"+i,i);
      loader['box'+i].beginFill(0xFFFFFF,100);
      loader['box'+i].moveTo(0,0);
      loader['box'+i].lineTo(0,0);
      loader['box'+i].lineTo(0+loaderboxweite,0);
      loader['box'+i].lineTo(0+loaderboxweite,0+loaderboxhoehe);
      loader['box'+i].lineTo(0,0+loaderboxhoehe);
      loader['box'+i]._x = loader['box'+(i-1)]._x+loader['box'+(i-1)]._width+loaderboxes_abstand;
      loader['box'+i]._alpha = 0;
   }
   loader._x = 70;            //(Stage.width/2)-(loader._width/2);
   loader._y = (Stage.height/2) - (loader._height/2);
   createTextField("txt", 1007, 0, 0, 0, 0);
   textform = new TextFormat();
   txt.autoSize = true;
   with(textform)
   {
      font  = "arial";
      bold  = true;
      color = "0xFFFFFF";
      size  = 14;
      bold  = true;
   }
   txt._x = loader._x + ((loader._width/2) - (txt._width/2));
   txt._y = loader._y + loader._height;
   txt.setTextFormat(textform);
   prestarter = 0;
   movieclip = 0;  
   loader.onEnterFrame = function()
   {
      loader['box'+movieclip].blink(1,1);
      prestarter++;
      
      if(prestarter >= loaderboxes)
      {
         prestarter = 0;
         movieclip++;
      }
      if(movieclip == loaderboxes) { movieclip = 0; }
   }
};


Hier erstellen wir nun also unseren berühmten Preloader und positionieren ihn. Ist euch der neue Befehl aufgefallen?
Code:
createTextField("txt",1007,0,0,0,0);


Mit dieser Klasse erstellen wir ähnlich createEmptyMovieClip() ein Textobjekt, welches uns später dann den prozentualen Wert des Ladefortschrittes wiedergeben soll. createTextField() wird mit folgenden Parametern erstellt: Textfeldnamen, Level, X Position, Y Position, Breite, Höhe.
Die Werte für die X und Y Position sind auf 0 gesetzt, da wir das ganze Objekt an den eigentlichen Preloader anhängen. So wird auch die Position mitvergeben. Die Breite und Höhe setzen wir ebenfalls auf 0, da wir hier die  Eigenschaft "autoSize" auf "true" setzen, wodurch sich unser Textobjekt an Textlänge und Fonthöhe anpasst. - Spielt einfach etwas mit den  Textformparametern herum.

Nun zum Herzstück, dem Holen und Verarbeiten der Daten:

Code:
//Daten laden
loadData = function(category)
{
   loDat = new LoadVars();
   loDat.onLoad = function(loaded)
   {
      if(loaded)
      {
         dirs = this.dirs.split("|");
         build_links();
         pics = this.pics.split("|");
         create_thumbs(pics);
         firstpic = pics[0];
         loadMainPic(firstpic);
      }
   }
   if(category != "")
   {
      loDat.chosen = category;
   }
   loDat.sendAndLoad(pfad+php, loDat, "POST");
}

Hier also seht ihr den Sinn hinter $_POST['chosen] im obigen PHP Teil. Die Variable wird anhand der durch die  Kategoriewahl erstellten Werte erstellt und an unser PHP-Script versandt. Der Befehl split() ist dem in PHP ähnlich und bedarf daher keiner näheren Erläuterung. Er splittet den String lediglich in ein Array auf.

Nun wird das Hauptbild geladen. Außerdem wird dahinter ein weißes Rechteck etwas größer als die Bildgröße aufgezogen, um den Effekt eines schönen weißen Rahmens zu erzeugen.
Code:
//Hauptbild laden  
loadMainPic = function(bild)
{
   if(startBild == 0)
   {
      createEmptyMovieClip("Pic0", 1004);
      mainpic = Pic0;
   }
   else
   {
      createEmptyMovieClip("Pic1", 1005);
      mainpic = Pic1;
   }
        
   mainpic.createEmptyMovieClip("pertou", 0);
   mainpic.createEmptyMovieClip("picture", 1);
   pertou = mainpic.pertou;
   picture = mainpic.picture;
   picture.loadMovie(pfad+bild);
   mainpic._alpha = 0;
  
   mainpic.onEnterFrame = function()
   {
      prz = Math.round(100/picture.getBytesTotal()*picture.getBytesLoaded());
      if(prz==100 && picture._width>1)
      {
         delete mainpic.onEnterFrame;
         if(startBild == 0)
         {
            Pic1.blink(100, 2);
            startBild = 1;
         }
         else
         {
            Pic0.blink(100, 2);
            startBild = 0;
         }
         scale = 100/picture._width*(mainpicweite - (rahmenbreite*2));
        
         picture._xscale = scale;
         picture._yscale = scale;
         picture._x = picx + rahmenbreite;
         picture._y = vAbstand + rahmenbreite;
        
         pertou.beginFill(0xFFFFFF,100);
         pertou.moveTo(picx,vAbstand);
         pertou.lineTo(picx,vAbstand);
         pertou.lineTo(picx + mainpicweite, vAbstand);
         pertou.lineTo(picx + mainpicweite, vAbstand+picture._height + (rahmenbreite*2));
         pertou.lineTo(picx, vAbstand+picture._height + (rahmenbreite*2));
        
         framer.onEnterFrame=function()
         {
            mainpic._alpha += 10;
            if(mainpic._alpha >= 100){ delete framer.onEnterFrame; }
         }
      }
   }
}  


Dann noch eine Funktion, die unsere Buttons erstellt und entsprechend anordnet:

Code:
//Kategorieauswahl erstellen
build_links=function()
{
   createEmptyMovieClip("links", 9);
   linkForm = new TextFormat();
   with(linkForm)
   {
      font  = "Arial";
      align = "center";
      color = "0xFFFFFF";
      bold  = true;
      size  = 10;
   }
   for(a=0; a<dirs.length; a++)
   {
      links.createEmptyMovieClip("link"+a, a);
      links['link'+a].lineStyle(3, 0xFFFFFF, 100);
      links['link'+a].beginFill(0xFF0000, 100);
      links['link'+a].moveTo(0, 0);
      links['link'+a].lineTo(0, 0);
      links['link'+a].lineTo(20, 0);
      links['link'+a].lineTo(20, 120);
      links['link'+a].lineTo(0, 90);
      links['link'+a].endFill();
      links['link'+a].createTextField("txt", a, 2.5, 0, 20, 100);
      
      thisText = dirs[a].split("");
      
      for(u=0; u<thisText.length; u++)
      {
         links['link'+a].txt.text += thisText[u]+"\n";
      }
      links['link'+a].txt.setTextFormat(linkForm);
      links['link'+a]._x = links['link'+(a-1)]._x + links['link'+(a-1)]._width;
      
      clicker = links['link'+a];
      clicker.id = a;
      clicker.onRollOver = function(){ links['link'+this.id]._alpha=30;  }
      clicker.onRollOut = function() { links['link'+this.id]._alpha=100; }
      clicker.onRelease = function() { loadData(dirs[this.id]); }
   }
   links._x = 0;
   links._y = 0;  
}


Schließlich folgt noch der Thumbsmoduloaufbau gefolgt vom ersten Funktionsaufruf:

Code:
//Thumbs erstellen
create_thumbs=function(bilder)
{
   starter = 0;
   createEmptyMovieClip("maske", 19);
   createEmptyMovieClip("thmb_holder", 13);
   maske.beginFill(0xFFFFFF, 100);
   maske.moveTo(0, links._y + links._height);
   maske.lineTo(0, links._y + links._height);
   maske.lineTo(picx - abstand, links._height);
   maske.lineTo(picx - abstand, Stage.height - vAbstand);
   maske.lineTo(0, Stage.height - vAbstand);
   maske.endFill();

   maske._alpha = 0;
   for(i=0; i<bilder.length; i++)
   {
      thmb_holder.createEmptyMovieClip("boarder"+i, i);
      thmb_holder.createEmptyMovieClip("thmb"+i, (i+bilder.length));
      thmb_holder['thmb'+i].loadMovie(pfad+bilder[i]);
      thmb_holder._alpha = 0;
   }
  
   build_loader();
   thframer.onEnterFrame = function()
   {
      dprz = Math.round(100/thmb_holder['thmb'+starter].getBytesTotal() * thmb_holder['thmb'+starter].getBytesLoaded());
      pr = Math.round(100/bilder.length*starter);
      
      txt.text = "Lade Thumbnails " + pr + "%";
      txt.setTextFormat(textform);
        
      if(dprz == 100  &&  thmb_holder['thmb'+starter]._width > 1)
      {
         starter++;
         if(starter == bilder.length)
         {
            delete thframer.onEnterFrame;
            
            loader.blink(100, 2);
            txt.removeTextField();
            th_max = 10;
            for(z=0; z<bilder.length; z++)
            {
               thmbscal = 100/thmb_holder['thmb'+z]._width * (weite-(abstand*2));
              
               thmb_holder['thmb'+z]._xscale = thmbscal;
               thmb_holder['thmb'+z]._yscale = thmbscal;
               thmb_holder['boarder'+z].beginFill(0xFFFFFF,100);
               thmb_holder['boarder'+z].moveTo(0,0);
               thmb_holder['boarder'+z].lineTo(0,0);
               thmb_holder['boarder'+z].lineTo(weite,0);
               thmb_holder['boarder'+z].lineTo(weite,(thmb_holder['thmb'+z]._height+(abstand*2)));
               thmb_holder['boarder'+z].lineTo(0,(thmb_holder['thmb'+z]._height+(abstand*2)));
               thmb_holder['boarder'+z].endFill();
              
               clickme = thmb_holder['thmb'+z];
               clickme.id = z;
              
               clickme.onRollOver = function()
               {
                  thmb_holder['thmb'+this.id]._alpha = 30;
               }
               clickme.onRollOut = function()
               {
                  thmb_holder['thmb'+this.id]._alpha = 100;
               }
               clickme.onRelease = function()
               {
                  delete _root.onEnterFrame;
                  delete framer.onEnterFrame;
                  delete loader.onEnterFrame;
                  delete thframer.onEnterFrame;
                  
                  loadMainPic(bilder[this.id]);
               }
              
               if(thmb_holder['thmb'+z]._height > th_max)
               { th_max = thmb_holder['thmb'+z]._height; }
            }
            
            //Modulo
            folge = 0;
            for(h=0; h<(Math.round(bilder.length/rows)); h++)
            {
               for(v=0; v<rows; v++)
               {
                  thmb_holder['boarder'+folge]._x = (weite + abstand)*v;
                  thmb_holder['boarder'+folge]._y = (th_max + abstand)*h;
                  thmb_holder['thmb'+folge]._x = thmb_holder['boarder'+folge]._x + (abstand);
                  thmb_holder['thmb'+folge]._y = thmb_holder['boarder'+folge]._y + (abstand);
                  folge++;
               }
            }
            //Moduloende
            
            thmb_holder._x = maske._x;
            thmb_holder._y = links._height;
            thmb_holder.setMask(maske);
            thmb_holder._alpha = 100;
            
            _root.onMouseMove=function()
            {
               if(thmb_holder.hitTest(_root._xmouse,_root._ymouse,true))
               {
                  div = thmb_holder._height - (maske._height);
                  pos = Math.round(100/(maske._height-50)*(maske._ymouse - links._height));
                  newPos = (div/100*pos) - links._height;
                  if(div > 0)
                  {
                     tween = new mx.transitions.Tween(thmb_holder, "_y", mx.transitions.easing.Regular.easeOut, thmb_holder._y, -newPos,3, true);
                  }
               }
            }
         }
      }
   }
}

// === Einstieg ===
loadData("");  


Für kleine Befehle wie setMask() o.ä. bitte ich euch, die Flashhilfe (F1) zu verwenden.

Ich hoffe, das Ganze war aufschlussreich für euch und hat euch gezeigt, dass Actionscript nicht anders als andere Sprachen ist, sondern eher weiträumiger. Desweiteren bitte ich euch um Verzeihung, dass der erste Teil dieses Tutorials ausführlicher war als der eigentliche Scriptaufbau, welcher ja nur minimal bis gar nicht erklärt wurde. Aber dieses Tutorial wurde doch umfangreicher, als ich am Anfang dachte. Ich denke dennoch, dass euch dieses Tutorial hilft, in die Welt des AS einzusteigen.

Hier nochmal der ganze AS Code zum Kopieren:

Code:
//Parameter zum Einstellen
rows = 3;                    // Wieviele Reihen
weite = 120;                 // Thumbnailbreite
abstand = 2;                 // Abstand zwischen den Thumbs
vAbstand=10;                 // Abstand von oben
loaderboxes = 10;            // Anzahl der Preloaderblinkboxen
loaderboxes_abstand = 2;     // Abstand zwischen den Preloaderblinkboxen
loaderboxhoehe = 20;         // Höhe der Preloaderblinkboxen
loaderboxweite = 10;         // Breite der Preloaderblinkboxen
rahmenbreite = 10;           // Breite des Rahmens um das Hauptbild
pfad = "";                   // Wenn du es offline testen willst dann pfad="http://deineseite.de/";
php = "galout.php";


//Aus obigem resultierende Dimensionen
thm_weite = (weite + abstand) * rows;
mainpicweite = Stage.width - thm_weite - vAbstand;
picx = thm_weite;
startBild = 0;

createEmptyMovieClip("framer", 8);
createEmptyMovieClip("thframer", 16);

//Preloader Kaestchenfadeoutprototyp
MovieClip.prototype.blink = function(fadestart,MC)
{
   this._alpha = fadestart;
   this.up = true;
   this.onEnterFrame = function()
   {
      if (this.up)
      {
         this._alpha += 10;
         if (this._alpha >= 100)
         {
            this.up = false;
         }
      }
      else
      {
         this._alpha -= 10;
      }
      
      if (this._alpha <= 0)
      {
         delete this.onEnterFrame;
         if(this == 2) { removeMovieClip(this); }
        
         this.up = true;
      }
   };
};


//Preloader erstellen (Reservierte Ebene = 1006)
build_loader = function ()
{
   createEmptyMovieClip("loader", 1006);
   for (i=0; i<loaderboxes; i++)
   {
      loader.createEmptyMovieClip("box"+i,i);
      loader['box'+i].beginFill(0xFFFFFF,100);
      loader['box'+i].moveTo(0,0);
      loader['box'+i].lineTo(0,0);
      loader['box'+i].lineTo(0 + loaderboxweite, 0);
      loader['box'+i].lineTo(0 + loaderboxweite, 0 + loaderboxhoehe);
      loader['box'+i].lineTo(0, 0 + loaderboxhoehe);
      loader['box'+i]._x = loader['box'+(i-1)]._x+loader['box'+(i-1)]._width + loaderboxes_abstand;
      loader['box'+i]._alpha = 0;
   }
   loader._x = 70;               // (Stage.width/2) - (loader._width/2);
   loader._y = (Stage.height/2) - (loader._height/2);
   createTextField("txt", 1007, 0, 0, 0, 0);
   textform = new TextFormat();
   txt.autoSize = true;
   with(textform)
   {
      font  = "arial";
      bold  = true;
      color = "0xFFFFFF";
      size  = 14;
      bold  = true;
   }
   txt._x = loader._x + ((loader._width/2) - (txt._width/2));
   txt._y = loader._y + loader._height;
   txt.setTextFormat(textform);
  
   prestarter = 0;
   movieclip = 0;  
  
   loader.onEnterFrame = function()
   {
      loader['box'+movieclip].blink(1,1);
      prestarter++;
      
      if(prestarter >= loaderboxes)
      {
         prestarter = 0;
         movieclip++;
      }
      if(movieclip == loaderboxes) { movieclip = 0; }
   }
};
  
//Daten laden
loadData = function(category)
{
   loDat = new LoadVars();
   loDat.onLoad = function(loaded)
   {
      if(loaded)
      {
         dirs = this.dirs.split("|");
         build_links();
         pics = this.pics.split("|");
         create_thumbs(pics);
         firstpic = pics[0];
         loadMainPic(firstpic);
      }
   }
   if(category!="")
   {
      loDat.chosen = category;
   }
   loDat.sendAndLoad(pfad+php,loDat,"POST");
}

//Hauptbild laden  
loadMainPic = function(bild)
{
   if(startBild == 0)
   {
      createEmptyMovieClip("Pic0", 1004);
      mainpic = Pic0;
   }
   else
   {
      createEmptyMovieClip("Pic1", 1005);
      mainpic = Pic1;
   }
  
   mainpic.createEmptyMovieClip("pertou", 0);
   mainpic.createEmptyMovieClip("picture", 1);
  
   pertou = mainpic.pertou;
   picture = mainpic.picture;
   picture.loadMovie(pfad+bild);
   mainpic._alpha = 0;
  
   mainpic.onEnterFrame = function()
   {
      prz = Math.round(100/picture.getBytesTotal() * picture.getBytesLoaded());
      if(prz==100 && picture._width>1)
      {
         delete mainpic.onEnterFrame;
         if(startBild == 0)
         {
            Pic1.blink(100,2);
            startBild = 1;
         }
         else
         {
            Pic0.blink(100,2);
            startBild = 0;
         }
        
         scale = 100/picture._width * (mainpicweite - (rahmenbreite*2));
         picture._xscale = scale;
         picture._yscale = scale;
         picture._x = picx + rahmenbreite;
         picture._y = vAbstand + rahmenbreite;
        
         pertou.beginFill(0xFFFFFF, 100);
         pertou.moveTo(picx, vAbstand);
         pertou.lineTo(picx, vAbstand);
         pertou.lineTo(picx + mainpicweite, vAbstand);
         pertou.lineTo(picx + mainpicweite, vAbstand + picture._height + (rahmenbreite*2));
         pertou.lineTo(picx, vAbstand + picture._height + (rahmenbreite*2));
        
         framer.onEnterFrame = function()
         {
            mainpic._alpha += 10;
            if(mainpic._alpha >= 100) { delete framer.onEnterFrame; }
         }
      }
   }
}

//Kategorieauswahl erstellen
build_links = function()
{
   createEmptyMovieClip("links", 9);
   linkForm = new TextFormat();
   with(linkForm)
   {
      font =  "Arial";
      align = "center";
      color = "0xFFFFFF";
      bold =  true;
      size =  10;
   }
   for(a=0;a<dirs.length;a++)
   {
      links.createEmptyMovieClip("link"+a,a);
      links['link'+a].lineStyle(3,0xFFFFFF,100);
      links['link'+a].beginFill(0xFF0000,100);
      links['link'+a].moveTo(0,0);
      links['link'+a].lineTo(0,0);
      links['link'+a].lineTo(20,0);
      links['link'+a].lineTo(20,120);
      links['link'+a].lineTo(0,+90);
      links['link'+a].endFill();
      links['link'+a].createTextField("txt",a,2.5,0,20,100);
      
      thisText = dirs[a].split("");
      for(u=0; u<thisText.length; u++)
      {
         links['link'+a].txt.text+=thisText[u]+"\n";
      }
      links['link'+a].txt.setTextFormat(linkForm);
      links['link'+a]._x = links['link'+(a-1)]._x + links['link'+(a-1)]._width;
      
      clicker = links['link'+a];
      clicker.id = a;
      clicker.onRollOver = function() { links['link'+this.id]._alpha =  30; }
      clicker.onRollOut  = function() { links['link'+this.id]._alpha = 100; }
      clicker.onRelease  = function() { loadData(dirs[this.id]); }
   }
  
   links._x = 0;
   links._y = 0;  
}
      
//Thumbs erstellen
create_thumbs = function(bilder)
{
   starter = 0;
  
   createEmptyMovieClip("maske", 19);
   createEmptyMovieClip("thmb_holder", 13);
  
   maske.beginFill(0xFFFFFF, 100);
   maske.moveTo(0, links._y + links._height);
   maske.lineTo(0, links._y + links._height);
   maske.lineTo(picx - abstand, links._height);
   maske.lineTo(picx - abstand, Stage.height - vAbstand);
   maske.lineTo(0, Stage.height - vAbstand);
   maske.endFill();
   maske._alpha = 0;

   for(i=0; i<bilder.length; i++)
   {
      thmb_holder.createEmptyMovieClip("boarder"+i,i);
      thmb_holder.createEmptyMovieClip("thmb"+i,(i+bilder.length));
      thmb_holder['thmb'+i].loadMovie(pfad+bilder[i]);
      thmb_holder._alpha = 0;
   }
  
   build_loader();
   thframer.onEnterFrame = function()
   {
      dprz = Math.round(100/thmb_holder['thmb'+starter].getBytesTotal() * thmb_holder['thmb'+starter].getBytesLoaded());
      pr = Math.round(100/bilder.length * starter);
      
      txt.text = "Lade Thumbnails " + pr + "%";
      txt.setTextFormat(textform);
        
      if(dprz == 100  &&  thmb_holder['thmb'+starter]._width > 1)
      {
         starter++;
         if(starter == bilder.length)
         {
            delete thframer.onEnterFrame;
        
            loader.blink(100, 2);
            txt.removeTextField();
            th_max = 10;
            for(z=0; z<bilder.length; z++)
            {
               thmbscal = 100/thmb_holder['thmb'+z]._width * (weite-(abstand*2));
              
               thmb_holder['thmb'+z]._xscale = thmbscal;
               thmb_holder['thmb'+z]._yscale = thmbscal;
              
               thmb_holder['boarder'+z].beginFill(0xFFFFFF,100);
               thmb_holder['boarder'+z].moveTo(0,0);
               thmb_holder['boarder'+z].lineTo(0,0);
               thmb_holder['boarder'+z].lineTo(weite,0);
               thmb_holder['boarder'+z].lineTo(weite,(thmb_holder['thmb'+z]._height+(abstand*2)));
               thmb_holder['boarder'+z].lineTo(0,(thmb_holder['thmb'+z]._height+(abstand*2)));
               thmb_holder['boarder'+z].endFill();
              
               clickme = thmb_holder['thmb'+z];
               clickme.id = z;
               clickme.onRollOver = function()
               {
                  thmb_holder['thmb'+this.id]._alpha = 30;
               }
               clickme.onRollOut = function()
               {
                  thmb_holder['thmb'+this.id]._alpha = 100;
               }
               clickme.onRelease = function()
               {
                  delete _root.onEnterFrame;
                  delete framer.onEnterFrame;
                  delete loader.onEnterFrame;
                  delete thframer.onEnterFrame;
                  loadMainPic(bilder[this.id]);
               }
               if(thmb_holder['thmb'+z]._height > th_max)
               { th_max = thmb_holder['thmb'+z]._height; }
            }
            
            //Modulo
            folge=0;
            for(h=0; h<(Math.round(bilder.length/rows)); h++)
            {
               for(v=0; v<rows; v++)
               {
                  thmb_holder['boarder'+folge]._x = (weite+abstand) * v;
                  thmb_holder['boarder'+folge]._y = (th_max+abstand) * h;
                  thmb_holder['thmb'+folge]._x = thmb_holder['boarder'+folge]._x + (abstand);
                  thmb_holder['thmb'+folge]._y = thmb_holder['boarder'+folge]._y + (abstand);
                  folge++;
               }
            }
            //Moduloende
            
            thmb_holder._x = maske._x;
            thmb_holder._y = links._height;
            thmb_holder.setMask(maske);
            thmb_holder._alpha = 100;
            
            _root.onMouseMove = function()
            {
               if(thmb_holder.hitTest(_root._xmouse,_root._ymouse,true))
               {
                  div = thmb_holder._height - (maske._height);
                  pos = Math.round(100/(maske._height-50) * (maske._ymouse-links._height));
                  newPos = (div/100*pos) - links._height;
                  if(div>0)
                  {
                     tween = new mx.transitions.Tween(thmb_holder, "_y", mx.transitions.easing.Regular.easeOut, thmb_holder._y, -newPos, 3, true);
                  }
               }
            }
         }
      }
   }
}
  

// === Einstieg ===
loadData("");


Viel Spaß ;)

>> Allgemeine Fragen oder Probleme mit dem Tutorial? Hier gehts zum Forum!

Impressum / Datenschutzerklärung          © der-Webdesigner.net 2002 - 2011           top ▲