Source code: http://www.bluerosegames.com/spacerocks/spacerocks_7_moving_ship.zip
In the last step we added logic to rotate the ship based on key presses. Moving the ship isn’t that different but we need to do a little trigonometry to get it moving in the right direction. The first thing we need is to check for the up key being pressed. We’ll use this as the key press to fire the ship’s engines. Here is our game loop with the added check for the cursor up key (and the W key):
private void GameLoop_Update(object sender, SilverArcade.SilverSprite.SimpleEventArgs<TimeSpan> e)
{
double seconds = e.Result.TotalSeconds;
KeyboardState keyState = Keyboard.GetState();
if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A))
{
ship.Rotation += (float)(rotationSpeed * seconds);
}
else if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D))
{
ship.Rotation -= (float)(rotationSpeed * seconds);
}
if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W))
{
UpdateShipVelocity(seconds);
}
ship.Update(seconds);
}
So when the up cursor key or W is pressed we’ll update the ship’s velocity by calling the UpdateShipVelocity method.This hasn’t been defined yet, so let’s define it:
float maxShipSpeed = 500;
float shipAcceleration = 100;
Vector2 RadiansToVector(float radians)
{
return new Vector2(-(float)Math.Sin(radians), -(float)Math.Cos(radians));
}
void UpdateShipVelocity(double seconds)
{
Vector2 normal = RadiansToVector(ship.Rotation);
ship.Velocity += normal * (float)seconds * shipAcceleration;
if (ship.Velocity.Length() > maxShipSpeed)
{
ship.Velocity = Vector2.Normalize(ship.Velocity) * maxShipSpeed;
}
}
UPDATE: Fixed issue with RadiansToVector method. It was always using the ship’s rotation instead of using the passed in value.
The RadiansToVector method returns a normalized Vector2 based on the ship’s rotation in the direction that the ship is facing. Normalized means that if you calculate the length of the vector, the length would be 1. From the pythagorean theorem (remember that from high school math?) we know that the length of the vector is the square root of the sum of the squared of the X and Y component. This normalized vector can be calculated from taking the sine and the cosine of the angle of rotation (that trigonometry stuff I was talking about).
NOTE: To do the opposite and find the angle from the vector you can use the Math.Atan2 method.
We can then combine this direction vector with the elapsed time and the ship’s acceleration to calculate a change in velocity. We can add this to the current velocity to create a new velocity.
Finally we need a maximum speed for the ship, otherwise it could just go to ludicrous speed after a while. If the speed goes above the max, we can get the normal of this velocity vector (explained above) and multiply that by the max speed.
If you run the game now you should be able to move the ship.
April 23rd, 2010 at 11:04 AM
[...] There was a bug in the RadiansToVector method listed in step 7, it has been fixed and the correct version is [...]