Jump to content
  • Advertisement
Sign in to follow this  
Side Winder

Asteroids-like ship movement

This topic is 4165 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've got the basis down. So far, the ship accelerates to a certain maximum velocity, and then stays at that velocity. Even when the up-key is let go, the ship will continue at that velocity until the ship is rotated and the up-key is once again pressed. What I want is for the ship to "drag" once the up-key is let go. I would also like for the ship to have (I'm guessing here) two vectors for movement. So that when the user rotates and presses the up-key again, the ship will not immediately change course but change course slowly over a period of time. How can I do this? I'm trying to do it like this.

Share this post


Link to post
Share on other sites
Advertisement
I'm assuming you already have a movement vector. The next step is to create a vector based off of the direction the ship is facing (not moving) and the magnitude of the thrust. Add that to the movement vector to apply thrust. As far as drag goes, I'm pretty sure that astroids style games don't have drag but it'd relatively easy to implement. Just reduce the magnitude of the movement vector at time based intervals when thrust isn't being applied. Does this make sense?

Share this post


Link to post
Share on other sites
Quote:
Original post by tstrimp
I'm assuming you already have a movement vector. The next step is to create a vector based off of the direction the ship is facing (not moving) and the magnitude of the thrust. Add that to the movement vector to apply thrust. As far as drag goes, I'm pretty sure that astroids style games don't have drag but it'd relatively easy to implement. Just reduce the magnitude of the movement vector at time based intervals when thrust isn't being applied. Does this make sense?


Yes, I have a vector.

By direction vector, you mean normalising the vector?

Share this post


Link to post
Share on other sites
Quote:
Original post by Side Winder
By direction vector, you mean normalising the vector?

No, he means a vector that represents the thrust velocity.

To effect Asteroids-style movement, you need one vector to represent the velocity of the ship and another to represent the thrust velocity. Each cycle, you add the thrust velocity to the ship velocity to yield the resultant movement vector of the ship. In addition, each cycle you add the ship acceleration (typically slightly negative, for a gradual deceleration effect) to the ship velocity and the thrust acceleration (ranges from negative, for deceleration, to zero or slightly positive, to achieve a stable top speed) to the thrust velocity. Also keep in mind that the accelerations are perfectly parallel to the velocities in this simplistic simulation.

Share this post


Link to post
Share on other sites
No. The direction vector is the angle that the ship is facing and the magnitude of the thrust. I'm not sure how else to explain it. Does your vector class support adding vectors? Post some of the code for your ship movement. Maybe I'll be able to give you an example using your own code.

Share this post


Link to post
Share on other sites
I'm using DirectX so, yes, it does support adding vectors.

Here's the code:

Draw function

void Draw(float x, float y)
{//draws the sprite at max alpha
m_SpeedX += m_AccelX;
m_SpeedY += m_AccelY;

D3DXVECTOR3 centre(0.0f, 0.0f, 0.0f);
D3DXVECTOR3 position(x, y, 0.0f);
movement = D3DXVECTOR2(m_SpeedX, m_SpeedY);

D3DXMatrixTransformation2D(&matrix, NULL, NULL, NULL, &SpriteCentre, m_Rotation, &movement);
d3dSprite->SetTransform(&matrix);

d3dSprite->Draw(m_Sprite, NULL, NULL, &position, D3DCOLOR_ARGB(255, 255, 255, 255));

return;
}



HandleUp function

HandleUp()
{//handles forward movement
if (KEY_DOWN(VK_UP))
{
m_AccelX = m_Acceleration * cos(m_Rotation);
m_AccelY = m_Acceleration * sin(m_Rotation);

m_SpeedX += m_AccelX;
m_SpeedY += m_AccelY;
}

}



Rotation is initially set at (-PI/2) so the ship starts facing upwards.
m_Acceleration initialises at 2.0f
The rest start at 0.0f

edit: I realise the parameters in my draw function have no meaning what-so-ever... Oops.

[Edited by - Side Winder on June 13, 2007 12:16:51 PM]

Share this post


Link to post
Share on other sites
I've tried following both of your instructions, but I still can't get it to work. Any chance you could look at the source code above and let me know what needs changing where? Thanks for any help.

Share this post


Link to post
Share on other sites
I just did this in my game...

You need a position vector, a rotation float, a velocity vector and a friction float, between 0 and 1, where 1 is no friction and 0 is no movement, counter intuitive, but it saves a calculation.

in your update function do...

position += velocity;
velocity *= friction;

if(key == 'i')
{

CVector3 dir(sin(rotation*(PI/180)),0,cos(rotation*(PI/180)));
velocity = velocity + Normalize(direction)*acceleration;

}
else if(key == 'k')
{
CVector3 dir(sin(rotation*(PI/180)),0,cos(rotation*(PI/180)));
velocity = velocity - Normalize(direction)*acceleration;
}
else if(key == 'j')
{
rotation+=speed;
}
else if(key == 'l')
{
rotation-=speed;
}

Now since you said you want a top speed there are a couple ways to do that. You can either get the magnitude of the velocity vector, check to see if it's greater than a certain float value, if so, normalize the velocity and multiply it by the max_speed in order to get your new velocity.

Share this post


Link to post
Share on other sites
you could always use a momentum value, if i remember the old asteroids game correctly...
lets say have a member M which is a mementum value of 0.95.
for your velocity update which you have:
Speed += Acceleration;
try:
Speed += (M*Speed)+((1-M)*Acceleration);

what this will do is only add a fraction of the new velocity making the ship take time to change direction, altering the value of M to a lower value will make the ship more responsive.

Hope this helps

Share this post


Link to post
Share on other sites
I may be repeating what people have said above but this is how I would do it:

Suppose your ship has a position, velocity, and direction. Where direction is where the ship is facing, and the direction in which thrust will be applied.

Each update you can do something like this:



void UpdatePlayerMotion()
{

float ax = 0.0 ;
float ay = 0.0 ;

if( player_thrust ) // If the player is trying to accelerate set by your input code
{
ax += THRUST_MAGNITUDE*Player->DirectionVector.x ;
ay += THRUST_MAGNUTIDE*Player->DirectionVector.y ;
}

ax -= FRICTION_MAGNITUDE*Player->VelocityVector.x ;
ay -= FRICTION_MAGNITUDE*Player->VelocityVector.y ;

Player->VelocityVector.x += ax*dt ;
Player->VelocityVector.y += ay*dt ;

Player->PositionVector.x += Player->PositionVector.x*dt ;
Player->PositionVector.y += Player->PositionVector.y*dt ;

}




THRUST_MAGNITUDE is some value that determines, well the magnitude of the thrust and FRICTION_MAGNITUDE is magnitude of the drag. And the DirectionVector should be normalized, but that can be handled by whatever code handles changing the direction when the player hits the arrow keys or whatever.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!