Godar's Game Development Package Tutorial.


Missile Fire, sprite movement and collision detection.

My basic asteroids game.

Here it is the first thing to look like a game made with the GGD package. I will be showing some basic techniques that are used to create this asteroids type clone. There are a number of algorithms required to create this type of game so I will only be outlining a few of them. I have a number of game templates one of which is the MyRoids template it will contain more advanced techniques within the asteroids game development.

PlayerSprite:

It's role is simple it controls the player's sprite in this case it's a dragon looking character.The ship should rotate fire a missile and move around the screen. If the player sprite is off the screen it wraps around to the opposite side of the screen. The first thing to note is the constructor it calls the methods discussed in previous tutorials to set up the sprites characteristics. The update function look daunting at first but it handel's two simple function updating the sprite position and ensuring the position is wrapped around the screen when the location of the sprite falls off. The algorithm to wrap any type of sprite around any bounds look like the pseudo code below:

If the left side of the sprite is > the right side of the screen
    sprite location = screen left - sprite width;
Else if the right side of the sprite is < the left side of the screen
    sprite location = screen right;
Else if the bottom of the sprite is < the top of the screen
    sprite location = screen bottom;
Else if the top of the sprite > the bottom of the screen
    sprite location = screen top - sprite height;

Wrapping algorithm. (This algorithm assumes that all sprites are drawn from the top right)

because the velocity values are added to the sprites location values when the sprite is place on to the other side of the screen it continues into the window on its predefined path. That's why it is essential that when the sprite is flipped to the other side of the screen it is drawn just out of the screens bounds so that it emerges into the screen.

The other main function of the player sprite is the thrust and rotation of the player. First the rotation of the sprite is no t difficult a task, by using the rotate() method outlined in the previous tutorial we can increment the theta rotation by constant var (in this case int rotate) just add or subtract the rotate value to rotate the sprite left and right as such:

rotate(getTheta() + rotate);       (right rotation)
rotate(getTheta() - rotate);        (left rotation)

Forward and reverse thrust is archived by using some basic trigonometry. We use cos(theta) to find the vx value and sin(theta) to find the vy values. The important thing to note here is that using trig functions is a CPU expensive exercise so to optimize trig calls we create a sin and cos lookup table. The tables are located in the com.ctek.GMath class, see the API for more information.

-------- TODO: Explain how sin and cos find the velocity coordinates. --------

Challenge: Can you find a way to have a max and min speed in the players thrust? Try to nut it out first, then look at the MyRoids Game Template source to find the answer. Currently you can increase the speed indefinitely, try it to see what happens.

BitmapMissile:

This class controls and animates a bitmap missile object. It is very similar to the BS_Loop class insofar as it animates a sprite but it further adds to this by internally controlling the duration that the missile exists for. It is meant to be inherited by your missile objects to give them some basic missile options, you should expand on this. In this example I have initiated the missile in the GMainPanel class it would be more elegant to place this sprite within the Player Sprite defined earlier and create a method to fire the sprite from there (More for you to experiment with). Because our basic BitmapSprite object supports rotation we can get the theta value of the PlayerSprite and rotate the missile accordingly. This is a good way to animate the asteroid type game because there is no need to create an image for every rotation degree for the missile and the player. When a missile is fired you have to options the first is to call BitmapMissile.init(float x, float y, int theta) or BitmapMissile.init(float x, float y) we will be using the former. The method we use allows for a theta value to be used, based on this angle the missile will follow on that trajectory until it dies. The other method is used for games that fire in one direction like space invaders. Once again sin and cos functions are used to determine the liner path of the missile sprite. A call to update() moves the sprite and increments the counter (How long the missile is alive) when the counter reaches the maxUpdate value the sprite is suspended. By using a wrapper class you could check the missile's location and introduce the wrapping algorithm outlined above (PlayerSprite) to have the missile wrap around the screen like the real asteroids game. An array of BitmapMissile objects could allow for multiple missile to be fired, try implementing things like that.

Asteroid Sprite:

Last but not least the asteroid sprite, in a real game this sprite would have its own class full of collision detection methods and interfaces and the works. For this simple example I have taken another shortcut and implemented asteroids as BS_Loop objects. I placed them into an array and just randomly found locations for them, when they are all destroyed I just re-initiated the array. You could play forever, pretty boring with no score and no other ships to fight. One thing to take notice of is that I have called the method mines[i].setCollisionArea(0.5f); what this does is decrease the current collision area by 50% and center it. I found this useful for creating the illusion that missile actually hits the asteroid (or mine) If your sprite has a large transparent area decrease the collision area so the sprites are closer together before registering a collision.

The main collision detection is done in the GMainPanel's update() method. What happens is the missile loops through the asteroids sprite array and tests for a number of conditions to hold true, they are:

  1. Have the two sprites collided.
  2. Is the missile active.
  3. Is the asteroid/mine active.

When all these test are true the asteroid is then suspended. and thus you have the illusion that you have destroyed the asteroid. For a more realistic game introduce an explosion sprite that is played after a collision is detected. Play around with this code and see what you can come up with yourself.


Download Source: missiles.zip

 


Copyright ©2000-2003 Michael Mifsud. All rights reserved.
godar@cairns.net.au