FLASH - Snap moving hand onto keys of a music keyboard

I'm using "startDrag" to initiate a dragging of my movieclip which is the graphic of a hand.

This works but I want to snap the hand over the keys so the finger is over the middle of the key it's over - not smoothly drag over the keyboard.

Is this possible?
With Thanks.
jasonbbSoftware EngineerAsked:
Who is Participating?
 
moagriusCommented:
snippet failed to attach...
//  POSITION BASED ON CLOSEST KEY

var format:TextFormat = new TextFormat("arial",20);

function createKey(letter:String):Sprite{
	var key:Sprite = new Sprite();
	key.graphics.lineStyle(0,0,1,true);
	key.graphics.beginFill(0xDDDDDD);
	key.graphics.drawRoundRect(0,0,40,40,10);
	key.graphics.endFill();
	var tf:TextField = new TextField();
	tf.autoSize = "left";
	tf.defaultTextFormat = format;
	tf.text = letter;
	tf.x = 20 - tf.width/2;
	tf.y = 20 - tf.height/2;
	key.addChild(tf);
	return key;
}

function positionCursor(event:MouseEvent):void{
	var distances:Array = [];
	var count:uint = keys.length;
	var xMouse:Number = stage.mouseX;
	var yMouse:Number = stage.mouseY;
	for(var i:int=0;i<count;i++){
		var key:Sprite = keys[i];
		var horizontalDistance:Number = Math.abs(key.x - xMouse);
		var verticalDistance:Number = Math.abs(key.y - yMouse);
		var totalDistance:Number = horizontalDistance + verticalDistance;
		distances[i] = {
			element : key,
			distance : totalDistance
		}
	}
	
	distances = distances.sortOn("distance", 16);

	var shortestDistance:Object = distances.shift();
	var closestKey:Sprite = shortestDistance.element;
	handCursor.x = closestKey.x;
	handCursor.y = closestKey.y;
	
}

var keyboard:Sprite = new Sprite();
addChild(keyboard);

var keys:Array = [];

var xPos:Number = 0;
var yPos:Number = 0;

for(var i:int=65;i<91;i++){
	
	var key:Sprite = createKey(String.fromCharCode(i));
	
	xPos += 80;
	
	if(xPos > stage.stageWidth){
		xPos = 0;
		yPos += 80;
	}
	
	key.x = xPos;
	key.y = yPos;
	
	keyboard.addChild(key);
	
	keys.push(key);
}

var handCursor:Shape = new Shape();
handCursor.graphics.lineStyle(0,0xFF,1,true);
handCursor.graphics.beginFill(0xFFFFFF,0.5);
handCursor.graphics.drawRoundRect(0,0,40,40,10);
handCursor.graphics.endFill();
addChild(handCursor);

stage.addEventListener("mouseMove", positionCursor);




/*  USING MOUSE OVERS ONLY

var format:TextFormat = new TextFormat("arial",20);

function createKey(letter:String):Sprite{
	var key:Sprite = new Sprite();
	key.graphics.lineStyle(0,0,1,true);
	key.graphics.beginFill(0xDDDDDD);
	key.graphics.drawRoundRect(0,0,40,40,10);
	key.graphics.endFill();
	var tf:TextField = new TextField();
	tf.autoSize = "left";
	tf.defaultTextFormat = format;
	tf.text = letter;
	tf.x = 20 - tf.width/2;
	tf.y = 20 - tf.height/2;
	key.addChild(tf);
	return key;
}

function positionCursor(event:Event):void{
	handCursor.x = event.currentTarget.x;
	handCursor.y = event.currentTarget.y;
}

var keyboard:Sprite = new Sprite();
addChild(keyboard);

var xPos:Number = 0;
var yPos:Number = 0;

for(var i:int=65;i<91;i++){
	var key:Sprite = createKey(String.fromCharCode(i));
	xPos += 80;
	if(xPos > stage.stageWidth){
		xPos = 0;
		yPos += 80;
	}
	key.x = xPos;
	key.y = yPos;
	key.addEventListener("mouseOver", positionCursor, false, 0, true);
	keyboard.addChild(key);
}

var handCursor:Shape = new Shape();
handCursor.graphics.lineStyle(0,0xFF,1,true);
handCursor.graphics.beginFill(0xFFFFFF,0.5);
handCursor.graphics.drawRoundRect(0,0,40,40,10);
handCursor.graphics.endFill();
addChild(handCursor);

*/

Open in new window

0
 
quizengineCommented:
If you issue 'startDrag' the hand will *always* follow the mouse.

Do you want it to either

a) follow the mouse but 'snap' to the closest one when the mouse is released ?

or

b) with the mouse down,not move at all until the next 'key' is reached and then 'snap'

Both of these require a different approach.

If you are able to share the fla that should make it easier. Plus, what version of actionscript, and what version of Flash are you using ?
0
 
jasonbbSoftware EngineerAuthor Commented:
Thanks QuizEngine,
AS3 version 9. I want option B. I tried the following code to test:
      private function mouseMoveHandler(event:MouseEvent):void
      {
            mcHand.x = mcHand.x & 0xffffffc0;
      }
It worked in that the hand snapped but it also skipped around horizontally as i moved the mouse and looked really bad.
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

 
quizengineCommented:
I'm really sorry, Jasonbb - I'm stuck in the past.  I may be a 'master' but only of AS2. Good luck finding someone who uses AS3 to crack your issue.
0
 
moagriusCommented:
to answer the original question, yes you can - you'd set up a mouseMove handler that compared the current mouse position to the positions of each key element, and compute the distance.  For the key that's closest to the mouse position, you'd set the hand cursor element to that key element's position.

but, it sounds like you don't want to drag it at all - but rather just position it over the key when the key is mouseovered.  this would be very simple - instead of a drag, just set a mouseOver event handler to each key that sets the hand cursor element's position to the position of the event.currentTarget.

i've attached a snippet with examples for both approaches.  open a new FLA and paste the contents in the frame 1's action's panel and run Test Movie to see the demo.  the first (un-commented) bit is using the mousemove approach; the second (commented) bit is using the mouseOver of individual elements aproach.  Just comment out or uncomment the one you want to try.
0
 
jasonbbSoftware EngineerAuthor Commented:
thanks moagrius that's unreal
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.