How to make my character move relative to the mouse position with actionscript 3? - actionscript-3

ok so i have a character called character_mc and i want it to move towards the mouse when you press the forward arrow and strafe relative to right angles of that.
i am quite new to actionscript so could you please include and example of your code in my original code
Here is my current code:
import flash.events.MouseEvent;
//Event Listners
stage.addChild(crosshair_mc);
crosshair_mc.mouseEnabled = false;
crosshair_mc.addEventListener(Event.ENTER_FRAME, fl_CustomMouseCursor);
function fl_CustomMouseCursor(event:Event)
{
crosshair_mc.x = stage.mouseX;
crosshair_mc.y = stage.mouseY;
}
Mouse.hide();
stage.addEventListener(MouseEvent.MOUSE_MOVE,facecursor);
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_KeyboardDownHandler);
//Functions
function facecursor(event):void
{
character_mc.rotation = (180 * Math.atan2(mouseY - character_mc.y,mouseX - character_mc.x))/Math.PI + 90;
}
function fl_KeyboardDownHandler(event:KeyboardEvent):void
{
trace("Key Code Pressed: " + event.keyCode);
if (event.keyCode == 38)
{
character_mc.y = character_mc.y - 5;
}
if (event.keyCode == 40)
{
character_mc.y = character_mc.y + 5;
}
if (event.keyCode == 39)
{
character_mc.x = character_mc.x + 5;
}
if (event.keyCode == 37)
{
character_mc.x = character_mc.x - 5;
}
}

I can tell you the basic concept of how you could do this, but you'll have to apply it to your own code. To involves converting your movement code to use a vector, then modifying the vector to get a direction facing the mouse (or at right angles to that direction) and a little bit of math.
Right now you have the character moving straight along the x and y axis only in each key press case. Left/Right only move along the X and Up/Down only move along the Y.
To move towards the mouse will require the character to move both along the X and Y when the Up/Down/Left/Right keys are pressed. Clearly you can see if you move both the character's x/y positions by the same amount, say 5, then it'll move exactly at 45 degrees (though it'll actually move a step of 7.07 pixels, hopefully you can see why). You can represent this as a vector: (5,5). You can use a Point object to represent this vector:
var movementVector:Point = new Point(5, 5);
trace(movementVector.x); // gives 5
trace(movementVector.y); // also gives 5
With that in mind, you can also use a vector to represent movement straight up and down on the y axis:
// set the x to 0 and y to 5
movementVector.x = 0; // 0 would mean not to move the character along the x
movementVector.y = 5; // using -5 would move the character up
And to move along the x axis only:
movementVector.x = 5; // using -5 would move the character right
movementVector.y = 0; // 0 would mean not to move the character along the y
To do the actual movement of the character would be the same as you are doing now, except you use the vector's values:
character_mc.x = character_mc.x + movementVector.x;
character_mc.y = character_mc.y + movementVector.y;
Now to figure out the proper vector to move on a diagonal from the character's position to the mouse position is pretty simple. The x value of the vector is the x distance from the character to the mouse, and the y value of the vector is the y distance from the character to the mouse.
Let's say the character is ay 125, 100 and the mouse at 225, 150. This means the distance between the character and mouse is 100, 50 x and y. Thus you'd end up with a vector:
movementVector.x = 100;
movementVector.y = 50;
If you were to apply this vector as it is to the character's position as it is, it would arrive at the mouse instantly (and then go beyond it) as the character is moving 100 pixels along the x and 50 pixels along the y right away. The step size would be 111.8 pixels long -too big. You would need to scale it down to the character's speed. You can do this by calling the normalise() method on the Point class to scale down the vector:
trace(movementVector.x); // gives 100
trace(movementVector.y); // gives 50
// assuming '5' is the max speed of the character
movementVector.normalise(5);
trace(movementVector.x); // gives 4.47213595499958
trace(movementVector.y); // gives 2.23606797749979
This would result in a 'step' size of 5 now. Applying this would make your character move 5 pixels towards a point 100 pixels to the right and 50 pixels down from where it started.
To transform a vector exactly 90 degrees, a quick and simple way is to swap the x and y values around.
If you are curious on what normalise() method mathematically does, is that it takes the x and y values of the vector (or point) and divides it by the length to get a unit vector (or a vector with a step size of 1), then times the input you give it to scale it to the desired length.

To move your character_mc towards the mouse point you only need the direction vector between the two:
var dir:Point = new Point(mouseX - character_mc.x, mouseY - character_mc.y);
dir.Normalize();
// The following should be called when the 'up' or 'forward' arrow is pressed
// to move the character closer to mouse point
character_mc.x += dir.x; // dir can be multiplied by a 'speed' variable
character_mc.y += dir.y;
Strafing left and right around the point is a little more tricky:
// Where radius is the distance between the character and the mouse
character_mc.x = mouseX + radius * Math.cos(rad);
character_mc.y = mouseY + radius * Math.sin(rad);
You should find this tutorial useful as it does everything you describe and more:
http://active.tutsplus.com/tutorials/actionscript/circular-motion-in-as3-make-one-moving-object-orbit-another/

Related

AS3 shooting bullets to cursor from centre of character position

I'm making a top down shooter game. I've got my character moving. All I want to do next is make a bullet shoot from the center of my character to the direction my cursor is at. How would i go about doing this?
I'm really struggling to think of the code i need to make this work.
This will involve simple vector math. There are tons of resources online about this. Here's the basic gist:
1) First, calculate the angle (in radians) between your character and your target (in this case the mouse location). You can use Math.atan2() to perform this calculation.
var angle:Number = Math.atan2(mouseY - playerY, mouseX - playerX);
2) Next, use that angle to create a vector (x,y delta) which represents the direction of travel for your bullet. You use Math.cos() and Math.sin() to compute the x and y value:
var speed:Number = 5;
var vector:Point = new Point(Math.cos(angle) * speed, Math.sin(angle) * speed);
3) Now you can update the bullets position each frame by that vector:
bullet.x += vector.x;
bullet.y += vector.y;
4) And if you want to make your bullet sprite point in the direction of travel, convert that angle to degrees and set the bullet sprite's rotation:
var degrees:Number = angle * (180 / Math.PI);
bullet.rotation = degrees;
Note that for the purpose of the math here, 0 degrees is considered to be right-facing along the x-axis, not up-facing like you might naturally think of 0 degrees (at least I do). What this means is your sprites unrotated orientation should be facing right-ward.

how to move polygon points depending on movement of one point?

i have polygon say (Hexagonal with 6 lines) this Hexagonal connected from center with 6 point That make 6 triangles
I need when move any point(cause to move triangles) ,, other points move like this point i mean if the left point move to lift other points move to the left and so on
the code I want like this ptcP1.x and ptcP1.y the point that i moving it other point move depend on ptcP1 movement note that, this equations work fine in square shape ,, put in Penta and hexa ..etc this equations in valid so can any one help me
function button1_triggeredHandler( event:Event ):void
{
mode="mode2";
//trace(list.selectedIndex);
if(list.selectedIndex==1)
{
DrawSqure.ptcP1.x = Math.random() + 50;
DrawSqure.ptcP1.y = Math.random() + 50;
DrawSqure.ptcP2.y = 50-DrawSqure.ptcP1.x;
DrawSqure.ptcP2.x = DrawSqure.ptcP1.y;
DrawSqure.ptcP3.x = 50-DrawSqure.ptcP1.y;
DrawSqure.ptcP3.y = DrawSqure.ptcP1.x;
DrawSqure.ptcP4.x = 50-DrawSqure.ptcP1.x;
DrawSqure.ptcP4.y = 50-DrawSqure.ptcP1.y;
}
As stated in the comments, storing the vertices/points into a container (Array or Vector) and then adjusting those positions when you move is the best way to do it. Here is an example of how that might work:
//setup array or vector of vertices
var polygonVertices:Array = [DrawPolygon.ptcP1, DrawPolygon.ptcP2, DrawPolygon.ptcP3, DrawPolygon.ptcP4];
This method will take all the vertices and apply the translation:
//function for adjusting all the vertices based on the distance you pass
function moveShape( vertices:Array, dx:Number, dy:Number ) {
var i:int;
for ( ; i < vertices.length; i++ ) {
vertices[i].x += dx;
vertices[i].y += dy;
}
}
Then you would just need to know your distance X & Y your shape has moved and you can call moveShape( polygonVertices, 100, 100 );
I inserted 100,100 as the distance parameters as an example, but this should give you the results you are looking for.

How can I determine whether it's faster to face an object rotating clockwise or counter clockwise?

I've been trying this to no avail for some days now, but basically I have some creatures and the player on the screen. What I want to happen is for the enemies to turn to face the player at a variable speed, rather than 'lock' into position and face the player immediately.
What I am trying to do is work out whether it is faster for a given enemy to rotate clockwise or counter clockwise to face the player, but it's proving to be beyond my capabilities with trigonometry.
Example:
x in these figures represents the 'shorter' path and the direction I want to rotate in each situation.
What is the simplest way to work out either 'clockwise' or 'counter-clockwise' in this situation, using any of the following:
The direction the enemy is facing.
The angle between the enemy to the player, and player to the enemy.
There is no need to calculate angles or use trigonometric functions here, assuming you have a direction vector.
var pos_x, pos_y, dir_x, dir_y, target_x, target_y;
if ((pos_x - target_x) * dir_y > (pos_y - target_y) * dir_x) {
// Target lies clockwise
} else {
// Target lies anticlockwise
}
This simply draws an imaginary line through the object in the direction it's facing, and figures out which side of that line the target is on. This is basic linear algebra, so you should not need to use sin() or cos() etc. anywhere in this function, unless you need to calculate the direction vector from the angle.
This also uses a right-handed coordinate system, it will be backwards if you are using a left-handed coordinate system -- the formulas will be the same, but "clockwise" and "anticlockwise" will be swapped.
Deeper explanation: The function computes the outer product of the forward vector (dir_x, dir_y) and the vector to the target, (target_x - pos_x, target_y - pos_y). The resulting outer product is a pseudoscalar which is positive or negative, depending on whether the target is clockwise or anticlockwise.
Crash course on vectors
A vector is a magnitude and direction, e.g., 3 km north, or 6 centimeters down. You can represent a vector using cartesian coordinates (x, y), or you can represent it using polar coordinates (r,θ). Both representations give you the same vectors, but they use different numbers and different formulas. In general, you should stick with cartesian coordinates instead of polar coordinates. If you're writing a game, polar coordinates suck royally — they litter your code with sin() and cos() everywhere.
The code has three vectors in it:
The vector (pos_x, pos_y) is the position of the object, relative to the origin.
The vector (target_x, target_y) is the position of the target, relative to the origin.
The vector (dir_x, dir_y) is the direction that the object is facing.
const CLOCKWISE:int = 0;
const COUNTER_CLOCKWISE:int = 1;
const PI2:Number = Math.PI * 2
function determineSmallestAngle(from:Sprite, to:Sprite):int
{
var a1:Number = Math.atan2(to.y - from.y, to.x - from.x);
var a2:Number = from.rotation * Math.PI / 180;
a2 -= Math.floor(a2 / PI2) * PI2;
if(a2 > Math.PI) a2 -= PI2;
a2 -= a1;
if (a2 > Math.PI) a2 -= PI2;
if (a2 < -1 * Math.PI) a2 += PI2;
if (a2 > 0) return CLOCKWISE;
return COUNTER_CLOCKWISE;
}

AS3: diagonal movement

I'm programming a flash game, I made an array of points (x and y positions) that some movieclips must follow. Those movieclips have a certain speed (they make steps of 5 pixels for now). When I want to move them horizontally or vertically, everything's fine, I have to add or remove 5 pixels of those clips' x or y. But sometimes they have to move diagonally and now that's complicated.
What I'm doing:
var angle:Number = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x) * 180 / Math.PI;
var xstep:Number = Math.cos(angle) * this.speed;
var ystep:Number = Math.sqrt(Math.pow(this.speed, 2) - Math.pow(xstep, 2));
this.x += xstep;
this.y += ystep;
It's only a fraction of the code, but I think it's all you need.
Basically, this makes my movieclip do a little step (of this.speed (currently set to 5) pixels).
If the current point and the next point have the same y position, it works fine. When they don't, it doesn't work. The angle is right at first but it slowly decreases (while it should stay the same). I don't know if it's the angle that isn't computed the right way or if it's the x and y steps, but it's one of those, I'm sure.
Try this instead:
var angle:Number = Math.atan2(nextPoint.y - this.y, nextPoint.x - this.x);
var xstep:Number = Math.cos(angle) * this.speed;
var ystep:Number = Math.sin(angle) * this.speed;
Because cos operates on angles in radians, you don't need to convert to degrees. Computing the y component of an angle uses sin, so it should be similar to x. I'm not able to test this, but it's possible that ystep will be backwards and may need to be multiplied by -1.

Flash AS3 tweening at an angle

Hi I have a as3 file (listed below) that simply moves a box along the X axis when a mouse is over it (using Tweenlight) . What I want to do though is put the box on a 30 degree angle and have the box move along this angle. Can anybody tell me what I am doing wrong please ?
import com.greensock.*;
import com.greensock.easing.* ;
cont.addEventListener(MouseEvent.ROLL_OVER, onOver);
cont.addEventListener(MouseEvent.ROLL_OUT, onOut);
var stx:Number;
function onOver(e:MouseEvent):void
{
var stx:Number = cont.x +20 ;
TweenLite.to(cont, 1, { x:stx });
}
function onOut(e:MouseEvent):void
{
stx = cont.x - 20
TweenLite.to(cont, 1, { x:stx } );
}
Here is live example: http://img42.imageshack.us/i/box.swf/
The hardest thing is to move your box on a line at a 30 degree angle.
You'll have to use Trigonometry...remember SOHCAHTOA?
So basically you'll need to move in the x and the y direction.
In your onOver handler...
you want to move x to 20Math.cos(30Math.PI/180)
you want to move y to 20Math.sin(30Math.PI/180)
The cos and sin gives you the x and y steps to keep your objects moving along 30 degrees.
If you want your object to move more change the 20 parameter.