Page 1 of 1

XNA 3.0 Game Tutorial - Part 3 Making an Asteroids clone

#1 SixOfEleven  Icon User is offline

  • using Caffeine;
  • member icon

Reputation: 945
  • View blog
  • Posts: 6,342
  • Joined: 18-October 08

Post icon  Posted 23 April 2009 - 09:26 PM

Creating an Asteroids Clone - Part 3

This is the updated program files:Attached File  AsteroidsClone.zip (3.38K)
Number of downloads: 621

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 1

Tutorial 2

So, 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:

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:

if (newState.IsKeyDown(Keys.Up))
{
    AccelerateShip();
}
else if (newState.IsKeyUp(Keys.Up))
{
    DecelerateShip();
}



You should add these lines before this line:

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:

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:

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:

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:

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:

oldState = newState;



These are the if statements:

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:

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.

Is This A Good Question/Topic? 2
  • +

Page 1 of 1