Timer Adobe Referenzen | TimerEvent Adobe Referenzen
Man kann sich einen Timer wie eine Uhr vorstellen. Man erstellt die Uhr, stellt das Zeitintervall ein und startet sie. Bei jedem Zeitintervall wird eine Nachricht gesendet. In der Event Funktion definiert man die Anweisungen, die bei jedem Zeitintervall ausgeführt werden.
In den folgenden Beispielen muss ein dynamisches Textfeld mit Instanznamen myText auf der Bühne liegen.
var myTimer:Timer = new Timer(1000); myTimer.start (); myTimer.addEventListener (TimerEvent.TIMER, TimerUpdate); function TimerUpdate (evt:TimerEvent):void { myText.text = String(evt.target.currentCount); }
Im folgenden Beispiel geht es um eine Animation per Timerfunktion. Die einzelnen Bilder der Figur werden per Timer aufgerufen. Von daher läuft die Figur immer gleich schnell, egal wie hoch die Framerate eingestellt ist. (die Hintergrundbewegung entspricht diesem Beispiel)
var myTimer:Timer = new Timer(50); myTimer.addEventListener(TimerEvent.TIMER, timerFunction); myTimer.start(); function timerFunction(event:TimerEvent) { if (hero.currentFrame == 15) { hero.gotoAndStop(2); } else { hero.gotoAndStop(hero.currentFrame+1); } }
Im folgenden Beispiel wird eine Zeit basierte Animtion erzeugt und zwar wird bei jedem Schritt (EnterFrame) abgefragt wieviel Zeit vergangen ist. Dann wird der Movieclip anhand dieses Wertes weiterbewegt. Nehmen wir an, jede Sekunde wird der Movieclip 100 Pixel weiterbewegt, so würde bei einem Zeitintervall von 2 Sekunden die Distanz 200 Pixel betragen.
Mit getTimer() kann man die Ablaufzeit des Flashfilms in Millisekunden abfragen.
Anhand dieses Wertes wird ermittelt, wieviel Zeit zwischen den einzelnen EnterFrames vergangen ist. timeDif = getTimer() - lastTime
, dann wird der Wert für lastTime gesetzt. lastTime += getTimer();
Dann wird der Movieclip anhand der ermittelten Zeitdifferenz weiterbewegt und zwar ein 10tel des ermittelten Millisekundenwertes. also 100 Pixel pro Sekunde. ball.x += timeDif * 0.1;
var lastTime:int = getTimer(); ball.addEventListener(Event.ENTER_FRAME, moveBall); function moveBall(evt:Event):void { var timeDif:int = getTimer() - lastTime; lastTime += timeDif; ball.x += timeDif * 0.1; }
Die Anziehungskraft in der realen Welt ist eine konstante Beschleunigung von 9,8 Meter pro Sekunde Richtung Erdboden. Da man in Flash nicht mit Metern, sondern mit Pixeln rechnet, wird der Wert verkleinert auf 0.0098. Man legt eine Startgeschwindigkeit fest und definiert damit eine Zeitbasierte Animation (siehe oben). Die vertikale Position wird bei jedem Schritt um den Anziehungskraft erhöht.
var lastTime:int = getTimer(); var gravity:Number = .00098; var dx:Number = .2; var dy:Number = -.8; ball.addEventListener(Event.ENTER_FRAME, moveBall); function moveBall(evt:Event):void { var timeDif:int = getTimer() - lastTime; lastTime += timeDif; dy += gravity * timeDif; ball.x += timeDif * dx; ball.y += timeDif * dy; }
Hier kommt eine Timer basierte Animation und eine Tastatursteuerung zusammen. Die Änderung des Zeitintervalls erhöht die Laufgeschwindigkeit in Punkto Geschwindigkeit der Bilder also auch der Position. var myTimer:Timer = new Timer(50);
Die Figur besteht aus verschachtelten Movieclips. In den 5 Bildern der Figur befindet sich je ein Movieclip mit einer Animation bild1 seitlich nach links, bild2 seitlich nach rechts, bild 3 von vorne, bild 4 von hinten, bild 5 von vorne stehend.
import flash.events.KeyboardEvent; import flash.events.Event; var leftArrow:Boolean = false; var rightArrow:Boolean = false; var upArrow:Boolean = false; var downArrow:Boolean = false; var speed:Number = 7; boy.gotoAndStop(5); stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressedDown); stage.addEventListener(KeyboardEvent.KEY_UP, keyPressedUp); function keyPressedDown(evt:KeyboardEvent):void { if (evt.keyCode == 37) { leftArrow = true; } else if (evt.keyCode == 38) { upArrow = true; } else if (evt.keyCode == 39) { rightArrow = true; } else if (evt.keyCode == 40) { downArrow = true; } } function keyPressedUp(evt:KeyboardEvent):void { if (evt.keyCode == 37) { leftArrow = false; } else if (evt.keyCode == 38) { upArrow = false; } else if (evt.keyCode == 39) { rightArrow = false; } else if (evt.keyCode == 40) { downArrow = false; } boy.gotoAndStop(5); } var myTimer:Timer = new Timer(50); myTimer.addEventListener(TimerEvent.TIMER, timerFunction); myTimer.start(); function timerFunction(event:TimerEvent) { if (boy.boy.currentFrame == 10) { boy.boy.gotoAndStop(1); } else { boy.boy.gotoAndStop(boy.boy.currentFrame+1); } if (leftArrow) { boy.x -= speed; boy.gotoAndStop(2); } if (rightArrow) { boy.x += speed; boy.gotoAndStop(1); } if (upArrow) { boy.y -= speed; boy.gotoAndStop(4); } if (downArrow) { boy.y += speed; boy.gotoAndStop(3); } }
TIMER_COMPLETE ist ein Ereignis, welches nach Ablauf oder Abarbeitung des Timers ausgelöst wird. In dem Zusammenhang kann man auch die Funktion updateAfterEvent() gut gebrauchen. Denn die Funktion weist den Flash Player oder die AIR-Laufzeitumgebung nach Abschluss der Verarbeitung dieses Ereignisses zur Wiedergabe an, wenn die Anzeigeliste geändert wurde. Lösche im folgenden Beispiel die Zeile mit updateAfterEvent(), dann wirst du sehen, dass die trace() Anweisung ausgeführt wird, aber die Anzeigenliste nicht aktualisiert wird. Die Anzeige im Textfeld wird nicht erneuert.
import flash.events.MouseEvent; var counter:uint = 1; var myTimer:Timer = new Timer(1000,6); myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timerEnde); myTimer.start(); function TimerUpdate(evt:TimerEvent):void { myText.text = String(counter); counter++; } function timerEnde(evt:TimerEvent):void { trace("Ende"); myText.text = "Ende im Gelände."; evt.updateAfterEvent(); }
Mittels reset kann man den Timer zurücksetzen. Danach kann man ihn neu starten. Im folgenden Beispiel wird nach Ablauf des Timers die Möglichkeit eingeräumt, durch MOUSE_UP den Timer neu zu starten. Während der Timer läuft wird der Eventlistener für den Neustart wieder entfernt.
import flash.events.MouseEvent; var counter:uint = 1; var myTimer:Timer = new Timer(1000,6); myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); myTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timerEnde); myTimer.start(); function TimerUpdate(evt:TimerEvent):void { trace(counter); stage.removeEventListener(MouseEvent.MOUSE_UP, startTimer); myText.text = String(counter); evt.updateAfterEvent(); counter++; } function timerEnde(evt:TimerEvent):void { myText.text = "Ende im Gelände."; stage.addEventListener(MouseEvent.MOUSE_UP, startTimer); evt.updateAfterEvent(); } function startTimer(evt:MouseEvent):void { myTimer.reset(); myTimer.start(); counter = 1; myText.text = " Neustart"; }
Im folgenden Beispiel wird durch Mausklick zwischen Pause und Play des Timers hin und her geschaltet.
import flash.events.MouseEvent; var counter:uint = 1; var onOff:Boolean = true; var myTimer:Timer = new Timer(1000); myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); stage.addEventListener(MouseEvent.MOUSE_UP, startStop); myTimer.start(); function TimerUpdate(evt:TimerEvent):void { myText.text = String(counter); evt.updateAfterEvent(); counter++; } function startStop(evt:MouseEvent):void { if (onOff == true) { onOff = false; myTimer.stop(); } else { onOff = true; myTimer.start(); } }
Die Figur im folgenden Beispiel lässt sich mit 2 Geschwindigkeiten abspielen. Klicke dazu auf den linken oder rechten "Speed" Button.
var myTimer:Timer=new Timer(100,0); myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); function TimerUpdate(event:TimerEvent):void { figur_mc.nextFrame(); } function TimerFast(evt:MouseEvent):void { myTimer.reset(); myTimer.delay=50; myTimer.start(); } function TimerSlow(evt:MouseEvent):void { myTimer.reset(); myTimer.delay=100; myTimer.start(); } fast_btn.addEventListener(MouseEvent.CLICK, TimerFast); slow_btn.addEventListener(MouseEvent.CLICK, TimerSlow);
In diesem Flashfilm gibt es einen Movieclip mit Instanznamen "figur_mc". Darin befinden sich 3 Schlüsselbilder. Im ersten Schlüsselbild befindet sich die Figur im Stopzustand. Im Schlüsselbild namens "forward" befindet sich eine MC-Instanz namens "run_mc" welches eine Einzelbildanimation mit vorwärts laufender Figur enthält. Im Schlüsselbild namens "back" befindet sich eine andere MC-Instanz mit rückläufiger Bewegung jedoch mit dem gleichen Instanznamen "run_mc".
var anim:String; var moveMode:String="stand";//"stand", "run" var frameSpeed:uint=50; var myTimer:Timer=new Timer(100,0); myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); // timerfunktion ruft die Frames des run_mc auf function TimerUpdate(event:TimerEvent):void { if(figur_mc.run_mc.currentFrame < figur_mc.run_mc.totalFrames){ figur_mc.run_mc.nextFrame(); }else{ figur_mc.run_mc.gotoAndStop(1); } } // timer mit einer gewissen Geschwindigkeit starten function setFrameSpeed(update:uint):void { myTimer.reset(); myTimer.delay=update; myTimer.start(); } function TimerFast(evt:MouseEvent):void { frameSpeed=50; if (moveMode=="run") { setFrameSpeed(frameSpeed); } } function TimerSlow(evt:MouseEvent):void { frameSpeed=100; if (moveMode=="run") { setFrameSpeed(frameSpeed); } } fast_btn.addEventListener(MouseEvent.CLICK, TimerFast); slow_btn.addEventListener(MouseEvent.CLICK, TimerSlow); function walkForward(evt:MouseEvent):void { moveMode="run"; setFrameSpeed(frameSpeed); anim="forward"; figur_mc.gotoAndStop(anim); } function walkBack(evt:MouseEvent):void { moveMode="run"; setFrameSpeed(frameSpeed); anim="back"; figur_mc.gotoAndStop(anim); } forward_btn.addEventListener(MouseEvent.CLICK, walkForward); back_btn.addEventListener(MouseEvent.CLICK, walkBack); function stopWalk(evt:MouseEvent):void { moveMode="stand"; myTimer.stop(); figur_mc.gotoAndStop(1); } stop_btn.addEventListener(MouseEvent.CLICK, stopWalk);
In diesem Flashbeispiel habe ich 2 MovieClips mit jeweils einer Klassendatei: SmileySimple.as und Smiley.as
Mit einem Timer wird in einem bestimmten Interval eine neue Position erzeugt, ausgehend von der jeweiligen Position.
Die Klasse Smiley.as ist etwas erweitert, weil hier ein zweiter Timer hinzugekommen ist, der dafür sorgt, dass sich das Objekt in kleinen Schritten (steps) auf das Ziel zubewegt, bevor ein neues Ziel erzeugt wird.
Mit dem Button kann man die Positionen wieder zurücksetzen. Diese Funktionalität habe ich hier nicht aufgeführt.
Hier wird jede Sekunde eine neue Position erzeugt und das Element auf diese Position gesetzt:
package { import flash.display.MovieClip; import flash.utils.*; import flash.events.*; import flash.geom.Point; public class SmileySimple extends MovieClip { protected var delay:uint=1000; protected var myTimer:Timer=new Timer(delay,0); protected var distance:uint=30; //------------------------------------ public function SmileySimple() { if (stage) { init(); } else { addEventListener(Event.ADDED_TO_STAGE,init); } } //------------------------------------------- private function init(e:Event=null):void { myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); myTimer.start(); } //------------------------------------------------ protected function TimerUpdate(event:TimerEvent):void { var p:Point=getNextPosition(); trace("xPos: "+this.x+" xZiel: "+p.x); this.x=p.x; this.y=p.y; } //---------------------------------------------- protected function getNextPosition():Point { var dirX:int; dirX=Math.floor(Math.random()*3)-1;//-1, 0, 1 var dirY:int; dirY=Math.floor(Math.random()*3)-1; // wenn beide Werte 0 sind, ergäbe sich keine neue Position if (dirX==0&&dirY==0) { getNextPosition(); } var xZiel:Number=this.x+distance*dirX; var yZiel:Number=this.y+distance*dirY; var zielPoint:Point=new Point(xZiel,yZiel); return zielPoint; } } }
Hier wurde die Klasse SmileySimple noch etwas erweitert, so dass Element sich in einer bestimmten Anzahl von Schritten auf das Ziel zubewegt.
package { import flash.display.MovieClip; import flash.utils.*; import flash.events.*; import flash.geom.Point; public class Smiley extends MovieClip { protected var delay:uint=1000; protected var steps:uint=20; protected var myTimer:Timer=new Timer(delay,0); protected var myMoveTimer:Timer=new Timer((delay/steps),0); protected var xPositions:Array; protected var yPositions:Array; protected var distance:uint=30; protected var reset:Boolean=false; //-------------------------------------------------------- public function Smiley() { if (stage) { init(); } else { addEventListener(Event.ADDED_TO_STAGE,init); } } //------------------------------------------- private function init(e:Event=null):void { myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); myTimer.start(); myMoveTimer.addEventListener(TimerEvent.TIMER, moveTimerUpdate); } //------------------------------------------------ protected function TimerUpdate(event:TimerEvent):void { myMoveTimer.stop(); var p:Point=getNextPosition(); trace("xPos: "+this.x+" xZiel: "+p.x); var distX:Number=(p.x-this.x)/steps; var distY:Number=(p.y-this.y)/steps; xPositions = new Array(); yPositions = new Array(); xPositions[0]=this.x+distX; yPositions[0]=this.y+distY; for (var i:uint=1; i < steps; i++){ xPositions[i]=xPositions[i-1]+distX; yPositions[i]=yPositions[i-1]+distY; trace(xPositions[i]); } myMoveTimer.start(); } protected function moveTimerUpdate(event:TimerEvent):void { this.x=xPositions[0]; xPositions.shift(); this.y=yPositions.shift(); } //---------------------------------------------- protected function getNextPosition():Point { var dirX:int; dirX=Math.floor(Math.random()*3)-1;//-1, 0, 1 var dirY:int; dirY=Math.floor(Math.random()*3)-1; // wenn beide Werte 0 sind, ergäbe sich keine neue Position if (dirX==0&&dirY==0) { getNextPosition(); } var xZiel:Number=this.x+distance*dirX; var yZiel:Number=this.y+distance*dirY; var zielPoint:Point=new Point(xZiel,yZiel); return zielPoint; } } }
Die Funktion gibt die Ablaufzeit seit dem Start des Flashfilms in Millisekunden zurück. Im folgenden Beispiel wird damit die Zeit zwischen 2 Mausklicks ermittelt.
import flash.events.MouseEvent; var spielStart:Number; info.text = "Klicke irgendwo."; stage.addEventListener(MouseEvent.CLICK, startTime); function startTime(evt:MouseEvent):void { spielStart = getTimer(); info.text = "Spiel läuft, Zeit wird gezählt, Spielende durch Mausklick."; trace(spielStart); stage.removeEventListener(MouseEvent.CLICK, startTime); stage.addEventListener(MouseEvent.CLICK, stopTime); } function stopTime(evt:MouseEvent):void { var spielStop:Number = Math.round((getTimer()-spielStart)/1000); stage.removeEventListener(MouseEvent.CLICK, stopTime); stage.addEventListener(MouseEvent.CLICK, startTime); info.text = String(spielStop) + " Sekunden Spielzeit."; }
Zeit in Minuten und Sekunden anzeigen
function timeString(milliSek:Number):String { var min:Number = Math.floor(milliSek/ 60000); var sek:Number = Math.floor(milliSek/1000 )-(60*min); var sekStrg:String = sek<10 ? 0+String(sek) : String(sek) ; return min+":"+sekStrg; } anzeige.text = timeString(getTimer());
Auf der meiner www.pastorpixel.de Seite unter "Art" gibt es ein Beispiel, wo eine Action 6 mal aufgerufen wird. Dann folgt eine längere Pause und die Schleife wird wieder 6 mal aufgerufen. Dazu habe ich 2 Timer erstellt. Einen für die Schleife und einen für die Pause.
var lichter: Array = new Array(); for (var i: uint = 0; i < 6; i++) { lichter[i] = new Licht(); addChild(lichter[i]); lichter[i].x = 60 + i * 80; lichter[i].y = 120; lichter[i].visible = false; } var myTimer: Timer = new Timer(1000); myTimer.start(); myTimer.addEventListener(TimerEvent.TIMER, TimerUpdate); var pause: Timer = new Timer(15000); pause.addEventListener(TimerEvent.TIMER, warte); var counter: int = -1; function TimerUpdate(evt: TimerEvent): void { counter++; trace(counter); if (counter < 6) { var nr: uint = counter; for (var i: uint = 0; i < lichter.length; i++) { lichter[i].visible = false; } lichter[nr].visible = true; } else { lichter[5].visible = false; myTimer.stop(); pause.start(); } } function warte(evt: TimerEvent) { counter = -1; myTimer.start(); pause.stop(); }