Looping problem in AS3 when using ROLL_OVER - actionscript-3

So basically I am trying to make a banner that adds and removes a movie clip on ROLL_OVER and ROLL_OUT with a button. I have the movie clip created, and the button, and it works fine if I only use ROLL_OVER. As soon as I add an eventListener for ROLL_OUT, it loops the functions like crazy and the movie clip keeps flashing on and off. I know I am missing something simple, but I can't get my mind around what. Here's the code:
var MySmiles:smilesEvery=new smilesEvery();
buttonSmiles_btn.addEventListener(MouseEvent.ROLL_OVER, smiles, false, 0, true);
function smiles(myevent:MouseEvent):void {
this.addChild(MySmiles);
};
buttonSmiles_btn.addEventListener(MouseEvent.ROLL_OUT, smilesOUT, false, 0, true);
function smilesOUT(myevent:MouseEvent):void {
this.removeChild(MySmiles);
};
Any thoughts?

removing listeners might help:
var MySmiles:smilesEvery=new smilesEvery();
buttonSmiles_btn.addEventListener(MouseEvent.ROLL_OVER, smiles, false, 0, true);
buttonSmiles_btn.mouseChildren = false //to be shure, that one of the childs interfire with mouse events
function smiles(myevent:MouseEvent):void {
this.addChild(MySmiles);
buttonSmiles_btn.addEventListener(MouseEvent.ROLL_OUT, smilesOUT, false, 0, true);
};
function smilesOUT(myevent:MouseEvent):void {
buttonSmiles_btn.removeEventListener(MouseEvent.ROLL_OUT, smilesOUT, false,0,true);
this.removeChild(MySmiles);
};

My guess: on roll over you show a clip, that overlaps your button.
Hence, you get an immediate roll out on the button.
Which in turn causes your button to recieve roll over again.
That causes a recursive stack overflow. :)
If the above holds true, just disable mouse on MySmiles.
Both mouseChidren and mouseEnabled.

Related

MOUSE OUT is being called inside MovieClip

I added a MOUSE_OVER event listener to my MovieClip, then i added MOUSE_OUT just like this :
mc.addEventListener(MouseEvent.MOUSE_OVER, boxItemMouseOver, false, 0, true);
protected function boxItemMouseOver(e:MouseEvent):void
{
trace("mouse over");
var boxItem:MovieClip = e.currentTarget as MovieClip;
boxItem.addEventListener(MouseEvent.MOUSE_OUT, boxItemMouseOut, false, 0, true);
boxItem.removeEventListener(MouseEvent.MOUSE_OVER, boxItemMouseOver);
}
protected function boxItemMouseOut(e:MouseEvent):void
{
trace("mouse out");
var boxItem:MovieClip = e.currentTarget as MovieClip;
boxItem.addEventListener(MouseEvent.MOUSE_OVER, boxItemMouseOver, false, 0, true);
boxItem.removeEventListener(MouseEvent.MOUSE_OUT, boxItemMouseOut);
}
But whenever i move the mouse inside my MovieClip, the MOUSE_OUT event function is being called, although i still didn't leave the area taken by the MovieClip.
I managed to find out where my Problem is, but still can't fix it, i'm adding to my SWF a Cursor that replaces the icon of the mouse (I hide the mouse), once i add it the problem occurs, here is a simple example.
Code : Simple Source Code, Couple of classes
Set mouseChildren to false on boxItem.
1.. u have 'trace("mouse over")' in both functions
2.. first remove mouse over listener, than add mouse out listener
3.. i don't get, why do u need to declare new variable 'boxItem' when u can just write e.target.removeEventListener(..)
4.. it's impossible what u are talking, i caught several unnecessary code in few lines, so there is big chance u are doing somth wrong in your code, show us bigger piece of your code..
p.s. also, try mouseEnabled to false along with mouseChildren to false, but i doubt it will work
Listen for ROLL_OUT instead. MOUSE_OUT is dispatched when cursor left any of the nested chidlren of you MovieClip.

Remove a MouseEvent.MOUSE_MOVE event listener if no user interaction occurs

I'm new to AS3 and need help figuring out how to remove my MouseEvent.MOUSE_MOVE listener if no user interaction occurs.
I have built an animation that does the following:
A solid line and some text appear on top of an image. After this finishes a mouse event is enabled that allows the user to move the line up and down. When the user stops interacting with the line, the line disappears and the final screen of the animation appears.
In the event that the user does not interact with the animation at all (the line never moves), I need to incorporate some way to remove the event listener, then have the final screen of the animation appear. I think adding a TimerEvent is the correct approach for doing what I want, but I'm not sure how to incorporate it. This also may not be the best or correct method. In that case, does anyone have suggestions as to what should be done?
Any help will be appreciated!
Here is my code:
import com.greensock.*;
//objects on the stage
line_mc.y=250;
raisingTxt.alpha=0;
arrow_mc.alpha=0;
final_mc.alpha=0;
logo_mc.alpha=1 ;
//move line mc to y:125
TweenLite.to(line_mc, 1, {y:125});
TweenLite.to(raisingTxt, .5, {alpha:1, delay:1.2});
TweenLite.to(arrow_mc, .5, {alpha:1, delay:1.2, onComplete:followMouse});
//calls MouseEvent onComplete of tween
function followMouse() {
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveIt);
}
function moveIt(e:MouseEvent):void {
TweenLite.to(line_mc, 0.5, {y:this.mouseY});
TweenLite.to([raisingTxt,arrow_mc], 0.5, {alpha:0, onComplete:finalScreen} );
}
//calls final screen onComplete of MouseEvent
function finalScreen() {
TweenLite.to(line_mc, 0.5, {alpha:0} );
TweenLite.to(final_mc, 0.5, {alpha:1} );
}
You can accomplish this with the built in Timer class. I like it a bit more than the setTimeout function because it's simpler to manage.
First create a class wide variable (assuming you are doing this in the Flash IDE, just create it near the top)
var timeout:Timer;
Then in your followMouse():
private function followMouse():void {
timeout = new Timer( 3000, 1 );
timeout.addEventListener( TimerEvent.TIMER_COMPLETE, removeMouseListener );
timeout.start();
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveIt);
}
Last create the removeMouseListener():
private function removeMouseListener( e:Event=null ):void {
timeout.removeEventListener( TimerEvent.TIMER_COMPLETE, removeMouseListener );
stage.removeEventListener(MouseEvent.MOUSE_MOVE, moveIt);
}
If you want to keep resetting the timer every time the mouse moves, you can add these two lines to your moveIt():
timeout.reset();
timeout.start();
I made the removeMouseListener() have an optional parameter so you can call it any time regardless of the timer.
Hope that helps! Good luck!

How to do "if Single Click" instead of "if MouseDown" in AS3?

I want to do a single click and have it not repeat the function if my mouse is still down if that makes any sense.
Currently I have it:
if (mouseDown)
{
avatar.moveABit( 0, -2);
sfxSoundChannel = moveSound.play();
}
and if I keep my Mouse Down it keeps repeating that. I want it to only work with a single click, and have to keep tapping to do it instead of leaving the mouse down.
You probably want
MouseEvent.MOUSE_CLICK
I would add an event listener on the object that is being clicked to listen for the click, and on the click run the handler function which would contain your move and soundplay code.
See this documentation.
You need MouseEvent.CLICK like so:
//Create a function (which moves avatar) to be called on mouse click
function moveAvatar(e:MouseEvent):void
{
avatar.moveABit( 0, -2);
sfxSoundChannel = moveSound.play();
}
stage.addEventListener(MouseEvent.CLICK, moveAvatar); //add mouse click event listener
EDIT: moveABit should not be using ENTER_FRAME event.
I don't know if I understood it correctly, maybe we'll need more of your code to understand what you really want.
I'm assuming that you're using some kind of loop (setInterval, Event.ENTER_FRAME) to check if the mouse button is down or not. If you are, I think you should change that to only fire inside a function like this:
function OnMouseDownHandler(event:MouseEvent):void
{
avatar.moveABit( 0, -2);
sfxSoundChannel = moveSound.play();
}
stage.addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDownHandler, false, 0, true);
If you use MouseEvent.CLICK event the OnMouseDownHandler Method will be fired only when you release the mouse button, using MouseEvent.MOUSE_DOWN will behave more like a "Tap".

How can I remove an eventListener, AS3

On the first frame of my timeline, I have the following action script:
stop();
ClickTAG.addEventListener(MouseEvent.ROLL_OVER, manageMouseOver, false, 0, true);
function manageMouseOver(event:MouseEvent):void
{
play();
}
I am not really familiar with AS, but this accomplishes what I want, i.e., is to start the timeline on mouseOver. However, if you repeatedly mouseOver and Off the swf later, this can interrupt the animation later in the timeline, e.g., it will skip through timeline delays and restart the movie after the last frame.
How can I remove this listener or prevent it from operating after the movie reaches the second frame? I less than basic understanding of AS, so thanks for you help.
function manageMouseOver(event:MouseEvent):void{
event.currentTarget.removeEventListener(event.type, manageMouseOver);
play();
}
This simple code is able to remove an event right after it's being called.
Handy way to removing event listeners in AS3
function manageMouseOver(event:MouseEvent):void
{
event.currentTarget.removeEventListener(event.type, arguments.callee);
play();
}
For more details arguments.callee docs
Removing listener from the object itself in your case:
stop();
ClickTAG.addEventListener(MouseEvent.ROLL_OVER, manageMouseOver, false, 0, true);
function manageMouseOver(event:MouseEvent):void
{
ClickTAG.removeEventListener(MouseEvent.ROLL_OVER, manageMouseOver)
play();
}

Actionscript 3: Preventing mouse events *except* for a specific button/movieclip?

Is there a way to block mouse events except for a specific MovieClip or Sprite?
i.e. I know that to prevent ALL mouse clicks, I can write something like:
stage.addEventListener(MouseEvent.CLICK, onPreventClick, true, 0, true);
...
private function onPreventClick(e:MouseEvent) {
e.stopImmediatePropagation();
e.preventDefault();
}
You can check e.currentTarget to find the object who fired the Event and doing your filtering according to that.