AS3 shooting bullets to cursor from centre of character position - actionscript-3

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.

Related

AS3 move object towards x,y and then continue in the same direction (using tweener)

I'm building a simple space shooter game
using Tweener class I wrote a code that fires a bullet from the hero spaceship current position to the mouse current position
var fire = new Bullet();
addChild(fire);
fire.x = ship.x + (ship.width * 0.5);
fire.y = ship.y
Tweener.addTween(fire, {x:_me.currentTarget.mouseX, y:_me.currentTarget.mouseY, time: 5} );
the problem is this code makes the bullet stop at the last mouse position
and I want the bullet to continue moving in the same direction until it's outside of the stage.
theoretically, the most simple way would be to input x.y position of the mouse as if it was at the same angle but outside of the stage
but how can i get those x,y coordinates??
determine the angle of the bullet.
using the angle, consider the origin of the bullet the center of a circle and the first point as a coordinate at the edge of the circle.
for the bullet to follow the same path, its just a larger circle, so the radius will increase.
the angle will be the same and so will the origin.
I think what you you want is to find a point one the same straight line with (fire.x, fire.y) , (_me.currentTarget.mouseX, _me.currentTarget.mouseY). And the point's x would be stage width.
So assume target point is A(stage.width, targetY)
We get
(targetY - mouseY)/(targetX - mouseX) = (mouseY - fire.y)/(mouseX - fire.x)
So
targetY = (mouseY - fire.y)/(mouseX - fire.x)*(targetX - mouseX) + mouseY;
Hero mouseX is _me.currentTarget.mouseX, mouseY is _me.currentTarget.mouseY
You can set targetX = stage.width + 10, then targetY
So you can get targetY, and do another tween
Tweener.addTween(fire, {x:targetX, y:targetY , time: 5} );

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;
}

Particles Shooting Out at Random Angles Between Certain Angles

Hello all,
I'm creating a game where some particles are created after a collision between two objects. The particles are then given a random x and y velocity and they shoot out in every direction. I've been trying to alter the way the particles shoot out to resemble Figure 1, where the particles shoot out at a randoom angle between 330 to 30 and 150 to 210 (I wrote the angles in degrees rather than radians for an ease in understanding). The red areas in Figure 1 are where the particles shouldn't shoot out and the blue is where they should. I have not been able to achieve the desired effect however. I was wondering if anyone could assist with a link to helpful reading or an example in code. I have been searching google but cannot find a decent example.
Figure 1
Notes:
- The angles are written in degrees but will need to be changed to radians because Flash uses radians, a simple conversion (Math.pi/180) added to the code should suffice.
- Figure 1 resembles the Cartesian Coordinate system but the y axis is inverted in Flash's coordinate system.
- I would post the code that I have tried but it is so far from what is desired that it would not help.
var speed:Number = minSpeed + Math.random() * (maxSpeed - minSpeed);
var angle:Number = Math.random() * 120 - 30;
if (angle > 30) angle += 120;
angle *= Math.PI/180;
var speedX = Math.cos(angle) * speed;
var speedY = Math.sin(angle) * speed;

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.

rotation problems when firing

I have a big problem when I try to rotate my projectiles along with the ship's rotation.
I want my spaceship shoot two shots at once. So I used my first array of projectiles and placed them at the right side of the ship (one shot on the left and one on the right). So far so good.
But when I shoot with my spaceship and I turn around the rotations of the projectiles look very strange. It's hard to describe so here's an image that shows the error in action.
http://imageshack.us/photo/my-images/841/projectilebug.jpg
I have huge problems rotating the projectiles ALONG with the spaceship so that it looks really good. Currently there is one single shot only. My shooting gets screwed up when I rotate and fire at once.
The goal is to create a dual firing cannon like in the picture shown.
Here is some code that places the projectile at the left of the ship (that doesn't really work):
var projectileRadians:Number = (player.frame / 180) * 3.14159;
tempProjectile.x = (player.point.x + 6) + Math.cos(projectileRadians);
tempProjectile.y = (player.point.y + 3) + Math.sin(projectileRadians);
The velocity code:
tempProjectile.nextX = tempProjectile.x;
tempProjectile.nextY = tempProjectile.y;
tempProjectile.dx = rotationVectorList[player.frame].x;
tempProjectile.dy = rotationVectorList[player.frame].y;
This updates the position:
nextX += (dx * (speed + Math.abs(xAdjust))) * step;
nextY += (dy * (speed + Math.abs(yAdjust))) * step;
The velocity code looks ok. You don't seem to be calculating the gun position correctly.
Edit: we're not using the standard trig frame of reference; instead, we're using one where angle=0 means up and angles increase as you rotate clockwise. So we take the standard usage and swap sin and cos.
Here, gx and gy mean the coordinates of a gun relative to the coordinates around which the ship moves. We need to rotate the vector <gx, gy> by the angle before adding it to the ship coords:
cs = Math.cos(projectileRadians);
sn = Math.sin(projectileRadians);
tempProjectile.x = player.point.x + gx * sn - gy * cs;
tempProjectile.y = player.point.y + gx * cs + gy * sn;
It would be a good optimization to restrict the ship's angle to certain values (perhaps every 5 degrees), and put all the trig functions into a table ahead of time. Trig functions are expensive to compute.
Note that this also assumes that positive Y is "up". Computer graphics often start with (0, 0) in the upper left corner and increase Y as you move down, so you may have to switch the sign of Y.