MOUSE OUT is being called inside MovieClip - actionscript-3

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.

Related

Actionscript: BlitMask stopping mouse event listeners from working, how to fix?

I have a button class which contains event listeners to trigger an animation of the button on click.
I used many instances of this class to form a list which the user can scroll through. I have implemented BlitMask, this works, however the mouse event listeners in the button class no longer work. This code
_blit = new BlitMask(_mc, _obounds.x, _bounds.y, _bounds.width, _bounds.height, false);
Is what stops the button class.
How can I get the behaviour pre blitmark?
My code which creates the bottom is
var tf:TextField = new TextField(text);
tf.x = 70;
tf.y = 20;
_btn.addChild(tf);
_btn.addEventListener(MouseEvent.CLICK, click);
click is never called.
The blitmask causes the movieclip to be nothing more than an image of clip.
bitmapMode must be set to false to correct this.
_blitMask.bitmapMode = false;
EDIT: To expand on a further issue that implementing this solution causes, turning bitmapMode on only when needed causes the bitmap to not reflect changes in the classes that changed while bitmapMode was off. So you must set
_blitMask.update(null, true);
To force a full update when you use
_blitMask.bitmapMode = true;

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".

AS3 MouseEvent and weakReference

Ok, here's a weird thing:
I have a class, which is a MovieClip that has 2 children, MovieClips also.
I add the children to him and base MovieClip to stage.One of the children is animated.
All is perfect.
Now when I add MouseEvent.MOUSE_UP on the children, all works fine.
Yet if I set useWeakReference to true (the 5th parameter) mouse event does not fire anymore,but the items are on stage. Basically, somehow, they are not in the memory.
Of course if I add a simple onEnterFrame that does nothing to base MovieClip, it traces the MovieClip, yet the MouseEvents does not trigger. That means the object is still there, but somehow for flash is not
Now, this is a simplified concept, that is easy to clean, but my code is very big and a simple removeEventListener is not a solution. At least not a simple one.
What are your suggestions to work around this?
I'm not sure how complex your code is, but if each movieclip has MOUSE_UP event handler - some function, you could indeed use removeEventListener MOUSE_UP function. For instance:
var mc:MovieClip = new MovieClip();
mc.addEventListener( MouseEvent.MOUSE_UP, onMU );
function onMU(e:MouseEvent){
var target = MovieClip(e.currentTarget);
target.removeEventListener( MouseEvent.MOUSE_UP, onMU );
}
This way you can have multiple movieclips and remove listeners without knowing object name.
Alternatively you could modify your code to add aray of all added events and then listen to REMOVE_FROM_STAGE event. Something like this:
var mc:MovieClip = new MovieClip();
mc.events = [];
mc.events.push( { evt: MouseEvent.MOUSE_UP, fn: onMU } );
mc.addEventListener( MouseEvent.MOUSE_UP, onMU } )
//or use events array reference to keep events and functions in one place.
//when object is removed you can iterate through events array and automatically remove
//all listeners
Another alternative would be to create Class that extends MovieClip - but since your code is huge you probably don't want to do that.
You can also look on Robert Penner's Signals library, which is interesting alternative to AS3 events. (https://github.com/robertpenner/as3-signals)

Looping problem in AS3 when using ROLL_OVER

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.

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.