Ship Movement

This is a discussion on Ship Movement within the Game Programming forums, part of the General Programming Boards category; Hi everyone! I am making a shooter game, where the player control a ship. The user moves accelerating with a ...

  1. #1
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244

    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!
    Nothing more to tell about me...
    Happy day =)

  2. #2
    Registered User
    Join Date
    Jun 2004
    Posts
    52
    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.

  3. #3
    Super Moderator
    Join Date
    Sep 2001
    Posts
    4,913
    I believe you're looking for addition and subtraction.

  4. #4
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    Why don't you post the code that your having problems with?
    "Knowledge is proud that she knows so much; Wisdom is humble that she knows no more."
    -- Cowper

    Operating Systems=Slackware Linux 9.1,Windows 98/Xp
    Compilers=gcc 3.2.3, Visual C++ 6.0, DevC++(Mingw)

    You may teach a person from now until doom's day, but that person will only know what he learns himself.

    Now I know what doesn't work.

    A problem is understood by solving it, not by pondering it.

    For a bit of humor check out xkcd web comic http://xkcd.com/235/

  5. #5
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    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.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  6. #6
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    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.
    Last edited by VirtualAce; 11-22-2004 at 12:06 AM.

  7. #7
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244

    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.
    Nothing more to tell about me...
    Happy day =)

  8. #8
    Super Moderator VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,596
    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);
    }

  9. #9
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244
    Thank you all for the help. Altought it is not very clear what I must do I will work on the ideas.
    Nothing more to tell about me...
    Happy day =)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Battle Ship AI
    By IdioticCreation in forum Game Programming
    Replies: 10
    Last Post: 01-05-2007, 10:22 PM
  2. I need movement...
    By Finchie_88 in forum C++ Programming
    Replies: 1
    Last Post: 10-04-2004, 03:10 PM
  3. natural leg movement
    By DavidP in forum Game Programming
    Replies: 32
    Last Post: 01-11-2004, 08:01 AM
  4. Movement
    By drdroid in forum C++ Programming
    Replies: 5
    Last Post: 02-09-2002, 10:02 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21