Creating an Asteroids Clone - Part 3
This is the updated program files:
AsteroidsClone.zip ( 3.38k )
Number of downloads: 134 This is my third tutorial on creating an Asteroids Clone using XNA 3.0. You will have to have completed the first two tutorials in this series. These are the links for the first two tutorials:
Tutorial 1Tutorial 2So, in this tutorial I will show you how to get the ship to move around the screen and activate a Hyper Space feature. The asteroids will be a little distracting so comment out these two lines:
XNA
if (asteroids.Count == 0)
CreateAsteroids();
Asteroids had an interesting feature. While you were thrusting your ship accelerated to a certain velocity then stopped When you stopped thrusting your ship slowly slowed down. I've tried my best to incorporate this. To get started you will want to add this statement to your
Update method:
XNA
if (newState.IsKeyDown(Keys.Up))
{
AccelerateShip();
}
else if (newState.IsKeyUp(Keys.Up))
{
DecelerateShip();
}
You should add these lines before this line:
XNA
oldState = newState;
I separated the logic for accelerating and decelerating the ship from the
Update method to try and keep it clean. So, what this does is if the Up key is down it accelerates the ship and if it is up decelerates the ship.
As I usually do I will show you the code and then explain it. This is the
AccelearteShip method:
XNA
private void AccelerateShip()
{
ship.Velocity += new Vector2(
(float)(Math.Cos(ship.Rotation - MathHelper.PiOver2) * 0.05f),
(float)((Math.Sin(ship.Rotation - MathHelper.PiOver2) * 0.05f)));
if (ship.Velocity.X > 5.0f)
{
ship.Velocity = new Vector2(5.0f, ship.Velocity.Y);
}
if (ship.Velocity.X < -5.0f)
{
ship.Velocity = new Vector2(-5.0f, ship.Velocity.Y);
}
if (ship.Velocity.Y > 5.0f)
{
ship.Velocity = new Vector2(ship.Velocity.X, 5.0f);
}
if (ship.Velocity.Y < -5.0f)
{
ship.Velocity = new Vector2(ship.Velocity.X, -5.0f);
}
}
First you need to determine what direction to accelerated the ship. This is just like finding what direction the bullets are traveling. Since the ship is pointing in the direction it is you need to subtract Pi over 2 from the rotation angle. Again, you use the Cos of the rotation and the Sin of the rotation. After experimenting a little I found that a 0.05 multiplier gave a good acceleration factor. You add the new velocity to the old velocity since the ship is accelerating After you find the new velocity of the ship you go through a series of if statements to limit the velocity. I've limited the velocity in one direction to 5.0. Again, this was after some experimenting.
Now you need a way to bleed off the velocity while the ship is not thrusting. Again, I will show the method and explain it. Here is the
DecelearteShip method:
XNA
private void DecelerateShip()
{
if (ship.Velocity.X < 0)
{
ship.Velocity = new Vector2(
ship.Velocity.X + 0.02f, ship.Velocity.Y);
}
if (ship.Velocity.X > 0)
{
ship.Velocity = new Vector2(
ship.Velocity.X - 0.02f, ship.Velocity.Y);
}
if (ship.Velocity.Y < 0)
{
ship.Velocity = new Vector2(
ship.Velocity.X, ship.Velocity.Y + 0.02f);
}
if (ship.Velocity.Y > 0)
{
ship.Velocity = new Vector2(
ship.Velocity.X, ship.Velocity.Y - 0.02f);
}
}
The
DecelerateShip method is similar to the
AccelerateShip method. If the velocity is negative in a direction the velocity in that direction is increased. Also, if the velocity is positive in a direction the velocity in that direction is decreased. Again, I used 0.02 after experimentation and found it a good value.
Now you have to update the position of the ship with the velocity of the ship. In the
Update method add this code just above where you call the
UpdateAsteroids method:
XNA
UpdateShip();
The
UpdateShip method is where you will update the ship's position. The code is almost identical to the
UpdateAsteroids method. The only difference is instead of using the width and height of the asteroid, you use the width and height of the ship. Here's the code:
XNA
public void UpdateShip()
{
ship.Position += ship.Velocity;
if (ship.Position.X + ship.Width < 0)
{
ship.Position = new Vector2(ScreenWidth, ship.Position.Y);
}
if (ship.Position.X - ship.Width > ScreenWidth)
{
ship.Position = new Vector2(0, ship.Position.Y);
}
if (ship.Position.Y + ship.Height < 0)
{
ship.Position = new Vector2(ship.Position.X, ScreenHeight);
}
if (ship.Position.Y - ship.Height > ScreenHeight)
{
ship.Position = new Vector2(ship.Position.X, 0);
}
}
None of that code should be new. You change the position of the ship with the ship's velocity then check the bounds of the screen to see if it has traveled off the screen, if it has you move it to the other side of the screen.
So, that just leaves the Hyper Space feature to add. You will need to add two if statements to your
Update method before the line:
XNA
oldState = newState;
These are the if statements:
XNA
if (newState.IsKeyUp(Keys.LeftControl) &&
oldState.IsKeyDown(Keys.LeftControl))
{
HyperSpace();
}
if (newState.IsKeyUp(Keys.RightControl) &&
oldState.IsKeyDown(Keys.RightControl))
{
HyperSpace();
}
They are like the code used to check if the space bar has been pressed and released. I went with the control keys to activate the Hyper Space feature. You can use any key you want. So, if one of the control keys is pressed you call the
HyperSpace method. I will show you the code, then explain it. Here's the code:
XNA
private void HyperSpace()
{
int positionX;
int positionY;
Random random = new Random();
positionX = random.Next(ship.Width, ScreenWidth - ship.Width);
positionY = random.Next(ship.Height, ScreenHeight - ship.Height);
ship.Position = new Vector2(positionX, positionY);
ship.Velocity = Vector2.Zero;
}
All this code does is create two variables to hold a random X and Y value. Creates a random number generator. To find the new x position of the ship I generated a number between the width of the ship and the width of the screen minus the width of the ship. As well, the new y position is between the height of the ship and the height of the screen minus the height of the ship. I did this so the ship will always be on the screen. Next I set the position of the ship and kill it's velocity.
So now you should be able to fly around the screen and activate a hyper space feature. I will post the new Game1.cs file for download.
You will notice something odd though. The speed of the bullets when the ship is accelerating or decelerating act a little weird. I will fix this in another tutorial. I think the next tutorial will be about collision detection between the asteroids and the ship. There are a couple of different techniques that can be used. I will try the simpler of them and then, in a separate set of tutorials I will discuss about different methods of checking for collisions.