WiiFlash Tip #4 – Revisiting Wii-mouse in a multiplayer scenario

In February, I posted about using the Wii remote as a virtual mouse in Flash. While that approach seems to work just fine in a simple single player application, I found that it breaks really badly when you another player to it. I just completed my first two player WiiFlash game and I’ll document a few things that I had to differently.

Originally,  based all of the interaction with the cursors off of the typical mouse events (rollover, rollout, etc.), but this did allow for find out which player rollover the sprite or which player “clicked” on the sprite.

Each player’s cursor is just a sprite itself, so I switched to using the hitTestObject function against each players cursor sprite and the object sprite on a mouse event. This returns which of the cursors interacted with the object. Additionally, since the cursor sprites are big, you do have to see them from a distance, I found that I needed to add an additional sprite to the cursor – the cursor “point” – at 0,0 and use that for the hitTest rather than the actual big cursor sprite. If the “tail” of the cursor arrow is still over the object sprite, you shouldn’t count that as a roll over, since the point of the arrow is the important part.

So here are the functions for a rollover:

 private function onItemOver(e:MouseEvent):void {
var wm:Array = whichWiiMotesAreOverMe(Sprite(e.target))
for (var i:int = 0; i < wm.length; i++) {
_WiiMotes[wm[i]].doRumbleSeconds(.1);
_WiiMotes[wm[i]].cursorState = WiiCursorView.CURSOR_POINT;
}
}

// returns array of which wiimote cursors are over the sprite
private function whichWiiMotesAreOverMe(tgt:Sprite):Array {
var a:Array = new Array();
// _WiiMotes is an array of Wii controller objects
for (var i:int; i < _WiiMotes.length; i++) {
if (tgt.hitTestObject(_WiiMotes[i].cursorPoint)) {
a.push(i);
}
}
return a;
}

The functions for a mousedown are:

private function onItemDown(e:MouseEvent):void {
// gets the index of the _WiiMote object that clicked the sprite
var wm:int = whichWiiMoteClickedMe(Sprite(e.target));
}

// returns index of which wii mote cursor is over with the A button down
private function whichWiiMoteClickedMe(tgt:Sprite):int {
var wm:Array = whichWiiMotesAreOverMe(tgt);
for (var i:int = 0; i < wm.length; i++) {
if (tgt.hitTestObject(_WiiMotes[wm[i]].cursorPoint)) {
if (wm.length == 1) {
// simple test if only one cursor is over
if(_WiiMotes[wm[i]].isADown) return wm[i];
} else {
// little harder if 2+ are over, _LastClickWMIdx is the last Wii mote to have pressed a button
if(_WiiMotes[wm[i]].isADown && _LastClickWMIdx==wm[i]) return wm[i];
}
}
}
return -1;
}

This method, while probably not the best way, turned out to work really well in the game.

2 Comments

  1. I love the post! I didn’t even think of the potential of all the complications a multi-mouse scenario would bring to the coding. Good job on the approach, I haven’t tried it yet, but it seems very logical.

    Reply

    1. Thanks! It works pretty well. I haven’t really done anything with WiiFlash since the game I reference in the post, but I’d like to one day – just no need at work right now (economy, etc.).

      Reply

Leave a Reply to ohNit Cancel reply