# Asteroids-like ship movement

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

## 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 on other sites
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 on other sites
Quote:
 Original post by tstrimpI'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 on other sites
Quote:
 Original post by Side WinderBy 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 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 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 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 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.

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 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 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.

• 10
• 16
• 14
• 18
• 15