as3, doing tasks in certain order - actionscript-3

I have a simple function going here.
import fl.transitions.Tween;
import fl.transitions.easing.*;
function goBack (e:MouseEvent):void{
var backAlpha:Tween = new Tween(MovieClip(parent).blueOverlay, "alpha", Strong.easeOut, 1, 0, 2, true);
MovieClip(parent).gotoAndStop("home");
}
btnBack.addEventListener(MouseEvent.CLICK, goBack);
What it is doing right now is: it is going to the "home" label as soon as btnBack is clicked, which means it is completely disregarding the alpha part.
What I need it to do is: do the alpha part first, then right after it's finished that, do the second part where it jumps to the "home" frame.
Thanks,
Wade

Look at the documentation for fl.transtions.Tween
Specifically, look at the motionFinish event.
Basically, what you want to do is something like this:
import fl.transitions.Tween;
import fl.transitions.easing.*;
function goBackStart (e:MouseEvent):void{
var backAlpha:Tween = new Tween(this.parent.blueOverlay, "alpha", Strong.easeOut, 1, 0, 2, true);
backAlpha.addEventListener("motionFinish", goBackFinish);
}
function goBackFinish(e:Event) {
removeEventListener(e.target.obj, goBackFinish);
this.parent.gotoAndStop("home");
}
btnBack.addEventListener(MouseEvent.CLICK, goBackStart);
I am not a fan of how the built-in Tweening class works, so I use either of these:
TweenLite - My new favorite
Tweener - My goto library of years past
Both of these libraries have similar APIs and use an onComplete property to handle completion.
Using Tweener you could do:
import com.caurina.transitions.Tweener;
btnBack.addEventListener(MouseEvent.CLICK, goBack);
function goBack(e:MouseEvent):void {
Tweener.addTween(this.parent.blueOverlay, {alpha:0, time:2.0, transition:"easeOutQuad", onComplete:function() {this.parent.gotoAndStop("home")}});
}

Related

Actionscript3 clearInterval is not working on TouchEvent.TOUCH_BEGIN

I have called a setInterval on TouchEvent.TOUCH_END and I want to clear it when ever screen is touched.
Here is my code:
import fl.motion.MotionEvent;
import flash.display.MovieClip;
import flash.utils.*;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
stage.addEventListener(TouchEvent.TOUCH_BEGIN, onTouchBegin);
stage.addEventListener(TouchEvent.TOUCH_END, onTouchEnd);
function onTouchBegin(evt:TouchEvent)
{
clearInterval(MovieClip(root).myInterval);
}
function onTouchEnd(evt:TouchEvent)
{
MovieClip(root).myInterval = setInterval(showTimer,1000);
}
function showTimer()
{
trace("interval working");
}
Your provided code doesn't really explain everything so there will be a fair bit of speculation in this answer:
Possiblity No. 1:
Your way of casting root to MovieClip is not working. Try changing to following:
function onTouchBegin(evt:TouchEvent)
{
var intervalRef:int = (root as MovieClip).myInterval;
clearInterval(intervalRef);
}
Possiblity No. 2:
It seems that your code is written in a frame. And although if you define something in a previous frame it should work, but if you have the code on a different (lower) layer on the same keyframe it could define the variable later and your MovieClip(root).myInterval variable is undefined or null is the value is not defined. So check if your variable even exists:
function onTouchBegin(evt:TouchEvent)
{
trace(MovieClip(root) == null); // see if the root is defined
trace(MovieClip(root).myInterval); // see if the myInterval is defined
}
Possiblity No. 3:
You're cycling through frames. When I had 2 frames: one blank and one with your code, the code didn't work properly. Tested in Flash CC.
Possibility No. 4:
You have a run-time error somewhere else and your whole frame's code is not being executed. Do you use the debug version of Flash Player?
Possible solution for less headache:
Use a Timer. It's easy to control, easy to manage and dispose of. I've edited your code to work with Timer and tested. Feel free to use it for your project.
import fl.motion.MotionEvent;
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
var timer:Timer = (timer == null) ? new Timer(1000) : timer;
timer.addEventListener(TimerEvent.TIMER, onTick);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onTouchBegin); // you can change back to TouchEvent, but since you're using TOUCH_POINT it's pointless so I'd just use MouseEvent
stage.addEventListener(MouseEvent.MOUSE_UP, onTouchEnd);
function onTouchBegin(evt:Event)
{
timer.stop();
}
function onTouchEnd(evt:Event)
{
timer.start();
}
function showTimer()
{
trace("interval working");
}
function onTick(e:TimerEvent):void
{
showTimer();
}
I do want to note that your code works if I just copy-paste it in a single frame Flash file. But still, it's encouraged by Adobe to use Timer instead.

Flash fadeIn / fadeOut

there is something similar for AC3 like fadeIn, fadeOut from jQuery?
Now I use visible=false but I want to animate this, from opacity 0 to opacity 1
You can achiev this with the tween class,this would be a fadein
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
var myTween = new Tween(mc, "alpha", Strong.easeIn, mc.alpha, 1, 3, true);
And here the "naked" one for all Properties:
var myTween:Tween = new Tween(object, "property", EasingType, begin, end, duration, useSeconds);
Reference Here
Also not the the Standard tweening class is not the best to use. It has a lot of problems with simultanious tweens. Best to use Tweenlite/max which can be found here: http://greensock.com/tweenlite
Reagarding comment, its been a long since i done as3 and currently have no method of testing it but this should work or atleast give you enough to fuigure it out. Import point to remeber is that the object must be alpha=0 but NOT visible=false; :
myObject.addEventListener(MouseEvent.MOUSE_OVER,overMouse);
myObject.addEventListener(MouseEvent.MOUSE_OUT,outMouse);
function overMouse(e:MouseEvent):void {
var myTweenIn = new Tween(myObject, "alpha", Strong.easeIn, myObject.alpha, 1, 3, true);
}
function outMouse(e:MouseEvent):void {
var myTweenOut = new Tween(myObject, "alpha", Strong.easeIn, myObject.alpha, 0, 3, true);
}

Tween event listener

In a frame script I have an event listener that should call the 'onFinish' function when the tween motion is finished. (See pertinent parts in red below.) I never see that 'done tweening' output. It fails silently. I've tried the addEventListener in different places.. to no avail. What am I missing?
Thanks!
import fl.transitions.*;
import fl.transitions.easing.*;
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
var currentFrameMC = animImg;
var scaleXTween:Tween=new Tween(animImg,"scaleX",Bounce.easeOut, 1,2,2.4,true);
var scaleYTween:Tween=new Tween(animImg,"scaleY",Bounce.easeOut, 1,2,2.4,true);
var alphaTween:Tween = new Tween(animImg, "alpha", Strong.easeOut, .5, 1, 11, true);
//Put a listener on the MC so I can tell when it's done tweening the scale.
currentFrameMC.addEventListener(TweenEvent.MOTION_FINISH, onFinish);
//This is another event listner put on a button:
//(The button, when clicked, will trigger the shrinking of the animImg MC)
reverseTween1.addEventListener(MouseEvent.CLICK,shrinkFrameMC);
//Shrink/scale down the anImg by tweening
function shrinkFrameMC(e:MouseEvent) //This scales down the playing movie clip
{
scaleXTween=new Tween(currentFrameMC,"scaleX",None.easeNone, currentFrameMC.scaleX,1,3,true);
scaleYTween=new Tween(currentFrameMC,"scaleY",None.easeNone, currentFrameMC.scaleY,1,3,true);
//Tween the alpha state of the movie clip again, this time in reverse
alphaTween=new Tween(currentFrameMC, "alpha", Strong.easeOut, 1, .5, 11, true);
}
function onFinish(e:TweenEvent):void //This does an action when the frame MC is done tweening
{
trace ("done tweening" );
//NEVER SEE THIS OUTPUT
}
You need to assign the Tween event listener to the Tween, not the object being tweened.
its working:
import fl.transitions.*;
import fl.transitions.easing.*;
import fl.transitions.Tween;
import fl.transitions.TweenEvent;
var scaleXTween:Tween=new Tween(animImg,"scaleX",Bounce.easeOut, 1,2,2.4,true);
var scaleYTween:Tween=new Tween(animImg,"scaleY",Bounce.easeOut, 1,2,2.4,true);
var alphaTween:Tween = new Tween(animImg, "alpha", Strong.easeOut, .5, 1, 11, true);
//Put a listener on the MC so I can tell when it's done tweening the scale.
scaleXTween.addEventListener(TweenEvent.MOTION_FINISH, onFinish);
//This is another event listner put on a button:
//(The button, when clicked, will trigger the shrinking of the animImg MC)
reverseTween1.addEventListener(MouseEvent.CLICK,shrinkFrameMC);
//Shrink/scale down the anImg by tweening
function shrinkFrameMC(e:MouseEvent) //This scales down the playing movie clip
{
scaleXTween=new Tween(currentFrameMC,"scaleX",None.easeNone, currentFrameMC.scaleX,1,3,true);
scaleYTween=new Tween(currentFrameMC,"scaleY",None.easeNone, currentFrameMC.scaleY,1,3,true);
//Tween the alpha state of the movie clip again, this time in reverse
alphaTween=new Tween(currentFrameMC, "alpha", Strong.easeOut, 1, .5, 11, true);
}
function onFinish(e:TweenEvent):void //This does an action when the frame MC is done tweening
{
trace ("done tweening" );
//NEVER SEE THIS OUTPUT
}

How can I create a simple "slider" with Flash AS3

I'm trying to create a jQuery-like slider in Flash. I'm currently using the tween class to move an object's x position, but it's slightly buggy. I have to use flash because it's being incorporated into a brochure software that works best with Flash.
When I click on the right arrow button, the object moves to a new x position. When I click on the button again, it moves, but sometimes it jumps back to the current position. When I click on the left button, it sometimes overshoots the destination.
I can create a simple "click to go to next frame" type of scroller, but it wouldn't provide the same tween/scrolling effect.
This is the code I'm using:
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
var scrollTweenRight:Tween = new Tween(mc_scroll, "x", Strong.easeOut, mc_scroll.x, mc_scroll.x-1940, 3, true);
scrollTweenRight.stop();
var scrollTweenLeft:Tween = new Tween(mc_scroll, "x", Strong.easeOut, mc_scroll.x, mc_scroll.x+1940, 3, true);
scrollTweenLeft.stop();
// functions
function scrollRight(e:MouseEvent){
scrollTweenRight.start();
}
function scrollLeft(e:MouseEvent){
scrollTweenLeft.start();
}
// listeners
btn_right.addEventListener(MouseEvent.CLICK, scrollRight);
btn_left.addEventListener(MouseEvent.CLICK, scrollLeft);
Use some library like TweenLite/TweenMax/Tweener, the built in one is not too good (and pretty slow as well).
If you want to move in regular 'steps', do not use mc.x to determine the final position as that will be taken upon each click on the button. Always store the 'final' (desired) position in a var. Example:
var shouldMoveToX:Number = 0; //initial position value
var step:Number = 500;
function scrollLeft(e:MouseEvent):void {
shouldMoveToX += step;
//kill the tween if any - I dunno if this is necessary, I haven't used Tween class in ages
//start the tween, pass the final position as shouldMoveToX
}
EDIT:
Oh I see what the problem is now - you are passing the mc's X pos into the constructor of Tween and you actually never update it. The tween will always begin from this point. Put that into your scrollLeft/Right functions:
function scrollRight(e:MouseEvent){
scrollTweenRight.begin = mc_scroll.x;
scrollTweenRight.start();
}
What I wrote above still applies, always use the shouldMoveToX as final position, otherwise it will have irregular movement when fast clicking.
...so your full code should look something like this:
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
var scrollTweenRight:Tween = new Tween(mc_scroll, "x", Strong.easeOut, mc_scroll.x, mc_scroll.x, 3, true);
scrollTweenRight.stop();
var scrollTweenLeft:Tween = new Tween(mc_scroll, "x", Strong.easeOut, mc_scroll.x, mc_scroll.x, 3, true);
scrollTweenLeft.stop();
var step:Number = 100;
var shouldMoveToX:Number = mc_scroll.x;
// functions
function scrollRight(e:MouseEvent){
scrollTweenRight.begin = mc_scroll.x;
shouldMoveToX -= step;
scrollTweenRight.finish = shouldMoveToX;
scrollTweenRight.start();
}
function scrollLeft(e:MouseEvent){
scrollTweenLeft.begin = mc_scroll.x;
shouldMoveToX += step;
scrollTweenLeft.finish = shouldMoveToX;
scrollTweenLeft.start();
}
// listeners
btn_right.addEventListener(MouseEvent.CLICK, scrollRight);
btn_left.addEventListener(MouseEvent.CLICK, scrollLeft);

Timer stops working properly after a few seconds

I have a tween playing every few seconds, and it works fine in the beginning, but then it starts to get jittery and resets before it even gets halfway through the tween.
Any idea why? the timer also seems to have a longer wait the first time i run the animation
import flash.events.Event;
import fl.transitions.Tween;
import fl.transitions.easing.*;
import flash.utils.Timer;
import flash.events.TimerEvent;
addEventListener(Event.ENTER_FRAME, move);
var signalTimer:Timer = new Timer(3000, 0);
function move(e:Event){
sender.x = mouseX;
sender.y = mouseY;
signalTimer.addEventListener(TimerEvent.TIMER, sendSignal);
signalTimer.start();
}
function sendSignal(e:TimerEvent){
signalTimer.stop();
var sigTween1X:Tween = new Tween(signal1, "x", None.easeOut, sender.x, mic1.x, 10, false);
var sigTween1Y:Tween = new Tween(signal1, "y", None.easeIn, sender.y, mic1.y, 15, false);
var sigTween3X:Tween = new Tween(signal3, "x", Strong.easeIn, sender.x, mic3.x, 7, true);
var sigTween3Y:Tween = new Tween(signal3, "y", Strong.easeOut, sender.y, mic3.y, 7, true);
}
This is a heavy segment of code; combining frame-based, timer, and tween timings.
Currently each frame calls move() which adds an event listener to your signalTimer without removing the previously added event listener:
signalTimer.removeEventListener(TimerEvent.TIMER, sendSignal);
However, adding and removing an event listener per frame is not optimal.
If you really want your timer to fire every 3-seconds, instantiate and add an event listener upon instantiation (not within the move() function):
var signalTimer:Timer = new Timer(3000, 0);
signalTimer.addEventListener(TimerEvent.TIMER, sendSignal);
signalTimer.start();
Then don't stop the timer in sendSignal().
Addressing the tweens, you could implement frame-based animation such as:
signal1.x -= (signal1.x - mic1.x) * 0.9;
signal1.y -= (signal1.y - mic1.y) * 0.9;
Therefore, implementing a delta based function to track x,y coordinates.