Changing the Mouse Cursor

In Flash there are three types of Mouse cursors:

While Flash does not provide an easy way to detect when cursor changes occur, Scaleform offers both a C++ API and an ActionScript Mouse class extension that allow you to manage a custom cursor. On the C++ side, you can use the GFx::StateBag::SetUserEventHandler function to install an event handler that notifies you whenever mouse cursor changes need to take place. You can use this handler to change either the cursor image drawn by the game engine or the system cursor, as illustrated in FxPlayer.cpp. Alternatively, you can choose to implement a custom cursor fully in ActionScript, with the added benefit of animation and artist control. An example of how this is done is provided in the new Mouse.fla/swf sample shipped in the SDK.

The Mouse sample implements a customizable mouse cursor as a simple movie clip object on the stage, called 'Cursor_M'. The cursor has several frames identified by the "hand", "arrow" and "ibeam" frame labels; the cursor image can be changed by simply moving the timeline to one of those frames. Whenever mouse movement is detected, the movie clip _x and _y coordinates are adjusted to follow the mouse.

In order to change a cursor type based on the object underneath, the mouse sample overrides the Mouse.setCursorType function, which is a Scaleform extension. This function is called with cursorType and mouseIndex arguments whenever a cursor change needs to take place, allowing such changes to be detected. The mouse sample interprets this sample by comparing cursorType with one of the mouse constants (Mouse["ARROW"], Mouse["HAND"] and Mouse["IBEAM"]) and changing the cursor frame appropriately.

Below is the source code responsible for handling multiple custom cursors in the mouse sample. We recommend referring to the actual sample for more details.

_global.gfxExtensions = 1;
// Hide system cursor.
Mouse.hide();

var mouseListener:Object = new Object;
mouseListener.onMouseMove = function(mouseIdx, x,y)
{
    if (mouseIdx == undefined)
        mouseIdx = 0;
    if (x == undefined)
    {
        x = _xmouse;
        y = _ymouse;
    }
    var cmc = eval("_root.Cursor_M"+(mouseIdx+1));

    cmc._x = x;
    cmc._y = y;
}
Mouse.addListener(mouseListener);

Mouse["setCursorType"] = function(cursorType, mouseIdx)
{
    if (mouseIdx == undefined)
        mouseIdx = 0;
   var cmc = eval("_root.Cursor_M"+(mouseIdx+1));
   switch(cursorType)
   {
        case Mouse["HAND"]:
            cmc.Cursor.gotoAndPlay("hand");
        break;
        case Mouse["ARROW"]:
            cmc.Cursor.gotoAndPlay("arrow");
        break;
        case Mouse["IBEAM"]:
            cmc.Cursor.gotoAndPlay("ibeam");
        break;
        default: return;
   }
}

// Override Mouse.show and Mouse.hide functions so that they affect our cursor.
ASSetPropFlags(Mouse, "show,hide", 0, 7);

Mouse.show = function(mouseIdx) 
{ 
    if (mouseIdx == undefined)
        mouseIdx = 0;
    var cmc = eval("_root.Cursor_M"+(mouseIdx+1));
    cmc._visible = true; 
}
Mouse.hide = function(mouseIdx) 
{ 
    if (mouseIdx == undefined)
        mouseIdx = 0;
    var cmc = eval("_root.Cursor_M"+(mouseIdx+1));
    cmc._visible = false; 
}