AS3 - Unable to capture button click when using Mouse Move listener - actionscript-3

In my first AS3 project (not used Flash since AS1) I need to use a custom movie clip as a cursor and detect clicking on a button. Using the code below, the custom cursor works as expected, but I am unable to capture clicking on the button.
If I comment out the first line, the trace for clicking works as expected. I have tried changing the order of the event listeners, applying the follow to the button rather than the stage, but cannot get both to work together.
Any advice as to where I'm going wrong ould be appreciated.
stage.addEventListener(MouseEvent.MOUSE_MOVE,follow);
start_button.addEventListener(MouseEvent.MOUSE_UP, playPhrase);
function playPhrase(event:MouseEvent) {
trace("Click received");
};
function follow(event:MouseEvent) {
cursor.x = mouseX;
cursor.y = mouseY;
};

Looks like that's because you always click on the cursor object as it always positioned right under mouse cursor. Make it "transparent" for mouse clicks:
cursor.mouseEnabled = false;
And if it's a DisplayObjectContainer then also:
cursor.mouseChildren = false;

Related

How to determine if the right mouse button is down or not in a MOUSE_MOVE event?

For the MOUSE_MOVE event, the documentation says there is a buttonDown property to indicate whether or not the left mouse button is currently down. But how can I determine if the right button is down?
There is not, but you can do this by setting a flag inbetween Right Mouse down and Right mouse up. If you listen on capture with a high priority, it will be available in all other mouse events.
In your document class or main timeline frame 1, add the following code:
var isRightMouseDown:Boolean = false;
stage.addEventListener(MouseEvent.RIGHT_MOUSE_DOWN, globalMouseDown,true,int.MAX_VALUE)
function globalMouseDown(e:MouseEvent):void {
isRightMouseDown = true;
}
stage.addEventListener(MouseEvent.RIGHT_MOUSE_UP,globalMouseUp,true,int.MAX_VALUE)
function globalMouseUp(e:MouseEvent):void {
isRightMouseUp = false;
}
Now you have a var you can access in your mouse move listeners. If using timeline code, access it outside the main timeline by doing MovieClip(root).isRightMouseDown. If using a document class, define it as static public static var isRightMouseDown:Boolean and access it like so from anywhere in your app: MyMainClassName.isRightMouseDown. (replace MyMainClassName with whatever you've called your document class)
When you add the listeners above, putting the third parameter as true and the fourth parameter as int.MAX_VALUE will ensure this listener will be processed before any others listening for the same event in your application.
For more information about how events work and their phases, see this:
http://www.adobe.com/devnet/actionscript/articles/event_handling_as3.html

Flash Actionscript 3.0 Mouse Cursor Duplicates

I wrote a simple game and I want to add custom mouse cursor. I created MovieClip called Pointer, exported it to AS3 and wrote this code:
/* Custom Mouse Cursor
Replaces the default mouse cursor with the specified symbol instance.
*/
stage.addChild(movieClip_2);
movieClip_2.mouseEnabled = false;
movieClip_2.addEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor_3);
function fl_CustomMouseCursor_3(event:Event)
{
movieClip_2.x = stage.mouseX;
movieClip_2.y = stage.mouseY;
}
Mouse.hide();
//To restore the default mouse pointer, uncomment the following lines:
//movieClip_2.removeEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor_3);
//stage.removeChild(movieClip_2);
//Mouse.show();
Here is a screenshot:
Whenever I play the game (ctrl enter) it stops the play and duplicates the custom cursor. Is there anyway I can make it not duplicate this is very annoying and I have no idea on how to fix it.
~ EDIT 2 ~
Okay I changed the code to but the problem is now it's showing me the regular cursor and the custom one at the same time.
movieClip_1.mouseEnabled = false; movieClip_1.addEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor); function fl_CustomMouseCursor(event:Event) { movieClip_1.x = stage.mouseX; movieClip_1.y = stage.mouseY; } stage.removeChild(movieClip_1) Mouse.hide()
~ EDIT 3 ~
Thank you #LDMS for helping me. I had to remove the first line stage.addChild(movieClip_1); and it worked. :)
Most likely, your problem stems from this line:
stage.addChild(movieClip_2);
When you add a movie clip that was created on the timeline to another display object (like the stage), it will not get removed from that new display object except through code.
If your timeline loops, then every loop it will create a new movie clip and add it to the stage (but not remove the old one).
To fix it, do one of the following:
don't loop your timeline (so the code only happens once), eg put a stop() on your timeline
manually remove the movie clip from the stage before the timeline loops (eg stage.removeChild(movieclip_2) at the end of your timeline
Don't add it to the stage to begin with. (just take out the stage.addChild(movieClip_2); line)

RollOver and RollOut effect in buttons

I'm using the code bellow to change the color of button on rollover and rollout and clicked. I have following issues in this
1. The color did not changed when button is clicked.
2. Button wont work after once clicked.
pages.gotoAndStop("home");
// list of button instance names
var previousClicked:DisplayObject;
var buttonsss:Array = [home, menudown.about, menudown.portfolio, menudown.clients, menudown.pricing, menudown.contact];
for each ( var mc:MovieClip in buttonsss)
{
mc.buttonMode = true;
mc.mouseChildren = false;
mc.addEventListener(MouseEvent.MOUSE_UP, onClick);
mc.addEventListener(MouseEvent.ROLL_OVER, rolloverEffect);
mc.addEventListener(MouseEvent.ROLL_OUT, rolloutEffect);
}
function onClick(e:MouseEvent):void
{
pages.gotoAndStop(e.target.name);
e.currentTarget.mouseEnabled = false;
TweenLite.to(e.currentTarget,2,{tint:0x666666, ease:Strong.easeOut});
TweenLite.to(previousClicked,2,{tint:null , ease:Strong.easeOut});// set the previous clicked to null tint
previousClicked.addEventListener(MouseEvent.ROLL_OUT, rolloutEffect);// restore the Roll_Over effect
previousClicked = DisplayObject(e.target); // update the last clicked button
e.target.removeEventListener(MouseEvent.ROLL_OUT, rolloutEffect);
}
function rolloverEffect(e:MouseEvent):void{
TweenLite.to(e.currentTarget,2,{tint:0x666666, ease:Strong.easeOut});
}
function rolloutEffect(e:MouseEvent):void{
//should change tint to null just when its enabled, but its changing always (enabled or disabled)
TweenLite.to(e.currentTarget,2,{tint:null , ease:Strong.easeOut});
}
How I have always done this is with the built in buttons instead of doing it with code.
If you click window up in the top bar then click on components (near the bottom) it will bring up a little window then if you expand the user interface folder and drag and drop from the button item. Then with that button on the stage if you double click on it you will go into the edit symbol screen and it will have pictures of each state that the button and if you double click on the state you want then you can visually edit that version of the button.
Hope this helped.
Note: I first started with flash pro-cs5.5 and your tag says flash-cs5 I don't know for sure if that function is available or not in 5.
I am unfamiliar with Tweenlite, but I'm guessig that what it does in this case is simply change the color, am I right? If so, I'd suggest creating the color changes on your timeline and using framelabels combined with gotoAndStop to create the different effects. This should also solve your problem concerning the button not working after it has been clicked once.

add even-listener to a button on timeline that is a grand child of a movie clip

I got a simple flash scene that contain movie clip that contain sliding button that changing every few seconds:
every layer contain a button and another movie clip.
If I want to add event-listener to a simple button on stage, i just write:
f4.addEventListener(MouseEvent.CLICK, f4Click);
function f4Click(event:MouseEvent):void
{
flash.external.ExternalInterface.call("dlHTCMD", "switchtogame?code=fnf50");
}
but when I'm trying to access the button inside the two movie clips, like
optContainer.optBeach.btnBeach.addEventListener(MouseEvent.CLICK, btnBeachClick);
and I'm adding a trace function to see if the event are triggered but nothing is happening.
looks like a simple problem but i didn't find a solution.
I thought about extending the button class and add a bind function with the value as the name of the button and set the Event Listener but I'm not an AS3 expert :(
Thanks.
Try this:
// Pass mouse events to children
optContainer.mouseChildren = true;
optContainer.optBeach.mouseChildren = true;
// Reset hit area
optContainer.hitArea = null;
optContainer.optBeach.hitArea = null;
// Reset masks
optContainer.mask= null;
optContainer.optBeach.mask= null;
Also check whether on each key frame button have name.

Alternatives for registering Events on the stage in AS3?

I am programming a little software prototype as Flash/Actionscript3 application. Currently I registered some Events on stage - but it is cumbersome since stopPropoagation() needs to be used all the time.
As Example:
I am having a element shown via mouseclick would and a event for closing the menu on stage. Without using stopPropagation, the menu opens and closes again immediately. The hide-function is registered on some objects so just checking if target= stage would not do it, unfortunately.
Are there any good solutions to get around this?
So you have a listener for a MOUSE_CLICK on the stage thats getting fired when you click on an 'element'.
Which looks something a bit like:
addEventListener(MouseEvent.CLICK, onClick)
function onClick(e:MouseEvent)
{
trace("CLICK")
}
mc.addEventListener(MouseEvent.CLICK, onMcClick)
function onMcClick(e:MouseEvent)
{
trace("mc")
e.stopPropagation();
}
If thats the case then yes, stage will always recieve this event since it has to do with how native flash events propogate and bubble. http://www.adobe.com/devnet/actionscript/articles/event_handling_as3_03.html
Instead of listening to the stage and having to call stopPropogation you can restructure your code. You will need to remove the listener on the stage and instead add it to the actual item so:
mc2.addEventListener(MouseEvent.CLICK, onClick)
function onClick(e:MouseEvent)
{
trace("CLICK")
}
mc.addEventListener(MouseEvent.CLICK, onMcClick)
function onMcClick(e:MouseEvent)
{
trace("MC 2 CLICK")
}
Of course this might then require you to change some of your other code but since I can't see it I am not sure what that is. Just remember that events propogate and bubble. So if you had a movieclip 'c' inside a movieclip 'b' thats on stage, and both c and b have listeners for a MOUSE_CLICK then if you click on c then both b and c events will recieve this event since it bubbles up the display list. But if c was not in b but c was on the stage and b was on the stage then this would not happen since b is not on the path for the bubbling of c. Hope that helps :)
1 solution is to check stage.focus , that is if when the menu opens the focus is on it you can add a focus out event listener so when the stage is clicked and the menu loses focus it will close .