effcient Event dispatchinging in Actionscript 3 - actionscript-3

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

Related

How to make a click run two functions in actionscript 3?

I was wondering if it was possible to call two different functions from one mouse event, like click. I figured it might just be something like:
button.addEventListener(MouseEvent.CLICK, function1 && function2);
Unfortunately that doesn't work. Do i need to call a new function that contains those two?
For example
button.addEventListener(MouseEvent.CLICK, function3);
function function3(){
function1();
function2();
}
The latter seems very inefficient so i assume there is a way to do it like the prior.
You can either do that or register two Click event handlers, or you could write the function inline (inside the addEventListener) such as
button.addEventListener(MouseEvent.Click, function(e:Event):void {
function2();
function3();
}):

Can I pass a button into its own MouseEvent function?

I have multiple MovieClip Symbols published with Flash into FlashDevelop (I'll only use 2 in my example). Each have 3 frames for default, hover and click that I'm using as buttons.
private var btnPlay:PlayButton, btnQuit:QuitButton;
btnPlay = new PlayButton();
btnQuit = new QuitButton();
btnPlay.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler);
btnPlay.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler);
btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, onPressHandler);
btnPlay.addEventListener(MouseEvent.MOUSE_UP, onReleaseHandler);
btnPlay.buttonMode = true;
btnPlay.useHandCursor = true;
function onRollOverHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(2);
}
function onRollOutHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(1);
}
function onPressHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(3);
}
function onReleaseHandler(myEvent:MouseEvent):void {
btnPlay.gotoAndStop(2);
}
// Same code for btnQuit here, but replace btnPlay with btnQuit
Instead of adding new EventListeners to every button that do practically the same thing like what I'm doing above, is there a way I could just pass in the button itself to the MouseEvent functions something like this? (I realize this might be difficult since all buttons are their own class)
btnPlay.addEventListener(MouseEvent.ROLL_OVER, onRollOverHandler(btnPlay));
btnPlay.addEventListener(MouseEvent.ROLL_OUT, onRollOutHandler(btnPlay));
btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, onPressHandler(btnPlay));
btnPlay.addEventListener(MouseEvent.MOUSE_UP, onReleaseHandler(btnPlay));
function onRollOverHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(2);
}
function onRollOutHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(1);
}
function onPressHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(3);
}
function onReleaseHandler(myEvent:MouseEvent, inButton:MovieClip):void {
inButton.gotoAndStop(2);
}
Maybe I am misunderstanding, but "event.target" provides you a reference to the button that has been clicked. So if you want to do something to the clicked button, you would write:
myEvent.target.gotoAndStop(1);
Or sometimes you might need to use "currentTarget". You'd still need to create listeners for each function but could use one set of handlers.
Simple answer: No. You could go to some trouble to override the MouseEvent class and allow it to send additional parameters, but why bother in this case? You don't seem to be saving any code.
SLIGHT UPDATE:
Here's a possibly-useful simplification of your original code. It saves a few lines-of-code and uses just a single handler function. Obviously, the 'trace' statements could be replaced by various 'gotoAndStop()' statements:
btnPlay.addEventListener(MouseEvent.ROLL_OVER, HandleAll);
btnPlay.addEventListener(MouseEvent.ROLL_OUT, HandleAll);
btnPlay.addEventListener(MouseEvent.MOUSE_DOWN, HandleAll);
btnPlay.addEventListener(MouseEvent.MOUSE_UP, HandleAll);
function HandleAll(e)
{
if (e.type == "rollOver") trace("rollover");
if (e.type == "rollOut") trace("rollout");
if (e.type == "mouseDown") trace("mousedown");
if (e.type == "mouseUp") trace("mouseup");
}

Remove a child after x amount of seconds? AS3

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

Startdrag is not a function

this.addEventListener(MouseEvent.MOUSE_DOWN,function(e:MouseEvent){this.startDrag(false,null);});
Hi I was wondering why the above doesnt work? Im trying to drag a sprite around screen.
create a sprite on stage, add instance name box, add code to frame one:
box.addEventListener(MouseEvent.MOUSE_DOWN, startMove);
function startMove(evt:MouseEvent):void {
box.startDrag();
}
box.addEventListener(MouseEvent.MOUSE_UP, stopMove);
function stopMove(e:MouseEvent):void {
box.stopDrag();
}
I think your example doesn't work because of the scope of "this" in the event listener handler.
If you remove this.; it will work. It's a scope issue since you use an anonymous function.
You could use the currentTarget of the event, this allows you to make other boxes draggable too, if you add the same listeners.
Note: It is hard to remove an anonymous function as event listener and could cause memory leaks, so the best way is to use a reference to a named function:
box.addEventListener(MouseEvent.MOUSE_DOWN, handleMouseEvent);
box.addEventListener(MouseEvent.MOUSE_UP, handleMouseEvent);
function handleMouseEvent(event:MouseEvent):void
{
switch(event.type)
{
case MouseEvent.MOUSE_DOWN:
{
DisplayObject(event.currentTarget).startDrag();
break;
}
case MouseEvent.MOUSE_UP:
{
DisplayObject(event.currentTarget).stopDrag();
break;
}
}
}

Is this the correct way to remove a timer?

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