Tween event listener - actionscript-3

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
}

Related

AS3: How do I call a function with two arguments - (vBox, and vFile)

Adobe Flash CC
Sort of confused here. I'm working on optimizing my code so that instead of calling launchVideo(); for every single video I can can simply call it once, while passing a new source string to the function.
How do I call the launchVideo function from within another function?
When I add an event listener, which calls the playMPMovie
buttonOne.addEventListener(MouseEvent.MOUSE_DOWN, playMPMovie, false, 0, true);
function playMPMovieOne(): void {
video_file = "/videos/MP_01.mp4";
launchVideo();
}
I get this...
Scene 1, Layer 'actions', Frame 1, Line 21, Column 2 1136: Incorrect number of arguments. Expected 2.
When I try adding (vBox, vFile) to launchVideo(); I get this...
Scene 1, Layer 'actions', Frame 1, Line 20, Column 20 1120: Access of undefined property vFile.
Scene 1, Layer 'actions', Frame 1, Line 20, Column 14 1120: Access of undefined property vBox.
Here is the full code.
stop();
import flash.events.MouseEvent;
import flash.events.Event;
import flash.display.MovieClip;
import flash.display.Graphics;
import fl.video.*;
vinetteMC.visible = false;
// VARIABLES //
var video_holder: MovieClip = new MovieClip();
var video_file: String;
// EVENT LISTENERS //
buttonOne.addEventListener(MouseEvent.MOUSE_DOWN, playMPMovie, false, 0, true);
function playMPMovieOne(): void {
video_file = "/videos/MP_01.mp4";
launchVideo();
}
// Place Playback
function launchVideo(vBox, vFile): void {
var flvPlayer: FLVPlayback = new FLVPlayback();
import fl.video.*;
import flash.events.*;
flvPlayer.source = vFile;
flvPlayer.skinAutoHide = true;
flvPlayer.skinBackgroundColor = 0x000000;
flvPlayer.width = 1920;
flvPlayer.height = 1080;
flvPlayer.addEventListener(Event.COMPLETE, completeHandler, false, 0, true);
function completeHandler(event: Event): void {
removeChild(video_holder);
removeChild(flvPlayer);
flvPlayer.addEventListener(fl.video.VideoEvent.COMPLETE, completeHandler, false, 0, true);
trace("Complete handler called");
}
vBox.addChild(flvPlayer);
}
launchVideo(video_holder, video_file);
It looks like you are wanting to call
function playMPMovieOne(): void {
video_file = "/videos/MP_01.mp4";
launchVideo(video_holder, video_file)
}
Also from your example code the video holder is created but never added to the display list. You may need to add this to see anything.
addChild(video_holder);

Why does TweenLite.to and hitTestObject not work?

this is my code:
stop();
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.TweenMax;
import com.greensock.TweenLite;
import flash.events.Event;
import com.greensock.TweenLite
stage.addEventListener(MouseEvent.CLICK, rijden); // Add the button click
function rijden(e:MouseEvent):void {
TweenLite.to(auto, 4, {x:666.15, y:375.6});
}
addEventListener(Event.ENTER_FRAME, einde1);
function einde1(e:Event){
if(auto.hitTestObject(stopauto)){
var myTween=TweenLite.to(auto, 4, {x:666.15, y:375.6});
myTween.kill(); //here code for tween killing
trace("works")
//
auto.x = 241;
auto.y = 375;
removeEventListener(Event.ENTER_FRAME, einde1)
}
}
and I want that if auto hits stopauto, auto goes to
auto.x = 241;
auto.y = 375;
it does the trace but it doesn't go to the x and y what I want it to go
You have two tweens, one of them is never killed. I guess it simple goes on and overrides your x/y for the final car destination.
//tween one
function rijden(e:MouseEvent):void {
TweenLite.to(auto, 4, {x:666.15, y:375.6});
}
//tween two
function einde1(e:Event){
if(auto.hitTestObject(stopauto)){
var myTween=TweenLite.to(auto, 4, {x:666.15, y:375.6});
myTween.kill(); //here code for tween killing
//REST OF YOUR CODE
}
}
#Fygo is absolutely correct. In your enterframe handler, instead of getting a reference to the Tween you started in the click handler, you are in fact creating a new Tween which you then kill immediately, rather than the original Tween which continues to execute.
I think the following will fix it:
// ... Rest of your code
function rijden(e:MouseEvent):void {
// start the tween on mouse click
TweenLite.to(auto, 4, {x:666.15, y:375.6});
}
addEventListener(Event.ENTER_FRAME, einde1);
function einde1(e:Event){
if(auto.hitTestObject(stopauto)){
// Objects have collided so stop the tween
TweenLite.killTweensOf(auto);
// Place the object somewhere else
auto.x = 241;
auto.y = 375;
removeEventListener(Event.ENTER_FRAME, einde1)
}
}

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.

as3, doing tasks in certain order

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")}});
}