Tweening with TimeLine animation - actionscript-3

Easy one for you guys but new to me. I have an animated walking character called mcPlayer. Inside of it's timeline I have frame labels at various animated states "walkingLeft","walkingRight" and "Idle". The walking animations are of him walking in one spot. I want to be able to use buttons to move the character with actionscript to various targets on the stage and have the corresponding animation play as it moves.So the most direct way I could think to do it is like this...
import com.greensock.*;
btnRight.addEventListener(MouseEvent.CLICK, moveRight);
btnLeft.addEventListener(MouseEvent.CLICK, moveLeft);
function moveRight(Evt:MouseEvent):void{
TweenLite.to(mcPlayer,2,{x:450});
mcPlayer.gotoAndPlay("walkingRight");
}
function moveLeft(Evt:MouseEvent):void{
TweenLite.to(mcPlayer,2,{x:450});
mcPlayer.gotoAndPlay("walkingLeft");
}
I have tried different commands on the mcPlayer timeline,like, putting a stop(); at the beginning of each anima. I have tried putting a gotoandplay(); at the end of each anima so it will go to the beginning and loop.I would like to use the timeline as little as possible.
How do I...
1. Have the animation play continuously while the tween is in motion
2. Have the animation stop when it has reached its destination
and finally have the anima"idle" play after mcPLayer has reached its target.

To loop an animation you would test for the last frame of the animation and then loop back, you can do that within a tween with the onUpdate parameter and use onUpdateParams to pass any data needed for the update. Such as the animation label and the last frame of the animation.
If you want to do something after a tween is completed, such as change to the idle animation, you'd use the onComplete parameter.
Here's an example of what you might do :
btnRight.addEventListener(MouseEvent.CLICK, moveRight);
btnLeft.addEventListener(MouseEvent.CLICK, moveLeft);
function moveRight(Evt:MouseEvent):void{
// lastframe should be replaced with whatever the frame the walk right animation ends on.
TweenLite.to(mcPlayer, 2, {x:450, onUpdate:updateHandler, onUpdateParams:['walkingRight', lastFrame], onComplete:idleHandler);
mcPlayer.gotoAndPlay("walkingRight");
}
function moveLeft(Evt:MouseEvent):void{
// lastframe should be replaced with whatever the frame the walk left animation ends on.
TweenLite.to(mcPlayer, 2, {x:10, onUpdate:updateHandler, onUpdateParams:['walkingLeft', lastFrame], onComplete:idleHandler);
mcPlayer.gotoAndPlay("walkingLeft");
}
function updateHandler(loopLabel:String, lastFrame:int):void
{
if (mcPlayer.currentFrame == lastFrame)
{
mcPlayer.gotoAndPlay(loopLabel);
}
}
function idleHandler():void
{
mcPlayer.gotoAndPlay("idle");
// this is also where you'd do anything else you need to do when it stops.
}
I am not sure how you have your content set up, I was just guessing that you had all the animations on the timeline of the mcPlayer with labels for each animation based on what you had said.
Depending how your content is set up, you might need to implement differently. But the concepts are still the same - using onComplete and onUpdate to handle things for those particular events.

Related

How do I change the size of a movieclip in flash by clicking on it? (Actionscript 3)

Everything I've found is for making a separate button, but I'm trying to make it so that clicking on the movieclip itself makes it change size. The reason is that it's being animated moving across the page, so clicking it is the challenge. Can anyone help? This is the code I tried:
info_btn_mc.buttonMode = true;
info_btn_mc.addEventListener(MouseEvent.CLICK, openInfo);
stop();
function openInfo(e:MouseEvent):void {
enemy_first.play("shrink");
}
You cannot use play("shrink"), the method
play() (Moves the playhead in the timeline of the movie clip) has no arguments. use gotoAndPlay/gotoAndStop instead that received an argument called frame:Object (frame number or label (String).
enemy_first.addEventListener(MouseEvent.CLICK, openInfo);
enemy_first.stop();
function openInfo(event:MouseEvent):void
{
trace('event.currentTarget:', event.currentTarget);
event.currentTarget.gotoAndPlay("shrink");
}

cocos2d-x animation play in loop

A animation move from point a to b, in the movement, the animation need to be play in loop. For example, a bullet move to a point and this bullet is a animation which should be played in loop.
CCSequence::create(
CCSpawn::createWithTwoActions(
CCTargetedAction::create(sprite, CCMoveTo::create(3.0f, point_a)),
CCTargetedAction::create(sprite, CCRepeatForever::create(CCAnimate::create(animation)))
),0);
But CCRepeatForever can not be a member of action sequence.
So how to do it? I use sequence because there are others actions be queued (omitted above)
you don't need to use ccspawn for this.. nor ccsequence just run both actions separately on the object.
CCSprite *newSprite=CCSprite::create("imageName");
CCAnimation *animation=CCAnimation::create();
//..some code to add frames to this animation object..
//to repeat for indefinite time you could setLoops to -1 or use CCRepeatForever class //like this..
//1:
animation->setLoops(-1);
newSprite->runAction(CCAnimate:create(animation));
//or..
//2:
newSprite->runAction(CCRepeatForever:create(CCAnimate:create(animation)));
//now to translate this sprite simultaneously use this.
newSprite->runAction(CCMoveTo::create(3.0,point_a));

Tweening with actionscript 3

I have been working on this one a while. I have an object in this case a movieClip called "mcBall". I set up two buttons "btnLeft" and "btnRight"with a tween so that the mcBall will ease between the two points smoothly.
Works fine, but where it gets glitchy is the the two buttons are still active an if the user clicks on either button of course the ball goes back to the starting point like it's supposed to.
My question is this ... What is the best way to have the buttons be de-activated while the "mcBall" object is moving. Would it be best to use a removeEventListener for the buttons and then have it added again. Would it be better to use an if statement like "If (mcBall.x = >=81 || <=469) removeEventListener"? Maybe use the tweenEvent.MOTION_FINISH to set up the eventListener again.
Any help would be greatly appreciated. Thanks
using Flash cs3
In this code I managed to turn off one button so that while the ball is moving it remains inactive but the other is still active. I'm not sure of the placement of the removeEventListener.
import fl.transitions.Tween;
import fl.transitions.easing.*;
function moveBallRight(evt:MouseEvent):void {
var moveBall:Tween=new Tween(mcBall,"x",Regular.easeOut,80,470,4,true);
btnRight.removeEventListener(MouseEvent.CLICK,moveBallRight);
btnLeft.addEventListener(MouseEvent.CLICK,moveBallLeft);
}
btnRight.addEventListener(MouseEvent.CLICK,moveBallRight);
function moveBallLeft(evt:MouseEvent) {
var moveBall:Tween=new Tween(mcBall,"x",Regular.easeOut,470,80,4,true);
btnRight.addEventListener(MouseEvent.CLICK,moveBallRight);
btnLeft.removeEventListener(MouseEvent.CLICK,moveBallLeft);
}
btnLeft.addEventListener(MouseEvent.CLICK,moveBallLeft);
Personally, I would recommend using the Actuate tween library. Unlike TweenLite/Max, it is fully opensource, and has most of the features, and is faster, with no pro/pay version.
I also like Actuate's interface much better than TweenLite. It is very similar so easy for people to start using it, but I like how tween modifiers are added in a more explicit way.
Simple example:
Actuate.tween(mySprite, 1, { alpha:1 });
Then is you want to specify an easing equation, just chain it on the end:
Actuate.tween(mySprite, 1, { alpha:1 }).ease(Quad.easeOut);
Want a delay as well? Add that to the chain:
Actuate.tween(mySprite, 1, { alpha:1 }).delay(1).ease(Quad.easeOut);
Of course you can also call a function onComplete, even with parameters:
Actuate.tween(mySprite, 1, { alpha:1 }).onComplete(trace, 'Tween finished');
Check out the Actuate Google Code page linked above for the full list of methods with examples.
I would recommend not using the native Tween class from fl.transitions.Tween. Its not very good. The industry standard is TweenMax from greensock.
Using TweenMax it is trivially easy to respond to end-of-tween events. You simply add an onComplete:myhandlerfunction to your tween.
An example from your above code would look like this:
Instead of
var moveBall:Tween=new Tween(mcBall,"x",Regular.easeOut,80,470,4,true);
You would have:
TweenMax.to(mcBall, 4, {x:470, ease:Expo.easeOut, onComplete:onBallMovedLeftComplete};
Hope that helps. And I hope you never have to use those native tween classes again. They are the pits.
I agree that you should use TweenLite or TweenMax as the other answers suggests.
From what I gather though, the question is the best approach in activating/deactivating your event listeners for the buttons.
I'd say the best approach is to have a function for adding your button listeners and another function for removing them.
Then, whenever you call a tween, you first call the removal function before executing the tween.
Then upon completion, you call the function to add them again. You can use the onComplete parameter with Tweenlite to specify the function to add the button listeners.
for example :
function moveBallRight(evt:MouseEvent):void
{
removeButtonListeners();
TweenLite.to(mcBall, 4, {x:470, ease:Expo.easeOut, onComplete:addButtonListeners};
}
function moveBallLeft(evt:MouseEvent):void
{
removeButtonListeners();
// do your tween
TweenLite.to(mcBall, 4, {x:80, ease:Expo.easeOut, onComplete:addButtonListeners};
}
function addButtonListeners():void
{
// add both listeners here
}
function removebuttonListeners():void
{
// remove both listeners here
}
Also, you'd obviously want to call addButtonListeners at the beginning of your program as well, so that the listeners are initially active when the program runs.

Set a button to invisible once clicked

I'm trying to set a button to invisible in AS3 however when the I leave the frame and come back to it the button is visible again. This is for a jeopardy game I make making for comm tech class.
Here is what I currently have:
a1.addEventListener(MouseEvent.CLICK, a1mouseClick);
function a1mouseClick(mouse:MouseEvent) {
a1.visible = false;
gotoAndStop("A1");
trace("Going to A1");
}
however when it comes back to the frame with the a1 button it is visible again.
Here is my current animation: https://dl.dropbox.com/u/23938245/jeporady.fla
While moving through the timeline flash player can recreates sprites, movie clips and text fields, so your buttons appears visible again. To prevent recreation move all controls to separate level without key frames. If key frames are required try to set the same instance name for this button in all keyframes.
#fsbmain and #prototypical they are right.
While moving through the timeline flash player can recreates sprites, movie clips and text fields, so your buttons appears visible again. To prevent recreation move all controls to separate level without key frames. If key frames are required try to set the same instance name for this button in all keyframes.
I was looking at your project, and offer a quick fix, you need to do the following:
Create a new layer on top to manage a few of actions availables for all frames with the following actions:
import flash.display.DisplayObject;
// Manages the buttons visible state
var buttonsStates:Object = {
"a1":true, "b1":true, "c1":true, "d1":true, "e1":true,
"a2":true, "b2":true, "c2":true, "d2":true, "e2":true,
"a3":true, "b3":true, "c3":true, "d3":true, "e3":true,
"a4":true, "b4":true, "c4":true, "d4":true, "e4":true,
"a5":true, "b5":true, "c5":true, "d5":true, "e5":true
};
// Checks the buttons visibility
function checkVisibility () {
for (var buttonName:String in buttonsStates)
{
var child:DisplayObject = this.getChildByName(buttonName);
child.visible = buttonsStates[buttonName];
}
}
// Saves the visible satatus to false
function setVisibilityToFalse(target:*) {
buttonsStates[target.name] = false;
target.visible = false;
}
Every time you want to check the visibility of the buttons you must call the checkVisibility() function. For example, every time you return to the button list.
Finally the event handler for each button must be like this:
function a1mouseClick(mouse:MouseEvent) {
setVisibilityToFalse(mouse.currentTarget); // Saves the visible state to false
gotoAndStop("A1");
trace("Going to A1");
}
You can download the edited file here http://cl.ly/Lt6X
You are missing a fundamental aspect of how the flash timeline and keyframes function. Once you move away from that frame, the stage instance of the content of that frame and it's properties/states are gone. When you return to that frame, the instance is created again based on the keyframe contents.
I think the best solution given your current approach is to put the main board persistent throughout all the frames. You can do that by creating a layer for it, and have it's keyframe extend from frame 2 to frame 27. However, your next issue will be adjusting visibility of all the elements on that screen when you don't want them visible.
My suggestion would be to put all the elements of that screen into a movieclip symbol of it's own and add that movieclip, and all code for it's listeners, to this new layer you created. For example you might name that instance - main_board and therefore you could modify it's visibility with main_board.visible property. If you did choose that solution, you would need to modify all the code on that frame to use that instance name as well ie :
main_board.a1.visible = false;
Also, you'd need to modify all you addEventListener lines as well :
main_board.a1.addEventListener(MouseEvent.CLICK, a1mouseClick);
Your approach for this game could be greatly simplified, but even further beyond the scope of this question than I have already gone!

currentFrame identifiers [AS3]

I'm completely new to Flash and AS3, and I'd have thought this would be a simple question, but I've been unable to find an answer online or in the documentation. I'm trying to use addEventListener (Event.ENTER_FRAME) and (.currentFrame) to disable a button for part of an animation sequence. While the animation sequence fades in, the Button Hand cursor is visible and people can select it before the sequence is completed. I want this button disabled for the first 213frames of the main timeline, which is when the button becomes visible.
Earlier, I was successfully able to disable a Rewind button for parts of a different movie scene using the code below with a few insignificant things changed.
Skip_btn.addEventListener(MouseEvent.CLICK, SkipToGoToScene);
function SkipToGoToScene(event:MouseEvent):void
{
MovieClip(this.root).gotoAndPlay(1, "Opening");
}
//Skip_btn functions
Skip_btn.addEventListener(Event.ENTER_FRAME, skipDisable);
function skipDisable(event:Event) {
if (this.currentFrame < 213)
{ Skip_btn.mouseEnabled = false;
} else {
Skip_btn.mouseEnabled = true;
}
if (this.currentFrame > 213) {
Skip_btn.removeEventListener(Event.ENTER_FRAME, skipDisable);
}
}
The problem is that before I could just use "this.currentFrame" as the button was on the same timeline that it controlled, whereas now it's embedded in a MovieClip that is on the main timeline. What can I swap "this" for so I can reference this main timeline? Also, could someone fill me in on what the other "identifiers" are for ".currentFrame", as I'm not too sure how it works. The documentation examples ask for Movieclips such as "MyMovie_mc.currentFrame", but what if you just want to reference a main timeline?
If the button is on main timeline you could just use
this.root.getChildByName("Skip_btn").mouseEnabled = true;
And if you start playing animation on main timeline use
MovieClip(this.root).currentFrame