make an object move directly towards a point and stop when it reaches it - actionscript-3

How can I make my object stop when it reaches the destination i gave it with my mouse click? The code makes the object move towards the point of a mouse click but I can't seem to find out how to make it stop, because it will almost never pass the specific destination point. :/ Somebody who knows how to accomplish this?
public function onMouseDown(evt:MouseEvent)
{
if (this._character != null)
{
_character.isMoving = false;
_character.dx = 0;
_character.dy = 0;
targetX = mouseX - _character.x;
targetY = mouseY - _character.y;
var angle:Number = Math.atan2(targetY,targetX);
var dx:Number = Math.cos(angle) * _character.speed;
var dy:Number = Math.sin(angle) * _character.speed;
_character.dx = dx;
_character.dy = dy;
_character.isMoving = true;
}
}
public function updateCharacter(e:Event):void
{
if (this._character.isMoving)
{
this._character.x += this._character.dx;
this._character.y += this._character.dy;
}
}

Easiest way to do it would be to calculate the angle to the point you want to stop at each time you move. This value should remain the same if you're moving in a straight line until you pass the point you're trying to stop at, at which point it will change drastically.
Once this happens, simply move your object back to the position it should have stopped at before you render it again.
I've created a demo with source code for you. There's a fair amount of code, so rather than posting everything here you can download the source instead:
http://martywallace.com/testing/gotoPoint.zip

Try this
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Guest extends MovieClip
{
var walkSpeed:Number = 5;
var oldPosX;
var oldPosY;
public function Guest()
{
stage.addEventListener(MouseEvent.CLICK, walk);
}
function walk(event:MouseEvent):void
{
oldPosX = parent.mouseX;
oldPosY = parent.mouseY;
rotation = Math.atan2(oldPosY - y,oldPosX - x) / Math.PI * 180;
addEventListener(Event.ENTER_FRAME, loop);
}
function loop(event:Event):void
{
// see if you're near the target
var dx:Number = oldPosX - x;
var dy:Number = oldPosY - y;
var distance:Number = Math.sqrt((dx*dx)+(dy*dy));
if (distance<walkSpeed)
{
// if you are near the target, snap to it
x = oldPosX;
y = oldPosY;
removeEventListener(Event.ENTER_FRAME, loop);
}
else
{
x = x+Math.cos(rotation/180*Math.PI)*walkSpeed;
y = y+Math.sin(rotation/180*Math.PI)*walkSpeed;
}
}
}
}

Similar questions have been asked many times.
However, see the code in my answer here that should explain how to move and stop.
Movement of Objects in a simulation

Related

Make three MovieClips appear and disappear inside a snowglobe when shaken

I used a creative cow tutorial to create my own snow globe that moves and snow reactivates - it really is a great tutorial.
What I'm trying to do is Change between 3 Movie clips in the ActionScript - But each time I add my movie clip names - Or try and add a simple visibility code I break my snow globe actions.
I have my MovieClip instances named friendsSceneThree, BuddiesSceneTwo and HatsOffSceneOne. I would think they'd be good but somewhere I'm missing something. Right now I can't get the code to even SEE The movieclips I'm getting a simple:
TypeError: Error #1006: value is not a function.at SnowGlobeContainer/update()
Down in the 'if drag' Update is where I'd like to Change from One MClip to the Next.
What Am I Not Seeing?!?! Any help would be greatly appreciated! Thanks
Here is the ActionScript:
package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.geom.Point;
public class SnowGlobeContainer extends Sprite {
public var snowForeground:SnowGeneratorCircle;
public var snowBackground:SnowGeneratorCircle;
public var friendsSceneThree:MovieClip;
public var buddiesSceneTwo:MovieClip;
public var hatsOffSceneOne:MovieClip;
public var drag:Boolean = false;
public var over:Boolean = false;
public var startPos:Point = new Point;
public var mouseDownOffset:Point = new Point;
public var bounds:Rectangle = new Rectangle;
public var vel:Point = new Point(0,0);
public var pos:Point = new Point(x,y);
public var old:Point = new Point(x,y);
public var gravity:Number = 5+(Math.random()*1);
public var restitution:Number = 0.5;
public var friction:Number = 0.9;
public function SnowGlobeContainer() {
// save some initial persistant properties
startPos.x = this.x;
startPos.y = this.y;
old.x = this.x;
old.y = this.y;
bounds.x = 0;
bounds.y = 0;
bounds.width = 600;
bounds.height = startPos.y;
// add mouse interaction listeners and show the cursor on rollover
this.mouseChildren = false;
this.useHandCursor = true;
this.buttonMode = true;
this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
this.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
this.addEventListener(Event.ENTER_FRAME, update);
}
protected function onMouseOver(e:MouseEvent=null):void { over = true; }
protected function onMouseOut(e:MouseEvent=null):void { over = false; }
protected function onMouseDown(e:MouseEvent=null):void {
// Save the offset of your mouse when you first start dragging. Same functionality as startDrag(false)
mouseDownOffset.x = mouseX;
mouseDownOffset.y = mouseY;
drag = true;
}
protected function onMouseUp(e:MouseEvent=null):void {
vel.x = vel.y = 0;
pos.x = x;
pos.y = y;
drag = false;
}
public function update(e:Event):void {
// this if/else statement controls the mouse over and out instead of using event listeners
if(mouseY < -175 || mouseY > 175 || mouseX < -175 || mouseX > 175){
if(over) onMouseOut();
}else{
if(!over) onMouseOver();
}
if(drag){
// drag around..
this.x = parent.mouseX - mouseDownOffset.x;
this.y = parent.mouseY - mouseDownOffset.y;
// keep this thing on the table :)
if(y >= bounds.height) y = bounds.height;
// if you "shake" or move the mouse quickly, we are going to reset the snow particles
var d:Point = new Point(Math.abs(old.x - x), Math.abs(old.y - y));
if(d.x > 50 || d.y > 50 ){
snowForeground.reset();
snowBackground.reset();
friendsSceneThree.visible = false;
}
// update the history position
old.x = x;
old.y = y;
vel.y = (y-old.y)/2;
}else{
// if you drop this object it should have a bit of realistic falling..
vel.y += gravity;
pos.y += vel.y;
// bounce
if(pos.y > bounds.height){
pos.y = bounds.height;
vel.y *= -(Math.random()*restitution);
}
y = pos.y;
}
}
}
}
I appreciate the help -- If you haven't noticed I'm new to all of this scripting. I'm looking in on lynda.com and other forums. the SnowGeneratorCircle.as is:
package {
import flash.display.Sprite;
import flash.events.Event;
public class SnowGeneratorCircle extends Sprite {
var totalFlakes:int = 500;
var flakes:Array = new Array();
public function SnowGeneratorCircle() {
addSnowFlakes();
addEventListener(Event.ENTER_FRAME, update);
}
protected function addSnowFlakes():void{
for(var i:int=0; i<totalFlakes; i++){
var f:SnowFlake = new SnowFlake();
addChild(f);
flakes.push(f);
}
}
public function reset():void{
for(var i:int=0; i<totalFlakes; i++){
var f:SnowFlake = flakes[i];
f.reset();
}
}
public function update(e:Event=null):void {
for(var i:int=0; i<totalFlakes; i++){
var f:SnowFlake = flakes[i];
f.update(0);
}
}
}
}
I debugged - didn't clean up the code, because every time I did - it broke the actions. So I left the code with the double spacing. That's how it went in when I copied and pasted from the tutorial anyway.
Here's the error on line 173 - which is the MovieClip I'd like to have change.
Attempting to launch and connect to Player using URL /Volumes/Lacie Biggest S2S/GRaid/Veronica
/V/Rubio/Work/SUBARU/SnowGlobe Subaru/SnowGlobeAnima/snowGlobeShakev3.swf
[SWF] Volumes:Lacie Biggest S2S:GRaid:Veronica:V:Rubio:Work:SUBARU:SnowGlobe >Subaru:SnowGlobeAnima:snowGlobeShakev3.swf - 468081 bytes after decompression
TypeError: Error #1006: value is not a function.
at SnowGlobeContainer/update()[/Volumes/Lacie Biggest S2S/GRaid/Veronica/V/Rubio/Work/SUBARU
/SnowGlobe Subaru/SnowGlobeAnima/SnowGlobeContainer.as:173]
I just don't know how to get the actionscript to find my MovieClips and then swap them out wt each shake of the globe.

Flash AS3 (shape class) CPU usage and optimization

I'm new to Flash Actionscript 3.0 and object programming in general. I'm trying to create a simple game, which is drawing a shape based on steering.
public class Player extends Shape
{
public var X,Y,v,vX,vY,size,a,r:Number;
public var k,counter,leftKey,rightKey,_color:uint;
public var line:Shape = new Shape();
public var dot:Shape = new Shape();
/*...*/
/*constructor, giving values to variables here, not important*/
/*...*/
public function Move():void
{
a=a+0.05*k;
//player controls k parameter k=0 by default
//k=1 when right key pressed
//k=-1 when left key pressed
vX=v*Math.cos(a);
vY=v*Math.sin(a);
X=X+vX;
Y=Y+vY;
dot.x=X+vX*size/(2*v);
dot.y=Y+vY*size/(2*v);
if (counter==0)
{
line.graphics.lineTo(X,Y);
if (Math.random()<0.008) counter=12;
} else
{
line.graphics.moveTo(X, Y);
counter--;
}
}
}
Function Move is in my Player class, which is called from inifinite TimerEvent function in my Main Class
public function mainLoop(TimerEvent:Event):void
{
for (var i:uint=0; i<players; i++) player[i].Move();
}
It seems to be working well at the beginning but after some time CPU usage raises dramatically and game becomes unplayble. I belivie it's caused by my shape (line) getting more and more complex.
Is there some reasonable way to optimize it? Can I somehow draw a line in less consuming way? I tried to convert it to bitmap but that looked ugly and didn't really help.
Thanks and cheers!
You're right in assuming that your slowdown in coming from your shape code - vector data is redrawn every frame in flash, so the more complex it is, the longer it takes to draw. Some solutions, depending on what you're willing to do:
Your fidelity is way to high - you're calling your Move function every frame; you probably don't need it that high, as the difference in movement since the last frame is probably less than a pixel. Sample your position every X frames instead (where X is the level of fidelity your willing to go down to). This can be done with a simple counter in the enter frame
If you don't need to keep the entire history of the drawing, put all your points into an array/vector, culling the length as needed. Then every frame, do a line.graphics.clear() and just draw the points in the array
If you do need to keep the entire history, then keep a BitmapData under your line (e.g. the size of the stage). Every so often, draw the line to the BitmapData and call clear() on your graphics to get right of the vector data. You shouldn't notice any loss in quality (set smoothing to true when you're drawing)
I'd do the first point in any case, then choose between the second and third, depending on your use case
Expanding my comment, try something like this:
public class Player extends Shape
{
public var X,Y,v,vX,vY,size,a,r:Number;
public var k,counter,leftKey,rightKey,_color:uint;
public var line:Shape = new Shape();
public var dot:Shape = new Shape();
/*...*/
/*constructor, giving values to variables here, not important*/
/*...*/
public function Player(){
//draw shapes
graphics.lineStyle(1);
graphics.drawCircle(0,0,r);
graphics.lineTo(size,0);//can't test this now, but make sure the line is in the same direction as rotation 0 (guessing it's to the right)
//your other constructor code here
}
public function Move():void
{
a=a+0.05*k;
//player controls k parameter k=0 by default
//k=1 when right key pressed
//k=-1 when left key pressed
vX=v*Math.cos(a);
vY=v*Math.sin(a);
X=X+vX;
Y=Y+vY;
x=X+vX*size/(2*v);
y=Y+vY*size/(2*v);
rotation = a * 57.2957795;//quick'n'dirty radians to degrees
}
and if you want to draw the trails you can try something like this:
var canvas:Bitmap = new BitmapData(state.stageWidth,stage.stageHeight,true,0xFF000000);
var ct:ColorTransform = new ColorTransform(1,1,1,.1);
public function mainLoop(TimerEvent:Event):void
{
for (var i:uint=0; i<players; i++) {
player[i].Move();
canvas.draw(player[i],player[i].transform.concatenatedMatrix,ct);
}
}
Hope this makes sense.
Update
Here is a standalone code snippet to illustrate the idea above(which has untested syntax):
package {
import flash.display.Bitmap;
import flash.geom.ColorTransform;
import flash.display.BitmapData;
import flash.text.TextField;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.utils.Dictionary;
import flash.display.Sprite;
public class PlayerMoveTest extends Sprite {
private var keys:Dictionary = new Dictionary();
private var players:Vector.<Player> = new Vector.<Player>();
private var trails:BitmapData;
private var fade:ColorTransform = new ColorTransform(1,1,1,.1);
public function PlayerMoveTest() {
addEventListener(Event.ADDED_TO_STAGE,init);
}
private function init(e:Event):void{
trails = new BitmapData(stage.stageWidth,stage.stageHeight,true,0x00FFFFFF);
addChild(new Bitmap(trails));
for(var i:int = 0 ; i < 2; i++){
var p:Player = addChild(new Player(10+i*10)) as Player;
p.x = stage.stageWidth * .5;
p.y = stage.stageHeight * .5;
players.push(p);
}
stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP,onKeyUp);
stage.addEventListener(Event.ENTER_FRAME,update);
}
private function onKeyDown(e:KeyboardEvent):void{
keys[e.keyCode] = true;
}
private function onKeyUp(e:KeyboardEvent):void{
keys[e.keyCode] = null;
}
private function update(e:Event):void{
if(keys[Keyboard.LEFT] != undefined) {players[0].a -= .05;players[1].a += .05;}
if(keys[Keyboard.RIGHT] != undefined) {players[0].a += .05;players[1].a -= .05;}
if(keys[Keyboard.UP] != undefined) {players[0].s += .15;players[1].s -= .15;}
if(keys[Keyboard.DOWN] != undefined) {players[0].s -= .15;players[0].s += .15;}
for(var i:int = 0 ; i < players.length; i++) {
players[i].move();
trails.draw(players[i],players[i].transform.concatenatedMatrix,fade);
}
}
}
}
import flash.display.*;
class Player extends Shape{
public var vx:Number,vy:Number,a:Number,size:Number,r:Number,s:Number;
public function Player(size:Number){
init(size);
}
private function init(size:Number):void{
vx = vy = a = s = 0;
this.size = size;
this.r = size * .25;
graphics.lineStyle(1);
graphics.drawCircle(0,0,r);
graphics.lineTo(size,0);
}
public function move():void{
rotation = a * 57.2957795;
vx = Math.cos(a) * s;
vy = Math.sin(a) * s;
x += vx;
y += vy;
if(x < 0) x = 0;
if(y < 0) y = 0;
if(x > stage.stageWidth) x = stage.stageWidth-width;
if(y > stage.stageHeight) y = stage.stageHeight-height;
}
}
You can test this code here and here's a preview:
Use the arrow keys to drive(up arrow accelerates, left/right steer).
The first player is the smaller one, having the correct controls, the other is simply mirroring the previous controls)

Relative coordinate issue in AS3

I've edited the following code in order to let those green rectangles to follow my cursor which is customized by a small rectangle. But I've encountered several problems:
Although I haven't defined any coordinate in the separate class, but the size is abviously wrong in the stage when publish with only half size for the cursor coordinate.
The reset button cannot be activated, although I've tested well in the other code.
Here is the work I've published: http://neowudesign.com/hwu_ex04.html
The code on timeline
//hw//Creating a new cursor
newcursor.startDrag ("true");
Mouse.hide();
//hw//Creating a holder to hold the butterfly objects
var mothHolder = new Sprite();
addChild(mothHolder);
//hw//Creating seven moths at the beginning
makeMoths(7);
//hw//creating a function which can generate limited numbers of moths.
function makeMoths(MothsNumber:Number)
{
for (var i = 0; i < MothsNumber; i++)
{
newMoth = new Moth();
mothHolder.addChild(newMoth);
}
}
//hw//Set the reset button at the top for clicking, but it's failed to work;
//hw//Set the cursor back to the default one, and remove the custom one when hovering;
mothHolder.setChildIndex(reset,mothHolder.numChildren);
reset.addEventListener(MouseEvent.MOUSE_OVER, cursorchange);
function cursorchange(event:MouseEvent):void
{
Mouse.show();
newcursor.visible = false;
trace("alert!!");
}
//hw//creating a function of reset
reset.addEventListener(MouseEvent.CLICK, resetClick, false, 0, true);
function resetClick(evt:MouseEvent):void
{
removeChild(mothHolder);
mothHolder = new MovieClip();
addChild(mothHolder);
var numMoths:Number = Math.round(Math.random() * 6) + 1;
trace("Moths Numeber: "+ numMoths);
makeButterflies(numButterflies);
}
//hw//when the cursor leave the reset region, it turns back to the customized one
reset.addEventListener(MouseEvent.MOUSE_OUT, fl_MouseOutHandler);
function fl_MouseOutHandler(event:MouseEvent):void
{
removeEventListener(MouseEvent.MOUSE_OVER, cursorchange);
Mouse.hide();
newcursor.visible = true;
}
And the code for class "Moth" separately named "angle.as"
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.geom.Point;
public class angle extends MovieClip {
var speed:Number = 8;
function angle() {
//letting every moth follow the moving of the cursor
addEventListener(Event.ENTER_FRAME,mothMove);
function mothMove(myEvent:Event) {
trace(mouseX);
trace(mouseY);
var angle:Number = Math.atan2(mouseY - y, mouseX - x);
x += Math.cos( angle ) * speed;
y += Math.sin( angle ) * speed;
}
}
}
}

AS3 - If symbol's coordinates arrive here?

I'm using Flash Professional CS5.5 and I need to make an app where there is a ball (symbol) that moves using the accelerometer and I want that, when the ball coordinates A reach this coordinates B it goes to frame 2 (gotoAndPlay(2)). I have to find the ball coord first, right? How do I make this?
Here is the code I've now
c_ball.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void{
c_ball.startDrag();}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void{
c_ball.stopDrag();}
would it work if, after retriving the coordinates?
function f_level (e) if (c_ball.x==100 && c_ball.y==100) {
gotoAndStop(2);}
MOUSE_UP and MOUSE_DOWN are not what you need if you're looking for Accelerometer data. You want the Accelerometer class and associated events.
Try something like this:
import flash.sensors.Accelerometer;
import flash.events.AccelerometerEvent;
var accel:Accelerometer = new Accelerometer();
accel.addEventListener(AccelerometerEvent.UPDATE, handleAccelUpdate);
Update handler:
function handleAccelUpdate(e:AccelerometerEvent):void{
//inside this function you now have access to acceleration x/y/z data
trace("x: " + e.accelerationX);
trace("y: " + e.accelerationY);
trace("z: " + e.accelerationZ);
//using this you can move your MC in the correct direction
c_ball.x -= (e.accelerationX * 10); //using 10 as a speed multiplier, play around with this number for different rates of speed
c_ball.y += (e.accelerationY * 10); //same idea here but note the += instead of -=
//you can now check the x/y of your c_ball mc
if(c_ball.x == 100 && c_ball.y == 100){
trace("you win!"); //fires when c_ball is at 100, 100
}
}
Now this will let you "roll" your MC off the screen so you're probably going to want to add some kind of bounds checking.
Check out this great writeup for more info:
http://www.republicofcode.com/tutorials/flash/as3accelerometer/
An easy and save way is to use colission detection, instead of testing for exectly one position ( what is hard to meet for users) you go for a target area :
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class Hittester extends Sprite
{
var ball:Sprite = new Sprite();
var testarea:Sprite = new Sprite();
public function Hittester()
{
super();
ball.graphics.beginFill(0xff0000);
ball.graphics.drawCircle(0,0,10);
testarea.graphics.beginFill(0x00ff00);
testarea.graphics.drawRect(0,0,50,50);
testarea.x = 100;
testarea.y = 100;
// if testarea should be invisble
/*testarea.alpha = 0;
testarea.mouseEnabled = false;
*/
ball.addEventListener(MouseEvent.MOUSE_DOWN, startDragging);
addChild(testarea);
addChild(ball);
}
private function startDragging( E:Event = null):void{
ball.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, stopDragging);
}
private function stopDragging( E:Event = null):void{
stage.removeEventListener(MouseEvent.MOUSE_UP, stopDragging);
ball.stopDrag();
test();
}
private function test():void{
if( ! ball.hitTestObject(testarea) ){
ball.x = 10;
ball.y = 10;
}
else{
// here goes next frame command ;)
}
}
}
}

startDrag - stop diagonal movement

Is there a way to have a MovieClip with startDrag, but to force only horizontal and vertical (i.e. not diagonal) movement?
Here is my solution. It tracks the mouseX and mouseY on click and compares it to last position. Finds out which direction the mouse is mainly moving then moves the object there. You may want to add some extra logic to lock the object to the nearest 10th unit or whatever unit size you want to form a snap grid for use in games or organized placement of the object.
Update: I went ahead and added a snapNearest function to help control the movement.
import flash.events.MouseEvent;
import flash.events.Event;
dragObj.addEventListener(MouseEvent.MOUSE_DOWN, dragIt);
var curX:Number = 0;
var curY:Number = 0;
var oldX:Number = 0;
var oldY:Number = 0;
var gridUnit:Number = 25;
function dragIt(e:MouseEvent):void
{
// set x,y on down
oldX = mouseX;
oldY = mouseY;
// add mouse up listener so you know when it is released
stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);
stage.addEventListener(Event.ENTER_FRAME, moveIt);
trace("Start Drag")
}
function moveIt(e:Event):void
{
// figure out what the main drag direction is and move the object.
curX = mouseX;
curY = mouseY;
// figure out which is the larger number and subtract the smaller to get diff
var xDiff:Number = curX > oldX ? curX - oldX : oldX - curX;
var yDiff:Number = curY > oldY ? curY - oldY : oldY - curY;
if(xDiff > yDiff) {
dragObj.x = snapNearest(mouseX, gridUnit);
}else{
dragObj.y = snapNearest(mouseY, gridUnit);
}
oldX = mouseX;
oldY = mouseY;
}
function dropIt(e:MouseEvent):void
{
//remove mouse up event
stage.removeEventListener(MouseEvent.MOUSE_UP, dropIt);
stage.removeEventListener(Event.ENTER_FRAME, moveIt);
trace("Stop Drag")
}
// snap to grid
function snapNearest(n:Number, units:Number):Number
{
var num:Number = n/units ;
num = Math.round(num);
num *= units;
return num;
}
yes. there are a few options.
A. you can choose to use the startDrag() function and supply it's 2nd parameter with a bounds rectangle for your draggable object. something like;
dragSprite.startDrag(false, new Rectangle(0, 0, 20, stage.stageHeight));
B. you can set your draggable object to listen for mouse events, moving it according to the mouse movements. something like:
dragSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
function mouseDownEventHandler(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
function mouseMoveEventHandler(evt:MouseEvent):void
{
//only move dragSprite horizontally
//dragSprite.y = evt.stageY;
dragSprite.x = evt.stageX;
}
function mouseUpEventHandler(evt:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
You could use a modifier key, for instance normal behavior would be horizontal & press down the shift key to move vertically.
function mouseMoveEventHandler(evt:MouseEvent):void
{
if(!evt.shiftKey)
dragSprite.x = evt.stageX;
else
dragSprite.y = evt.stageY;
}
You can only constrain to one axis or the other (using a constraint rectangle) But diagonal movement would be possible in the method you propose, unless you also define some other limits... for example a grid.