
Ship Movement
Hi everyone!
I am making a shooter game, where the player control a ship. The user moves accelerating with a keyboard key, but moves towards the mouse cursor. I had to use sin and cos functions to discover the ship horizontal and vertical speeds. This works very fine, however, I want to add another functionality. The player must be able to move to left and right (the classical side step). I have discovered a good algorithm for this kind of movement, but it has some problems that I dont know how to solve efficiently. My question, finally, is: does anyone know a good algorithm for this kind of movement (where the user can move ANY direction)?
Thanks any help!

This doesnt answer your question but that is the most well thought out and well structured question I think I have ever heard. Gratz. Sorry I dont really know about the subject your talking about.

I believe you're looking for addition and subtraction.

Why don't you post the code that your having problems with?

Are you talking about strafing? Also, I'm unsure if you are talking about 2D or 3D but I will discuss the technique for both.
2D: You should at least have a forward vector for your ship at all times. This way when he spins around you rotate the forward vector and you know which way he is facing. Then presumably to move you simply do something like:
//playerPos and forward are both 2D vectors and k is a real valued scalar (forward should be normalized at all times)
playerPos += forward * k;
To strafe you would simply calculate the vector that cuts the ship in half the other way. You would rotate your forward vector by 90 degrees to obtain this vector. Then you would do the same some or update with this new vector for strafing.
3D: This would be pretty much the same except you probably already have a view system for your ship (uvn) or (right up forward). So you simply use the u vector for this calculation.

If you have a view system setup for your ship in 3D then simply translate along the right look vector by either a negative value for left strafe or a positive vale for right strafe.
Ship.VelocityVector+=(Ship.right*Ship.strafe_speed );
Given that VelocityVector and right are 3D vectors and strafe_speed is a scalar.
This of course does not show a view matrix. This is really just the concept of what needs to be done. For more information check the moving through 3D space post.

Hi again!
Thanks for all the help until now! :)
Sorry, I forgot to tell that my game is 2D. Ok, I will post the piece of code that works for forward movement. In the code, x, y are the mouse coordinates. clWidth and clHeight is the sprite dimension, not very important. The number 4 is the maximum speed (will be a class attribute later).
Code:
// Critical region
WaitForSingleObject(clSemVel, INFINITE);
{
// Update ship angle
int base = x  clX(clWidth/2); // base of triangle
int height = y  clY(clHeight/2); // height of triangle
hipotenusa = sqrt(pow(base, 2) + pow(altura,2));
clAngleY = height/hipotenusa;
clTopYSpeed = clAngleY * 4;
clAngleX = base/hipotenusa;
clTopXSpeed = clAngleX * 4;
}
// End of critical region
ReleaseSemaphore(clSemVel, 1, NULL);
Now, I know that to do strafe, the Y speed must be equal to X speed, and X equal to Y, the problem is the sign of the variable, remembering that a negative value in Y, the object moves up, and negative in X the object moves left.
Code:
// Critical region
WaitForSingleObject(clSemVel, INFINITE);
{
// User has pressed strafe
int sign_y = 0;
int sign_x = 0;
if( strafe == LEFT ){
sign_y = 1; //for example
sign_x = 1; //for example too
}
if( strafe == RIGHT ){
sign_y = 1; //another example
sign_x = 1; //yes... example
}
cpTopYSpeed = sign_y * clTopXSpeed;
cpTopXSpeed = sign_x * clTopYSpeed;
}
// End of critical region
ReleaseSemaphore(clSemVel, 1, NULL);
The problem is that the sign calculation is too complex for my understanding. If anyone have a better idea ou the algoritm itself, I am grateful.

You can represent all directions in 2D with 3 basis vectors. Position, X, and Y.
struct vector2D
{
float x;
float y;
};
Second, you can compute the vector between two objects by first subtracting the vectors to produce a third vector and then normalize that vector. The normalization is simply the square root of the dot product of the vector. Or you can store each movement vector as a prenormalized vector and then rotate the prenormalized vector. However with this approach you will still have to normalize the resulting vector if you do anything with it.
So here is a small snippet that might help.
Code:
#define PI 3.14159f
#define DEGTORAD(x) (float)((float)(x)*(PI)/(180.0f))
struct Object
{
point2D Position;
float Rotation;
float RotateTo;
point2D VelocityVector;
float Speed;
};
void Update(Object &unit)
{
unit.Position.x+=(unit.VelocityVector.x*unit.Speed);
unit.Position.y+=(unit.VeclotiyVector.y*unit.Speed);
}
void SetVectorAngleRadians(Object &unit,float x_radians,float y_radians)
{
//Set velocity vector based on angle in radians
unit.VelocityVector.x=cosf(_xradians);
unit.VelocityVector.y=sinf(_yradians);
}
void SetVectorAngleDegrees(Object &unit,float x_degrees,float y_degrees)
{
//Get cos and sin of our angles
unit.VelocityVector.x=cosf(DEGTORAD(x_degrees));
unit.VelocityVector.y=sinf(DEGTORAD(y_degrees));
}
void GetVectorToCursor(Object &unit,point2D MouseCursor)
{
//Compute vector from object to mouse
point2D ToMouse;
ToMouse.x=unit.xMouseCursor.x;
ToMouse.y=unit.yMouseCursor.y;
//Normalize vector
float dist=sqrt((ToMouse.x*ToMouse.x)+(ToMouse.y*ToMouse.y));
//Floating point mul instead of floating point divide
float oneOverDist=1/dist;
//Set new velocity vector to move towards mouse
unit.VelocityVector.x=ToMouse.x*oneOverDist;
unit.VelocityVector.y=ToMouse.y*oneOverDist;
//Set new rotation value that we need to rotate to
unit.RotateTo=atan2(unit.VelocityVector.x,unit.VelocityVector.y);
}

Thank you all for the help. Altought it is not very clear what I must do I will work on the ideas.