Custom Mouse Cursor for ActionScript 3

I threw together an FLA for someone to show them the different ways to handle custom mouse cursors in ActionScript 3 (AS3). I figured I should start posting more of my code for people since I use other people’s blogs all the time to figure out my own problems.

I’m mostly coding up stuff for Flash, Flex, Augmented Reality, iPhone, PHP, and CSS/HTML right now so hopefully I’ll have the time to post more snippets of things I’ve figured out trying to get all this technology to work.

[SWF]http://www.mikeziray.com/blog/wp-content/uploads/2009/05/customcursor_cs3.swf, 550, 400[/SWF]

Direct Access to the X and Y Mouse Coordinates

The first method allows us a finer control over the movement of the cursor by directly changing the X and Y coordinates of the cursor movieclip with the X and Y coordinates of the mouse. If we wanted to restrict the movement to say, a specific Y coordinate (as we’ll see in the next example), we can do that just as easily by keeping the target_mc.y a constant when we update it’s X coordinate.


// Set up our listeners for each of our mouse actions
boundary_mc.addEventListener( MouseEvent.MOUSE_OVER,
onMouseOver );
boundary_mc.addEventListener( MouseEvent.MOUSE_OUT,
onMouseOut );

// Ignores all sub movie clips and treats them as the parent
// -- otherwise events will be triggered on the child
// movieclips and not our main clip
target_mc.mouseChildren = false;
boundary_mc.mouseChildren = false;

// Ignore all the mouse events for the cursor
// -- otherwise MOUSE_OUT will trigger since mouse is
// now on target_mc instead of boundary_mc
target_mc.mouseEnabled = false;

///////////////////////////////////////////////////////////////
// ON MOUSE OVER /////////////////////////////////////////////
/////////////////////////////////////////////////////////////
// When the mouse rolls over onto our red boundary, hide
// mouse/show cursor
//
function onMouseOver( theEvent:MouseEvent ):void
{
// Swap the mouse for the cursor
Mouse.hide(); // hide mouse cursor
target_mc.visible = true;

// Add a listener to handle the moving of the mouse
// We add the listener here because otherwise the onMouseMove
// would execute whenever the mouse moved, whether it was
// on our boundary or not. Not a big deal, but better for
// efficiency
boundary_mc.addEventListener( MouseEvent.MOUSE_MOVE,
onMouseMotion );

// Handle the movement now so we don't have to wait for a
// mouse movement to reposition the cursor
onMouseMotion(null);
}

///////////////////////////////////////////////////////////////
// ON MOUSE MOTION ///////////////////////////////////////////
/////////////////////////////////////////////////////////////
// When the mouse moves, we also want to move our target to follow
// the mouse
//
function onMouseMotion( theEvent:MouseEvent ):void
{
// Reposition our custom cursor
target_mc.y = stage.mouseY;
target_mc.x = stage.mouseX;
}

///////////////////////////////////////////////////////////////
// ON MOUSE OUT //////////////////////////////////////////////
/////////////////////////////////////////////////////////////
// When mouse goes outside our red boundary, show default mouse,
// and hide our custom one
//
function onMouseOut( theEvent:MouseEvent ):void
{
// Swap the cursor for the mouse
Mouse.show();
target_mc.visible = false;

// Stop listening for mouse movement
boundary_mc.removeEventListener( MouseEvent.MOUSE_MOVE,
onMouseMotion );
}

The Drag and Drop Method

Our next method uses the drag function built into Flash. With this function you can drag a movieclip around the stage with the mouse automatically. This restricts some of our freedom, but gives us some very easy coding to control the mouse cursor to specific regions. In this case we simply restrict the motion of the cursor along a rectangle of 0 height (so it won’t move along the Y axis) and with a width as wide as our boundary box. This feature has its advantages, and I merely include it to demonstrate how to use it in the context of a custom mouse cursor.


// Set up our listeners for each of our mouse actions
boundary2_mc.addEventListener( MouseEvent.MOUSE_OVER,
onMouseOver2 );
boundary2_mc.addEventListener( MouseEvent.MOUSE_OUT,
onMouseOut2 );

// Ingores all sub movie clips and treats them as the parent
// -- otherwise events will be triggered on the child
// movieclips and not our main clip
target_mc.mouseChildren = false;
boundary2_mc.mouseChildren = false;

// Ignore all the mouse events for the cursor
// -- otherwise MOUSE_OUT will trigger since mouse is
// now on target_mc instead of boundary_mc
target_mc.mouseEnabled = false;

// Calculate the the vertical center of our boundary
// so that the cursor can move along that line
var verticalCenter_num = boundary2_mc.y + (boundary2_mc.height / 2);

///////////////////////////////////////////////////////////////
// ON MOUSE OVER 2 ///////////////////////////////////////////
/////////////////////////////////////////////////////////////
// Same as our previous one, but set for another boundary
//
function onMouseOver2( theEvent:MouseEvent ):void
{
// Swap the mouse for the cursor
Mouse.hide();
target_mc.visible = true;

// Add a listener to handle the moving of the mouse
// We add the listener here because otherwise the
// onMouseMove would execute whenever the
// mouse moved, whether it was on our boundary
// or not. Not a big deal, but better for efficiency
boundary2_mc.addEventListener( MouseEvent.MOUSE_MOVE,
onMouseMotion2 );

// Handle the movement now so we don't have to wait
// for a mouse movement to reposition the cursor
target_mc.y = verticalCenter_num;
target_mc.x = stage.mouseX;
}

///////////////////////////////////////////////////////////////
// ON MOUSE MOTION 2 /////////////////////////////////////////
/////////////////////////////////////////////////////////////
// Restricts the movement of our custom cursor along the X axis
//
function onMouseMotion2( theEvent:MouseEvent ):void
{
// Calculate the the vertical center of our boundary
// so that the cursor can move along that line
var verticalCenter_num = boundary2_mc.y +
(boundary2_mc.height / 2);

// We use startDrag() here since it's easier to restrict
// the cursor's boundaryusing a Rectangle object.
// boundary2_mc.x: Start from the x position of our
// boundary verticalCenter_num: Start from the
// vertical center as our y coordinate
// boundary2_mc.width: Allow the cursor to move
// the length of the boundary's width (starting from x)
// 0: Don't allow the cursor to move up or down
target_mc.startDrag( true, new Rectangle(
boundary2_mc.x,
verticalCenter_num,
boundary2_mc.width,
0)
);
}

///////////////////////////////////////////////////////////////
// ON MOUSE OUT 2 ////////////////////////////////////////////
/////////////////////////////////////////////////////////////
// When mouse goes outside our gray boundary, show default mouse,
// hide custom mouse and stop drag
//
function onMouseOut2( theEvent:MouseEvent ):void
{
// Swap the cursor for the mouse
Mouse.show();
target_mc.visible = false;

// Stop our drag
target_mc.stopDrag();

// Stop listening for mouse movement
boundary2_mc.removeEventListener( MouseEvent.MOUSE_MOVE,
onMouseMotion2 );
}

I hope the code is commented well enough for you to understand what’s going on. It should be fairly self explanatory, but if not, feel free to ask.

Sample Code

Below is the source code for the SWF used at the top of the post:

Download the Custom Cursors sample code.

Did you find this useful?

If you found this page useful, please consider helping us out by checking out the links on the right. Thanks!

7 Comments on “Custom Mouse Cursor for ActionScript 3

  1. Thanks, this is exactly what I was looking for for a flash game I’m making. The only trouble I’m having is it’s throwing up the error 1120: Access of undefined property target_mc.

  2. Hey so the 2 code that you give here 😉 where shoould i put it,on layer,or on the movie instance?
    im new on this one.can you tell me what the name of the movie on that code? and where sheould i put first code and the second,at my movie.
    thank you.

    • Hey Paul,

      I posted the source code I used at the bottom of this article. It should explain everything. Hope that answers your questions!

      Thanks!
      Mike

  3. I got some issue with the custom cursor and the arrow blinking together. After reading your example, It turned out that mouseChildren = false is critical to stop that blinking.

    thanks man!

  4. This totally works! Thanks! But the boundary layer is now making the button that lies beneath it no longer work. If I move the boundary layer below the button, the button works, but the custom cursor disappears. Thoughts?

    • You can set your event listener on any object you want, so you can set it to the top layer. Also, setting mouseChildren to true on the top layer might also solve your issue.