I would like to remove a child x amount of seconds after it is created. How can I do this?
The child is created inside of a function.
Basically, something like this...
function makechild() {
addChild(thechild);
thechild.x=240;
thechild.y=330;
// what should go here? so it deletes after x seconds?
}
Use a one-time timer via flash.utils.setTimeout() like this:
setTimeout(dropChild,seconds*1000);
...
function dropChild():void {
removeChild(thechild);
}
With Actionscript 2 you would use setInterval. However, the Actionscript 3 way is to use the Timer class, like so:
function makechild() {
addChild(thechild);
thechild.x=240;
thechild.y=330;
// add a timer to "thechild" that will trigger it to be deleted
thechild.selfdestruct:Timer = new Timer(1000, 1); // 1 second
thechild.selfdestruct.addEventListener(TimerEvent.TIMER, deleteobject);
thechild.selfdestruct.start();
}
function deleteobject(event:TimerEvent):void {
// delete the child object, below is one example
this.parent.removeChildAt(0);
}
You can get lots more details on the Timer class from the Actionscript documentation. For more info about the Timer class vs. setInterval see this link:
http://blogs.adobe.com/pdehaan/2006/07/using_the_timer_class_in_actio.html
Related
My aim is to change the frame rates of my individual (looping) movie clips through clickable controls (slow/med/fast). I've heard it isnt possible to achieve this through as3/flash alone, so I've tried greensock's TweenMax... However I can't seem to figure out how to do this. Is there anyone that could help?
box1.addEventListener(MouseEvent.MOUSE_DOWN, box1down);
function box1down(event:MouseEvent):void {
//FRAMERATE CODE HERE
}
Many thanks!
Here is the API doc for TweenMax: http://www.greensock.com/as/docs/tween/com/greensock/TweenMax.html
If you have multiple movieclips that you are trying to control, you can just create an abstract class with the functionality you want and extend that class. So something like:
public class ControlledMovieClip extends MovieClip {
public function ControlledMovieClip() {
stop();
}
public function animate(frameRateInSeconds:Number):void {
TweenMax.to(this, frameRateInSeconds, { frame: this.totalFrames - 1, repeat: -1, ease: Linear.easeNone });
}
}
Have all your movieclips that are looping extend that class, and then you could call the animate function on the objects in your box1down event handler.
I haven't tested that code so you might need a gotoAndStop(1) at the end of each iteration.
It's possible through Actionscript alone it just requires you to handle the frame progression yourself (instead of using mc.play() you stop the movieclip and call nextFrame() yourself).
Lets say a Movieclip (myMC) has 20 frames of animation. To manually run the animation at normal speed you simply call myMC.nextFrame(); on every frame of your project (using an ENTER_FRAME listener for example).
To have the animation run at half speed you can use a frame count and a frame trigger:
var frameTick = 0;
var frameAnimTrigger = 2;
function Update(e:Event):void
{
frameTick++;
if(frameTick == frameAnimTrigger)
{
myMC.nextFrame();
frameTick = 0;
}
}
Because nextFrame is only called every other frame the animation appears to run at half speed.
This is my original pseudo code:
function1();
function1():void{
//do something
after mouseclick do function2
}
function2():void{
//do something
after animationfinish do function3
}
etc..
Can I get it into something like this?:
function1();
after mouseclick do function2()
after animationfinish do function3()
What is an easy way to get listeners on the top level?
If I understand your question correctly, when function1 is called you want to addEventListener(MouseEvent.CLICK, function2);
Are you using Actiosncript to animate or Keyframes?
I know with TweenMax you can add a function to call at the end of the tween. If using fl.Transtions.Tween you can listen for TweenEvent.MOTION_FINISH and then call function3. I don't mess much with the timeline in Flash, since I feel more in control with coding it, but I know you can add code at the last frame of an animation to call function3.
If I am completely missing you question feel free to clarify what exactly you are seeking.
If i good understand - You like to create functions chain .
I depends what You like to do , problem is in many possibilities.
For call few functions i use this class :
https://github.com/turbosqel/as3SupportLib/blob/master/as3SupportLib/src/turbosqel/utils/CountCall.as
You can also use deeper and more elastic way and add next callbacks to function :
var func:Function = function():void { // declare new function
... function body // your class actions
for each(var call:Function in arguments.callee){ // get functions
call(); // call function
}
}
func["someFunction"] = someFunction; // add function as dynamic value
func["otherFunction"] = anotherFunctionToCall; // add another function
func(); // call function
I'm not sure if the way I did makes the garbage collector remove the timer. Here are my two functions:
public function newWave() {
var callTimer:Timer = new Timer(800);
callTimer.start();
leftToSpawn = 4;
callTimer.addEventListener(TimerEvent.TIMER,waveCall);
}
public function waveCall(e:TimerEvent) {
leftToSpawn--;
if(leftToSpawn <= 0){
e.target.stop();
e.target.removeEventListener(TimerEvent.TIMER_COMPLETE,waveCall);
}
spawnEnemy();
}
Thanks
To remove an event listener you need to remove it with the exact same signature.
If you do:
.addEventListener(TimerEvent.TIMER,waveCall);
Then you need to use the same event type and function to remove it:
.removeEventListener(TimerEvent.TIMER,waveCall);
Using TimerEvent.TIMER_COMPLETE here will try to remove a listener that doesn't exist, which is silently ignored.
Using target here is ok, for other listener types you may need to use currentTarget, which is always the object the listener got added to. For example in a mouse click event, target could be a child of a MovieClip and without any listeners.
Moreover, timer already has ability to repeat specified number of times and the correct code will be like this:
public function newWave() {
var callTimer:Timer = new Timer(800, 4); //repeat 4 times
callTimer.start();
callTimer.addEventListener(TimerEvent.TIMER,waveCall);
}
public function waveCall(e:TimerEvent) {
spawnEnemy();
}
just change:
e.target.removeEventListener(TimerEvent.TIMER_COMPLETE,waveCall);
to
e.target.removeEventListener(TimerEvent.TIMER,waveCall);
I have 6 instances of a moiveClip. when one is clicked, i need to write a function that affects all other instances of the movieClip, and not affect the one being clicked.
What is the most efficient way of doing this? Im thinking something to do with event class for sure.aa
Put a single event handler on all of them and do something like this:
private function onClickMovieClip(event:MouseEvent):void
{
for (/*run through your clips*/)
{
if (event.target != /*current clip*/)
{
doSomething();
}
}
}
I want to run some code whenever a DisplayObject is added as a child to a DisplayObjectContainer.
Or to put in other words, to catch the addedToStage event of all DisplayObjects, even ones I don't know about.
Is it possible? and if not, any ideas on how to do something similar?
An 'added' event is dispatched whenever a child display object is added to the display list via addChild() or addChildAt(). In the DisplayObjectContainer class add the listener:
addEventListener(Event.ADDED, onAdded);
and the handler:
private function onAdded(e:Event):void
{
trace('number of children is now ' + numChildren);
}
Using Event.ADDED_TO_STAGE on stage Object and setting useCapture to true.
More info on event here
Example:
function onAdded(e:Event):void{
trace(e.target.toString()); //use target to get the Object added
}
stage.addEventListener(Event.ADDED_TO_STAGE, onAdded, true); // set capture to true
I don't know if there is a built in way to do this.
Alternatives include the obvious,
private var _num_children:Number = 0;
addEventListener(Event.ENTER_FRAME, _checkChildren, false, 0, true);
private function _checkChildren($evt:Event):void {
if (this.numChildren != _num_children) {
_num_children = this.numChildren;
// There was a child (or more) added in the last frame execution
}
}
However, this seems like a more elegant solution...
public function _addChild($do:DisplayObject) {
$do .addEventListener(Event.ADDED_TO_STAGE, _childAdded);
addChild($do );
}
private function _childAdded($evt:Event) {
// do whatever with $evt.target
}
The difference here, is the _childAdded will get fired for each and every child added via _addChild method. This means if you are doing some costly code execution you will be doing it once for each child instance.
If you use the first method, you are only calling the method once per frame, and if 10 images are added on a single frame, then it will only run once.