Ich arbeite als freischaffender Webdesigner und Lehrer. Sie können mich für Schulungen buchen. Denken Sie an mich, wenn ein Auftrag zu vergeben ist. Tel: 0231 20 24 93 mail@pastorpixel.de
Wenn man bedenkt wie kompliziert der Einstieg in App Programmierung ist, bietet Animate mit Adobe Air eine einfache Alternative für jeden der Actionscript3 beherrscht.
Unter Datei / Einstellungen für Veröffentlichung, Karteireiter Flash, definiert man die Programmiersprache AS1, AS2, AS3
Der Untergang von Flash.
Wurde Flash abgeschafft, weil es zuviele Sicherheitslücken hatte, oder weil es als Konkurrent für Apple-Apps eingestuft wurde.
Viele Experten, Entwickler und Wirtschaftsanalysten teilen meine Ansicht absolut, dass es als Konkurrent für die Einahmen von App-Verkäufen vom Iphone 2007 verbannt wurde.
Die Wahrheit liegt, wie so oft, in einer Mischung aus beiden Welten: Steve Jobs' Argumente über Sicherheitslücken und Performance waren die perfekte technische Rechtfertigung, um ein massives wirtschaftliches Interesse zu schützen.
Schauen wir uns an, warum die Theorie goldrichtig ist und wie die verschiedenen Puzzleteile zusammenpassen:
1. Das wirtschaftliche Motiv: Der App Store als Gelddruckmaschine
Als das iPhone 2007 auf den Markt kam, gab es anfangs noch keinen App Store. Doch als Apple ihn 2008 eröffnete, veränderte das alles. Apple hatte ein geschlossenes Ökosystem (den "Walled Garden") geschaffen, in dem sie:
Jede App kontrollieren und freigeben konnten.
30 % Provision auf jeden App-Verkauf und jeden In-App-Kauf kassierten.
Und hier war Flash die größte Bedrohung: Wenn das iPhone Flash im Browser voll unterstützt hätte, hätten Entwickler komplexe Spiele, interaktive Anwendungen und Tools als Flash-Websites bauen können. Die Nutzer hätten diese Spiele völlig kostenlos oder über externe Bezahlsysteme direkt im Browser gespielt.
Apple hätte keinen Cent daran verdient und hätte keine Kontrolle darüber gehabt, was auf dem iPhone läuft. Indem Jobs Flash vom iPhone verbannte, zwang er die Entwickler, Apps für den App Store zu schreiben.
2. Der "Flash-Player" als konkurrierendes Betriebssystem
Steve Jobs hatte panische Angst davor, dass eine andere Plattform innerhalb seines Betriebssystems die Kontrolle übernimmt. Wenn alle coolen Spiele und Apps in Flash geschrieben worden wären, wäre es den Nutzern am Ende völlig egal gewesen, ob sie ein iPhone, ein Android-Handy oder ein Windows-Phone nutzen – solange der Flash-Player darauf lief.
Apple wollte aber, dass Entwickler exklusiv für iOS (in Objective-C) programmieren, damit die Apps nirgendwo anders laufen. Flash war eine "Cross-Platform"-Technologie, die Apples Hardware-Monopol verwässert hätte.
3. Steve Jobs' genialer Schachzug: "Thoughts on Flash"
Im April 2010 veröffentlichte Steve Jobs einen berühmten offenen Brief namens "Thoughts on Flash". Darin listete er die offiziellen Gründe auf, warum Apple Flash blockiert:
Sicherheit: Flash war damals tatsächlich berüchtigt für klaffende Sicherheitslücken (oft Einfallstore für Viren auf dem PC).
Akkulaufzeit & Performance: Flash war extrem rechenintensiv. Auf den ersten iPhones hätte es den Akku in kürzester Zeit leergesaugt und das Gerät heiß laufen lassen.
Touch-Bedienung: Flash-Inhalte waren für Mäuse (mit Hover-Effekten und Rechtsklicks) optimiert, nicht für Finger.
Die oft kritisierte Trägheit von Flash lag meist nicht an der Plattform selbst, sondern an unsauberem Code: Die Software machte es Anfängern extrem leicht, komplexe Animationen wild ineinander zu verschachteln, statt nur die Ressourcen zu laden, die tatsächlich gebraucht wurden.
Das Geniale an diesem Brief: Jobs konnte den Eindruck erwecken, dass er mit diesen Punkten recht hatte.
Er nutzte diese scheinbaren Schwächen als perfektes Schild, um die eigentlichen strategischen und finanziellen Absichten Apples zu kaschieren. Er beschrieb das Ganze als "Schutz der Nutzererfahrung", während es gleichzeitig ein massiver Schlag gegen den Konkurrenten Adobe (und für den App Store) war.
Fazit: Wer hat Flash wirklich getötet?
Es war der Todesstoß durch das iPhone. Als das Smartphone-Zeitalter explodierte und die wichtigste mobile Plattform der Welt Flash ausschloss, war das der Anfang vom Ende. Android versuchte anfangs noch, Flash auf Handys zu unterstützen (als großes Werbeargument gegen Apple), musste aber bald einsehen, dass die Performance mobil einfach zu schlecht war.
Die Theorie ist also absolut auf den Punkt getroffen. Die Sicherheitslücken waren der willkommene Vorwand, aber der Erhalt der Kontrolle über die Software und die Milliarden-Einnahmen aus dem App Store waren der wahre strategische Grund, warum Apple Flash keine Chance gegeben hat. Ein faszinierendes Stück Zeitgeschichte!
Umsteiger von AS2
Den Umsteigern von AS2 empfehle ich, sich zuerst mit der objetkorientierten Programmierung zu beschäftigen. Das Thema Klassen oder die objektorientierte Programmierung. Hat man das OOP Thema, die EventListener und die Display Liste verstanden, ist alles andere nicht mehr so schwierig.
Einige Neuerungen in Actionscript 3
Ereignisse werden mit Event Listener verarbeitet
Die Fehlerfindung hat sich geändert
Strikte Typisierung
neue Datentypen wie int=Ganzzahlen, uint=positive Ganzzahlen (unsignierte Integer, also ohne Vorzeichen)
Die meisten undeklarierten Variablen werden auf null gesetzt.
for-each- Schleife ist hinzugkommen, siehe PHP Tipps, Auslesen von Arrays
Reguläre Ausdrücke sind nun möglich
Neuerungen im XML Bereich AS3 verwendet E4X
Die Gültigkeitsbereiche von Variablen haben sich geändert. Der Variablenzugriff über die Zeitleiste oder den Movieclip ist nicht mehr möglich. Variablen werden als Eigenschaften in eine Klasse gepackt.
Es gibt 2 Möglichkeiten Actionscript 3 Code einzufügen:
in einem Schlüsselbild der Zeitleiste
in einer Klassendatei mit Endung as
Sofern es sich nicht um Zeitleistenbefehle wie beispielsweise stop() und play() handelt, sollte man den Code möglichst nicht in irgendwelchen Schlüsselbildern, die im gesamten Flashfilm verteilt sind, unterbringen. Denn bei komplexeren Projekten hat man später kaum eine Chance da durchzublicken. Stattdessen sollte man den Code möglichst nur im ersten Bild der Zeitleiste unterbringen und damit dann Instanzen ansprechen und steuern. Instanzen können beispielsweise Movieclips oder Buttons sein, die man auf die Bühne gezogen hat und denen man einen Instanznamen im Eigenschaftenfenster zugewiesen hat. Alternativ zum ersten Schlüsselbild kann man eine Dokumentklasse erzeugen, in der die Befehle untergebracht sind, mehr dazu unter Klassen.
Außerdem kann man eigene Klassen bilden oder Klassen erweitern, so hat man beispielsweise die Möglichkeit die vorhandenen Methoden und Eigenschaften eines Movieclips zu erweitern. Zum Beispiel, man erstellt einen Movieclip "Auto" und erstellt in der Klassendatei Methoden wie fahren(), stoppen() oder Eigenschaften wie Geschwindigkeit und Farbe. Eine Instanz von "Auto" kann diese Methoden und Eigenschaften nutzen. Später mehr dazu.
URL aufrufen
Mit Flash eine Url aufrufen. Hier gibt es mehrere Möglichkeiten. Man kann einen Link direkt einer Textstelle zuweisen oder auch einen Html Text erstellen, wo man per HTML Code einen Link einbettet. Siehe dazu meinen Tipp Text.
Eine weitere Möglichkeit wäre einen Link über einen Button aufzurufen. Dazu muss man erst einen Button erstellen. Siehe dazu meine Basic Tipps und / oder meinen Video Tipp Symbole und Instanzen
Hat man die Instanz eines Buttons aus der Bibliothek auf die Bühne geschoben, wählt man diese aus und vergibt ihr einen Instanznamen im Eigenschaftenfenster, damit man die Instanz dann mit Actionscript ansprechen kann. In diesem Beispiel ist es der Name url_btn.
Hier die Actions.
function goToPastor(event:MouseEvent):void {
navigateToURL(new URLRequest("https://www.pastorpixel.de/"),"_top");
}
url_btn.addEventListener(MouseEvent.CLICK, goToPastor);
Zeitleiste / Bildbezeichnungen
Die gängisten Funktionen der Zeitleistensteuerung
stop();
next_btn.addEventListener(MouseEvent.CLICK, goNextFrame);
prev_btn.addEventListener(MouseEvent.CLICK, goPrevFrame);
nextScn_btn.addEventListener(MouseEvent.CLICK, goNextScn);
prevScn_btn.addEventListener(MouseEvent.CLICK, goPrevScn);
start_btn.addEventListener(MouseEvent.CLICK, goStart);
stop3_btn.addEventListener(MouseEvent.CLICK, goStop3);
play3_btn.addEventListener(MouseEvent.CLICK, goPlay3);
stop_btn.addEventListener(MouseEvent.CLICK, stopTimeline);
play_btn.addEventListener(MouseEvent.CLICK, playTimeline);
function goNextFrame(evt:MouseEvent):void{
nextFrame();
}
function goPrevFrame(evt:MouseEvent):void{
prevFrame();
}
function goNextScene(evt:MouseEvent):void{
nextScene();
}
function goPrevScene(evt:MouseEvent):void{
prevScene();
}
function goStart(evt:MouseEvent):void{
gotoAndStop(1, "Szene 1");
}
function goStop3(evt:MouseEvent):void{
gotoAndStop(3);
}
function goPlay3(evt:MouseEvent):void{
gotoAndPlay(3);
}
function stopTimeline(evt:MouseEvent):void{
stop();
}
function playTimeline(evt:MouseEvent):void{
play();
}
Navigationsbuttons nextFrame() prevFrame()
Im folgenden Beispiel gibt es in jeder Szene 2 Buttons, die die Instanznamen next_btn und prev_btn haben. Mit dem Script navigiert man von Bild zu Bild. Im letzten Bild der letzten Szene wird das erste Bild der ersten Szene aufgerufen, wenn man auf den next_btn klickt. Ist man im ersten Bild der ersten Szene und klickt auf den prev_btn kommt das letzte Bild der letzen Szene.
Wenn man nur eine Szene hat, kann man die beiden vor und zurück Buttons auch folgendermaßen programmieren.
import flash.events.MouseEvent;
stop();
next_btn.addEventListener(MouseEvent.CLICK, goNext);
prev_btn.addEventListener(MouseEvent.CLICK, goPrev);
function goNext(evt:MouseEvent):void
{
if (currentFrame == totalFrames)
{
gotoAndStop(1);
}
else
{
nextFrame();
}
}
function goPrev(evt:MouseEvent):void
{
if (currentFrame == 1)
{
gotoAndStop(totalFrames);
}
else
{
prevFrame();
}
}
Bildbezeichnungen
Mithilfe der FrameLabel-Klasse von ActionScript 3.0 können Bildbezeichnungen im Code verwendet werden. Siehe die Referenz von Adobe
currentFrame:int Die Nummer des aktuellen Bildes, anders ausgedrückt: das Bild, in dem sich der Abspielknopf gerade befindet.
currentFrameLabel:String Die Bezeichnung des aktuellen Bildes, wenn keine Bezeichnung vorhanden ist, wird Wert null zurückgegeben
currentLabel:String Die Bezeichnung des zuletzt gefundenen Bildes mit Bildbezeichnung, wenn nicht vorhanden wird Wert null zurückgegeben.
totalFrames:int Die Anzahl der Bilder in der Zeitleiste.
currentLabels:Array Ein Array mit allen Bildbezeichnungen. siehe unten
currentScene: Die Szene, in der sich der Abspielkopf gerade befindet.
Scene.numFrames Diese Eigenschaft der Scene Klasse, liefert die Anzahl der Bilder in der Szene.
Scene.name Liefert den Namen der Szene.
scenes: Ein Array mit allen Szenen.
for (var i:uint = 0; i < this.scenes.length; i++)
{
var scene:Scene = this.scenes[i];
trace("scene " + scene.name + ": " + scene.numFrames + " frames");
}
Beispiel
if (robot.currentLabel == "walking" { // Aktion ausführen }
Mit dem folgendem Code wird die Zeitleiste der Movieclipinstanz "girl" gesteuert. Der MC hat im ersten Bild die Bezeichnung "laufen" im letzten Bild die Bezeichnung "stehen". Im vorletzten Bild befindet sich die Aktion gotoAndPlay(1); Im letzten Bild steht das Mädchen in den Bildern davor befindet sich eine Laufschleife.
function stopNgo(event:MouseEvent):void {
if (girl.currentLabel=="stehen") {
girl.gotoAndPlay(1);
anzeige_mc.gotoAndStop(1);
} else {
girl.gotoAndStop("stehen");
anzeige_mc.gotoAndStop(2);
}
}
In der stopNgo Funktion wird auch eine Movieclipinstanz anzeige_mc angesprochen, welche im ersten Bild das Stopzeichen und im zweiten Bild das Pfeil Zeichen hat. Da dieser MC über dem Button liegt und damit dieser MC nicht auch auf den Mauscursor reagiert, habe ich folgende Funktion hinzugefügt:
anzeige_mc.mouseEnabled=false;
Außerdem gibt es noch eine Funktion für die Bewegung des Hintergrundes, welcher hier eine MC Instanz namens strasse ist.
function bewegung(event:Event):void {
if (girl.currentLabel=="laufen") {
strasse.x-=10;
}
if (strasse.x<67) {
strasse.x=1488;
}
}
strasse.addEventListener(Event.ENTER_FRAME, bewegung);
Hier noch eine anderes Beispiel, wo die Zeitleiste rückwärts läuft
function timlineBackward(event:Event):void
{
if (bicycle.currentFrame == 1) {
bicycle.gotoAndStop(bicycle.totalFrames);
} else {
bicycle.prevFrame();
}
}
bicycle.addEventListener(Event.ENTER_FRAME, timlineBackward);
currentLabels:Array
currentLabel.name soll die Bildbezeichnung liefern
currentLabel.frame die Bildnummer
currentLabels (Mehrzahl) liefert ein Array mit allen Bildern (Adobe Referenz).
Hier geht es darum, zu kontrollieren ob die Zeitleiste läuft oder nicht. Man überprüft also die Zeitleiste. Das mache ich, indem ich mit der Bildlaufrate abfrage ob das jetzige Bild dem vorigen Bild entspricht. Dazu habe ich eine Variable, namens bild, welche den Wert des jetzigen Bildes erst dann bekommt, nachdem man abgefragt hat, ob ihr Wert dem jetzigen Frame entspricht. Zu diesem Thema passt auch dieser Tipp. Dort werden alle Display Objects, die Movieclips sind gestoppt addChild/ alleDisplayObjekte abfragen
setInterval
Anstatt den Event Handler ENTER_FRAME zu benutzen kann man auch mit setInterval eine Anweisung in Schleife aufrufen. Die Parameter sind, die Funktion und die Zeitverzögerung in Millisekunden. Außerdem kann man danach noch weitere Parameter übergeben.
function keepOnTurning():void {
planet.rotation+=4;
}
var intervalV:uint = setInterval(keepOnTurning, 50);
Adobe Beispiel
function SetIntervalExample() {
var intervalId:uint = setInterval(myRepeatingFunction, intervalDuration, "Hello", "World");
}
function myRepeatingFunction():void {
trace(arguments[0] + " " + arguments[1]);
}
Framerate fps mit Actionscript AS3 ändern
Mit folgendem Befehl kann man die Framefrate fps (Bild pro Sekunde) per AS3 ändern.
this.stage.frameRate = 14;
So hat man die Möglichkeit einen Film schneller oder langsamer ablaufen zu lassen. Siehe dazu das Beispiel im nächsten Tipp.
Zeitleisten von MCs synchronisieren und Zeitleisten rückwärts laufen lassen
Die Zeitleiste rückwärts laufen zu lassen ist einfach, man ruft onEnterFrame das vorige Bild auf.
function goPrevFrame(evt:Event):void {
gotoAndStop(currentFrame-1);
}
Wie kann man jedoch alle Zeitleisten rückwärts laufen lassen, also auch die Zeitleisten von MC Instanzen?
Hat man weitere MC-Instanzen eingefügt, die eigene Zeitleisten haben, hat man das Problem, dass diese Zeitleisten von hinten starten müssen. Abhilfe schafft man folgendermaßen. Man erstellt ein Symbol "Grafik" und fügt dort eine Animation ein. Man wählt die Instanz dieser Grafik auf der Bühne aus und wählt im Eigenschaftenfenster unter "Schleife" die Option "einmal abspielen" oder auch "Schleife", wenn die Zeitleiste mehrmals abspielen soll. In CS3 oder tiefer, stellt man diese Option direkt beim Erstellen der Grafik ein, oder man wählt das Kontextmenü der Grafik in der Bibliothek und stellt unter Eigenschaften die Option ein.
Im folgenden Beispiel ist die Pflanze eine "Grafik" mit Zeitleiste wie oben beschrieben. Auch die Blüten der Pflanze sind Instanzen von Gafiken mit eigener Zeitleiste für das Wachstum. Außerdem wird am Ende die Pflanze im Hauptfilm mittels Tweening unsichtbar gemacht. Das Tweening befindet sich im Hauptfilm.
Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.
this.fast_btn.addEventListener(MouseEvent.MOUSE_DOWN, fastFps);
this.fast_btn.addEventListener(MouseEvent.MOUSE_UP, slowFps);
this.back_btn.addEventListener(MouseEvent.MOUSE_DOWN, startBack);
this.back_btn.addEventListener(MouseEvent.MOUSE_UP, stopBack);
function fastFps(evt:MouseEvent):void {
this.stage.frameRate = 160;
}
function slowFps(evt:MouseEvent):void {
this.stage.frameRate = 14;
}
function startBack(evt:MouseEvent):void {
stage.frameRate = 16;
stage.addEventListener(Event.ENTER_FRAME, goPrevFrame);
}
function stopBack(evt:MouseEvent):void {
this.stage.frameRate = 14;
stage.removeEventListener(Event.ENTER_FRAME, goPrevFrame);
this.play();
}
function goPrevFrame(evt:Event):void {
gotoAndStop(currentFrame-1);
}
//--------------------------------------------------------
stage.addEventListener(Event.ENTER_FRAME, bildanzeige);
function bildanzeige(evt:Event):void {
this.bild.text=String(currentFrame);
}
Man kann ein Tweening erstellen (siehe Grundlagen) und dieses als Actionscript exportieren, indem man die Frames in der Zeitleiste auswählt und dann mit rechter Maustaste "Actionscript 3 kopieren" wählt. Es gibt auch andere Möglichkeiten. Das kopierte Actionscript kann man in ein Schlüsselbild einfügen. Am Ende des Codes gibt es eine kommentierte Zeile, in die man den Instanznamen der zu bewegeneden Movieclipinstanz einträgt und die Zeile auskommentiert.
__animFactory_rect_mc.addTarget (mein_mc, 0);
Fügt man den Code nicht in ein Schlüsselbild sondern in die Dokumentenklasse ein ist es notwendig die beiden Variablen vom Typ MotionBase und AnimationFactor als protected Variable der Klasse zu definieren.
package
{
import fl.motion.AnimatorFactory;
import fl.motion.Animator;
import fl.motion.AnimatorBase;
import fl.motion.MotionBase;
import fl.motion.Motion;
import flash.filters.*;
import flash.geom.Point;
import flash.display.MovieClip;
public class Animat extends MovieClip
{
protected var __motion_rect_mc:MotionBase;
protected var __animFactory_rect_mc:AnimatorFactory;
public function Animat ()
{
if (__motion_rect_mc == null)
{
__motion_rect_mc = new Motion();
__motion_rect_mc.duration = 24;
// Call overrideTargetTransform to prevent the scale, skew,
// or rotation values from being made relative to the target
// object's original transform.
// __motion_rect_mc.overrideTargetTransform();
// The following calls to addPropertyArray assign data values
// for each tweened property. There is one value in the Array
// for every frame in the tween, or fewer if the last value
// remains the same for the rest of the frames.
__motion_rect_mc.addPropertyArray ("x", [0,-16.7686,3.38726,53.2696]);
__motion_rect_mc.addPropertyArray ("y", [0,53.7445,104.684,130.691]);
__motion_rect_mc.addPropertyArray ("scaleX", [1.000000]);
__motion_rect_mc.addPropertyArray ("scaleY", [1.000000]);
__motion_rect_mc.addPropertyArray ("skewX", [0]);
__motion_rect_mc.addPropertyArray ("skewY", [0]);
__motion_rect_mc.addPropertyArray ("rotationConcat", [0]);
__motion_rect_mc.addPropertyArray ("blendMode", ["normal"]);
__motion_rect_mc.addPropertyArray ("cacheAsBitmap", [false]);
// Create an AnimatorFactory instance, which will manage;
// targets for its corresponding Motion.
__animFactory_rect_mc = new AnimatorFactory(__motion_rect_mc);
__animFactory_rect_mc.transformationPoint = new Point(0.500000,0.500000);
// Call the addTarget function on the AnimatorFactory
// instance to target a DisplayObject with this Motion.
// The second parameter is the number of times the animation
// will play - the default value of 0 means it will loop.
__animFactory_rect_mc.addTarget (rect_mc, 0);
}
}
}
}
MovieClips
Näheres zu Symbolen siehe meine AS2 Tipps.
Es gibt 3 Arten eine Instanz eines Movieclips zu erzeugen:
Einen Movieclip aus der Bibliothek auf die Bühne ziehen. Um diesen per Actionscript anzusprechen, muss man der Instanz im Eigenschaftenfenster einen Namen zuweisen. Man kann diese Instanz über diesen Namen per Actionscript ansprechen: this["derInstanzname"].x=400;
Wenn man einen Movieclip erstellt aktiviert man die Option "Export für Actionscript" (evt. "Erweiterte Ansicht" wählen). Dann vergibt man einen Klassennamen. Außerdem kann man zu diesem Klassennamen eine Klassendatei erstellen. Man kann dann eine Instanz per Actionscript erzeugen: var myInstanz:MyMCKlasse = new MyMcKlasse();
addChild(myInstanz);
mehr dazu siehe hier
Eine leere Movieclipinstanz erzeugen, um diese beispielsweise als Container für andere Displayobjekte / Movieclipinstanzen zu nutzen: var myMC:MovieClip = new MovieClip();
addChild(myMC);
Eigenschaften
Eine Auflistung der Eigenschaften findet man im Actionbedienfeld CS6 unter flash.display / Movieclip / Eigenschaften (properties) oder im Actionscript 3 Komponenten Referenzhandbuch. Im nächsten Tipp wird erklärt, wie man Movieclips dynamisch erzeugt.
Die wichtigsten Eigenschaften
x horizontale Position
y vertikale Position
width Breite
height Höhe
scaleX Originalbreite von 0 bis 1 / 1 ist Originalbreite
scaleY Orignalhöhe von 0 bis 1 / 1 ist Origianlhöhe
alpha Transparenz von 0 bis 1
rotation Drehwinkel in Grad
visible, Sichtbarkeit, der boolsche Wert ist true oder false, bei false ist der Movieclip praktisch nicht vorhanden der er nicht mehr auf die Maus reagiert
currentFrame die aktuelle Nummer des Frames der angezeigt wird
totalFrames die gesamte Anzahl der Frames der Zeitleiste
mouseX die horizontale Position der Mauszeigers zum Referenzierungspunkt
mouseY die vertikale Position des Mauszeigers zum Nullpunkt
parent das Elternelement in dem sich die Instanz befindet auch mehrfach möglich parent.parent
stage eine Eigenschaft welche auf die Bühne verweist.
numChildren die Anzahl der enthaltenen Displayobjekte
mask diese Eigenschaft erwartet ein DisplayObject, welches als Maske dient
buttonMode boolscher Wert true oder false, der Movieclip lässt sich als Button einsetzen, denn der Mauscursor zeigt die Hand.
MovieClip als MouseCursor
Wenn man beispielsweise eine Movieclipinstanz als Cursor einsetzen will (siehe dragMovieclip oder Mausposition), kann es von Vorteil sein, dass er nicht mehr auf MouseEvents reagiert, damit darunterliegende Displayobjekte oder Buttons anklickbar sind. Die Deaktivierung erfolgt folgendermaßen:
my_mc.mouseEnabled = false;
Man sollte auch darauf achten, dass Kindelemente innerhalb des Mc auch entsprechend mouseEnabled werden.
Movieclips als Buttons
Oft bietet es sich an, anstatt Schaltflächen Movieclips zu nehmen.
Beispielsweise aus folgenden Gründen:
Man kann Movielcip Instanzen Variablen anhängen. mc.bild = 1;
Man kann in Movielcips dynamische Textfelder einfügen.
Man kann per Actionscript mehrere Zustände programmieren, beispielsweise wenn die Maus die Instanz verlässt.
Damit ein Movieclip, den bei Buttons üblichen Handcursor anzeigt, weise folgenden Eigenschaften den Wert true zu.
In dem Zusammenhang sollte man wissen wie man dynamische Textfelder deaktiviert, damit sie nicht mehr auf Mausereigenisse reagieren. Das kann man gebrauchen, wenn man unter den Textfeldern Buttons hat, welche auf die Maus reagieren sollen.
Wie die Füllmethoden in Photoshop so ist es auch mit Flash möglich Movieclips Füllmethoden zuzuweisen. Es gibt 2 Möglichkeiten a) händisch über die Einstellungen "mischen" im Einstellungsfenster oder über Actionscript:
Den AS2 Befehl attachMovieClip() gibt es nicht mehr. In Actionscript 3 werden Instanzen aus der Bibliothek mit addChild() auf die Bühne gebracht. Der Befehl duplicate Movieclip wurde in AS3 ersatzlos gestrichen. In AS3 ist es möglich alle Instanzen anzusprechen, auch die die man in der IDE eingefügt hat. Selbst dann, wenn man keinen Instanznamen vergeben hat.
Eine Sache hat mir beim Umstieg von AS2 zu AS3 Schwierigkeiten bereitet und zwar die Referenzierung oder das Ansprechen von Movieclips oder anderen Instanzen, die ineinander verschachtelt sind. Wenn ich im ersten Frame per Actionscript Instanzen erzeuge und diese mit addChild() innerhalb einer anderen Instanz einfüge, so kann ich in AS3 diese Instanz trotzdem einfach über den Instanznamen ansprechen, ohne den Pfad aufzuführen.
var mc:MovieClip = new MovieClip();
addChild(mc);
var tf:TextField = new TextField();
mc.addChild(tf);
tf.appendText("bla bla");
folgendes ist falsch, obwohl sich tf innerhalb von mc befindet mc.tf.appendText("bla bla");
Anders verhält es sich, wenn das Textfeld händisch in dem Movieclip eingefügt wurde. Nehmen wir an, es hätte auch den Instanznamen tf im Eigenschafteninspektor zugewiesen bekommen und die Instanz des Movieclips hat wieder den Instanznamen mc. In dem Fall müsste ich das Textfeld folgendermaßen ansprechen.
mc.tf.appendText("bla bla");
In beiden Fällen ist es völlig egal ob der mc händisch auf die Bühne gezogen wurde oder ob es sich um eine Movieclipklasse handelt, die per Actionscript instanziiert wurde.
setChildIndex(DisplayObject, int);
Bewege die Maus über die MovieClip Instanzen (Kreise);
Um einen DisplayObjekt Container nach vorne zu bringen, kann man ihn einfach mit addChild() wieder hinzufügen. Alternativ kann man den Z-Index aber auch über seChildIndex() definieren. Das Thema in den Adobe Referenzen
Für den Inhalt dieser Seite ist eine neuere Version von Adobe Flash Player erforderlich.
ADDED_TO_STAGE (AS3 Referenzen)
Wenn man eine Movieclip- Klasse oder ein andere Display Objekt Klasse hat und möchte in dieser Klasse einen Event Listener auf die stage registrieren, so ist das erst dann möglich, wenn die Bühne bekannt ist. Das ist der Fall, wenn das Objekt an die Displayliste angehängt wurde. addChild()
REMOVED_FROM_STAGE (AS3 Referenzen)
Wenn man ein DisplayObject aus der Displayliste entfernt, werden nicht automatisch alle Events entfernt, die eventuell in der Klasse enthalten sind, das kann zu Fehlern führen und außerdem belastet es den Speicher, besonders bei onEnterFrame Ereignissen. Abhilfe schafft hier removedFromStage. Damit kann man alle enthaltenen Events löschen, sobald die Instanz aus der Displayliste entfernt wird.
package {
import flash.display.MovieClip;
import flash.events.*;
public class MyMc extends MovieClip {
//----------------------------------------------
public function MyMc() {
super();
if (stage) {
init();
} else {
addEventListener(Event.ADDED_TO_STAGE,init);
}
}
//-----------------------------------------------
private function init(e:Event=null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
addEventListener(Event.REMOVED_FROM_STAGE, destroy);
}
//-----------------------------------------------
private function destroy(e:Event):void {
removeEventListener(Event.REMOVED_FROM_STAGE, destroy);
}
}
}
ADDED und REMOVED
Wenn ein neues Child Display Object einem Display Object Container hinzugefügt wird, versendet Actionscript einen Event Event.ADDED der auf das Child Display Object verweist. Genauso wird eine Event Event.REMOVED verschickt, wenn ein Display Object von einem Display Object Container entfernt wird.
Mit Event.ADDED kann man jedoch nicht überprüfen, ob ein Object der Display Liste hinzugefügt wurde, da er nur erscheint, wenn ein Object einem DisplayObject-Container hinzugefügt wurde. Dieser Container muss aber nicht zwangsläufig der Displayliste hinzugefügt worden sein. Für derlei Überprüfungen nimmt man Event.ADDED_TO_STAGE und Event.REMOVED_FROM_STAGE
Wenn ein Event Dispatch (Versand) auf ein Ziel in der Displaylisten-Hierachie verweist werden alle Abkömmlinge und Eltern benachrichtigt. Daher kann man Event.ADDED und Event.REMOVED auf 2 Arten einsetzen:
Eine Display-Object-Container Instanz wird benachrichtigt wenn ihr ein DisplayObject hinzugefügt oder entfernt wird.
Eine Display-Object-Container Instanz kann den Event.ADDED oder Event.REMOVED dazu nutzen, um zu erkennen, ob es selbst zu einem Eltern-Container hinzugefügt oder davon entfernt wurde.
var container:Sprite = new Sprite ();
var child:Sprite = new Sprite ();
var grandchild:Sprite = new Sprite();
function addedListener (e:Event):void
{
trace ("ADDED wurde aufgerufen");
trace (e.currentTarget.name);
trace(e.target.name);
}
In diesem Beispiel wird die Funktion "addedListener" 3 mal aufgerufen.
An diesen Beispielen kann man auch die Phasen eines Events verdeutlichen und zwar ist der EventListener auf container registriert. Die "container" Instanz wird per addChild hinzugefügt und der Eventflow befindet sich in der Target Phase, während sich der Eventflow bei child und grandchild in der Bubbling Phase befindet.
Die Aufnahmephase (EventPhase.CAPTURING_PHASE).
Die Zielphase (EventPhase.AT_TARGET).
Die Bubbling-Phase (EventPhase.BUBBLING_PHASE).
function addedListener (e:Event):void
{
trace ("ADDED während Phase: "+e.eventPhase);
trace(e.target.name);
}
Es lassen sich somit verschiedene Überprüfungen programmieren.
Das Display Object selbst wird einem Eltern-Container hinzugefügt:
if(e.eventPhase == EventPhase.AT_TARGET)
{ trace("ich wurde selbst hinzugefügt"); }
Dem Display Object wurde ein Display Object hinzugefügt:
if(e.eventPhase == EventPhase.BUBBLING_PHASE)
{ trace("ich habe einen Nachfahren bekommen"); }
Das Display Object ist ein direktes Child:
if(DisplayObject(e.target.parent) == e.currentTarget)
{
trace("Ich habe ein Kind bekommen.");
}
Alle Objekte der Displayliste löschen
Alle Objekte der Displayliste löscht man am besten mit einer while Schleife
while (this.numChildren>0) {
this.removeChildAt(this.numChildren-1);
}
Alle auf diese Weise gelöschten Objekten befinden sich noch im Speicher und könnten mit addChild() wieder hinzugefügt werden. Man müsste also auch noch alle Variablen die auf das Objekt verweisen auf null setzen, damit der Garbage Collector den Speicher frei machen kann.
Alle DisplayObjects abfragen / komplette Displaylist abfragen
und wenn es Movieclips sind, werden sie gestoppt.
function displayListStop(container:DisplayObjectContainer):void {
var child:DisplayObject;
var movie:*;
var clip:MovieClip;
for (var i:uint=0; i < container.numChildren; i++) {
child=container.getChildAt(i);
if (child is MovieClip) {
movie=child;
clip=movie;
clip.stop();
}
if (container.getChildAt(i) is DisplayObjectContainer) {
displayListStop(DisplayObjectContainer(child));
}
}
}
Aufruf der Funktion für die gesamte Bühne. Man achte auf die Syntax: this.stage
displayListStop(this.stage);
Alle Displayobjekte unter einem Point beispielsweise der Mausposition
mc.getObjectsUnderPoint(Point):Array
Mit dieser Funktion bekommt man ein Array mit Objekten, die diesem Displayobjekt (mc) untergeordnet sind. Im folgenden Beispiel werden alle Objekte, die unter dem angeklickten Punkt liegen etwas transparenter.
import flash.geom.Point;
addEventListener(MouseEvent.CLICK, alphaTarget);
function alphaTarget(evt:MouseEvent):void
{
var mausPos:Point = new Point(stage.mouseX,stage.mouseY);
var touchedObj:Array = stage.getObjectsUnderPoint(mausPos);
trace(touchedObj);
for (var i:uint=0; i < touchedObj.length; i++)
{
touchedObj[i].alpha -= 0.1;
}
}