# Ship Movement

• 11-21-2004
gustavosserra
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!
• 11-21-2004
Siggy
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.
• 11-21-2004
sean
I believe you're looking for addition and subtraction.
• 11-21-2004
manofsteel972
Why don't you post the code that your having problems with?
• 11-21-2004
MrWizard
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.
• 11-21-2004
VirtualAce
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.
• 11-22-2004
gustavosserra
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.
• 11-23-2004
VirtualAce
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 pre-normalized vector and then rotate the pre-normalized 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.x-MouseCursor.x;   ToMouse.y=unit.y-MouseCursor.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); }```
• 11-27-2004
gustavosserra
Thank you all for the help. Altought it is not very clear what I must do I will work on the ideas.