AS3: change handcursor graphic on buttons - actionscript-3

I would like to replace the little handcursor that appears when hovering over movieclips with buttonMode=true by a custom graphic.
Is there any way to do this globally for my whole application or do I have to go to every single button, add MOUSE_OVER, MOUSE_OUT and MOUSE_MOVE handlers which will hide and show the mouse cursor as well place the handgraphics over it and position it correctly?
seems tedious...

There seems to be a way to change the native cursor; http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/Mouse.html#registerCursor()
But you would have to target flash player 10.2+ only...

You could write a single set of MOUSE_OVER, MOUSE_MOVE and MOUSE_OUT handlers that do the replacement and positioning as you described but then add listeners to all your buttons that point to these handlers. Remember, the same handlers can be used for multiple objects.
Or alternatively, assuming your 'buttons' are MovieClips, you could write a custom ActionScript class that extends MovieClip, defines this default functionality and then have all your button instances use this class as a base. See below:
public class ButtonMovieClip extends MovieClip {
public function ButtonMovieClip() {
addEventListener(MouseEvent.MOUSE_OVER, buttonOver);
addEventListener(MouseEvent.MOUSE_OUT, buttonOut);
addEventListener(MouseEvent.MOUSE_MOVE, buttonMove);
}
public function buttonOver(event:MouseEvent) {
//Hide mouse and add replacement graphic
}
public function buttonOut(event:MouseEvent) {
//Show mouse and remove graphic
}
public function buttonMove(event:MouseEvent) {
//Position graphic where mouse should be
}
}
The key then is to ensure all your buttons are created from this class (either by code or from within the Flash IDE).

Related

Why do my buttons only work on the first frame of the main timeline in Flash AS3?

I'm trying to code the navigation of a Flash AS3 project in an actionscript file. In the project there are several frames with buttons to navigate through the project. The ones I have coded for the first frame work, but on any other frame they don't.
here is the code:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Main extends MovieClip
{
public function Main()
{
trace("it's working");
btn_one.addEventListener(MouseEvent.MOUSE_UP,eventResponse1);
btn_two.addEventListener(MouseEvent.MOUSE_UP,eventResponse2);
btn_three.addEventListener(MouseEvent.MOUSE_UP,eventResponse3);
btn_four.addEventListener(MouseEvent.MOUSE_UP,eventResponse4);
btn_five.addEventListener(MouseEvent.MOUSE_UP,eventResponse5);
btn_six.addEventListener(MouseEvent.MOUSE_UP,eventResponse6);
}
function eventResponse1(evt:MouseEvent):void
{
gotoAndStop("game");
}
function eventResponse2(evt:MouseEvent):void
{
gotoAndStop("specimenroom");
}
function eventResponse3(evt:MouseEvent):void
{
gotoAndStop("how");
}
function eventResponse4(evt:MouseEvent):void
{
gotoAndStop("game");
}
function eventResponse5(evt:MouseEvent):void
{
gotoAndStop("feedback");
}
function eventResponse6(evt:MouseEvent):void
{
gotoAndStop("home");
}
}
}
In the code the first five buttons work, but the sixth doesn't. This button is not located on the first frame of the main timeline, it's on the second and third frame. It doesn't work at all. What code is needed to get them to work? Any help is much appreciated, thank you.
The button must be present on the frame that the AS3 code gets executed on.
For example, if your button is on frame 2 and your code that tries to add the listener is on frame 1, that will not work.
I assume you are using a Document class, so the same applies. Only what is present on the stage at the time that constructor code runs, is available for you to work with.
What you could do is have a method that adds listeners to the appropriate buttons when you go to that frame.
There are other solutions that would require a more radical change to your current design of using the timeline to change screens, so I suggested the one that would require minimum change.
Because you asked in comments another possible solution is to not navigate through your different screens via timeline frames, but instead do it via code and MovieClip symbols that contain your UI screens. You would just create the instances of the screens in code as needed and handle their handlers appropriately when doing so.
other solution is that make button accessible on first frame and change its alpha to zero so that its not visible. This why u will not have to change the code and just change the time line.

MouseEvent in flash

I'm trying to make my own button in flash application. Here is some code:
addEventListener(MouseEvent.MOUSE_OUT, Out);
addEventListener(MouseEvent.MOUSE_OVER, Over);
...
private function Over(event:MouseEvent):void
{
addChild(overImage);
}
private function Out(event:MouseEvent):void
{
removeChild(overImage);
}
When mouse is over this button, overImage is blinking. Looks like Over and Out are calling each frame. What am I doing wrong?
If the mouse is positioned in a point where overImage will appear, then that child object will cause a MOUSE_OVER event on itself and thus a MOUSE_OUT event on its parent. The parent MOUSE_OUT will remove the overImage from the display list and that wil cause again a MOUSE_OVER over the parent, startin the loop once again and making the overImage to blink.
Since you tagged this with Flex; why not use a Flex Button?
The MouseOver event will fire continuously as the mouse moves. I would perform a check before calling the addChild to see if the overImage is already parented:
private function Over(event:MouseEvent):void
{
if(!overImage.parent){
addChild(overImage);
}
}
private function Out(event:MouseEvent):void
{
if(overImage.parent){
removeChild(overImage);
}
}
I suspect that will prevent the "Blinking".
Like the other guy said use ROLL_OVER and ROLL_OUT instead, OR set the button.mouseChildren = false.
The reason it's blinking is because MOUSE_OVER and MOUSE_OUT will for every child of that button. So if you have text, or a bg image / color, or a shine, or other elements inside of it, every time you roll over ANY of those parts, it's firing.
So when you add "overImage", it appears below the mouse, and that fires another mouseOut and mouseOver. Again, just use ROLL_OVER and ROLL_OUT, OR set mouseChildren = false
Just consider using MouseEvent.ROLL_OVER and MouseEvent.ROLL_OUT events. They ignore component's children. Without any additional checks and ugly tricks.
And by the way, buttons support skins and states, so you can just include your image into 'over' state.

AS3 ClickToGoToAndStop function from main timeline targeted to frame within movieclip

I'm creating a website in flash and I'm having trouble finding what code to use for timeline and movieclip navigation. Right now I have my main navigation buttons on the main timeline, and a separate animation that serves as my content container on a movieclip within the main timeline. I don't know how to make it so that when I click a button on the main timeline to have it navigate to a frame within the content movieclip. I've found many troubleshooters regarding how to control the main timeline from within a movieclip, which is the opposite of what I'm trying to do.
I also have MouseOut handlers on the buttons which direct to mouse out animations on the main timeline.
HomeBtn1.addEventListener(MouseEvent.MOUSE_OUT, fl_MouseOutHandler_1);
Num2Btn.addEventListener(MouseEvent.MOUSE_OUT, fl_MouseOutHandler_2);
ThrdBtn1.addEventListener(MouseEvent.MOUSE_OUT, fl_MouseOutHandler_3);
function fl_MouseOutHandler_1(event:MouseEvent):void
{
gotoAndPlay(2);
trace("Moused out");
}
function fl_MouseOutHandler_2(event:MouseEvent):void
{
gotoAndPlay(30);
trace("Moused out");
}
function fl_MouseOutHandler_3(event:MouseEvent):void
{
gotoAndPlay(56);
trace("Moused out");
}
I would like it if I could add a function like this:
function fl_ClickToGoToAndStopAtFrame(event:MouseEvent):void
{
gotoAndStop(x);
}
But with a path targeted within the movieclip, I know it may sound like a simple question but I'm relatively new to flash.
To target the content movieclip:
1. Give it an instance name.
Select it on the stage and enter a name in the textfield on the Properties panel. Call it something like 'contentClip'.
2. Access it in your code using the instance name.
contentClip.gotoAndStop(30);
Will make the content clip go to frame 30.

Bring Timeline animation to top

I have a movie that adds a MovieClip to it's stage in the constructor, i Also have an animation on the timeline that plays on certain events. Everything is working, except the movie I need the movie on the timeline to be the top layer, it is on the bottom currently.
public Class BallCollision extends MovieClip{
public function BallCollision(){
mcBall = new MovieClip();
stage.addChild(mcBall);
//Adds stuff to the movie clip
}
}
You can do one of the following:
Create a container on the timeline called 'container' and then add mcBall to that instead. This container will be on a layer underneath the existing animation.
Place all of the existing animation into a MovieClip and give it an instance name like animation. Whenever you add something to the stage, also use stage.addChild(animation) to bring it back to the top.
Obviously option 1 is preferable, but I've offered option 2 for the sake of free knowledge.

MoveClip.Visible and MouseEvent - ActionScript3

Say I have the following;
public function onBellyPatch_Two(e:MouseEvent):void
{
inBelly_Two.visible = true;
}
inBelly_Two is a MovieClip
I have two movieclips over top of each other, when you click one MovieClip another one shows up on top, and when you click that (second MovieClip)a textBox is updated.
I noticed that even if a movieclip object's visible property is false, when you click in the area where the movie clip is the MouseEvent.CLICK event is called. Is there a way to get around this? I would like to stack movieClip.
I guess one way to get around this problem would be:
removing the eventListener when movieClip is not visible and enabling the eventListener when moviclip is visible.
Is there some otherway?
Much Thanks,
Mike
Try adding:
inBelly_Two.buttonMode = false;
This will let onBellyPatch_Two be called no matter if inBelly_Two is visible or not.
Instead of removing the listener, you can just say
mc.mouseEnabled = false;
mouseEnabled docs