Creating an “Asteroids” arcade game in Flash

Those of you who read Flash and Flex Developer’s Magazine might have already read my Asteroids tutorial in the January edition.  If not, you can grab yourself a copy over at FFDmag.com

The tutorial shows you how to create a simple arcade game from scratch, based on the classic arcade hit Asteroids.  Rather than completely rehash the entire article here, what I wanted to do was back the article up with a little more info, show some of the setup in a more visual manner (with a short video) and then show how the game in the tutorial could be extended with extra features like audio, powerups and other game extensions.

In today’s post I’ll show you how to set up the Flash file, and go over how I designed and built the basic game.  Then I’ll follow up in a few days with a second post showing how to add extra functionality to the game, and get it to a level where it could be published online.  First of all, let’s take a look at the game… (note this is scaled down from full size of 800×600 px)

I’ve named it “Space Debris” but essentially it’s the same gameplay as the old Atari classic.  You move a small spaceship around the screen by rotating (cursors LEFT/RIGHT) thrusting (cursor UP) and firing bullets (X) in an attempt to destroy the asteroids.  Shoot a large asteroid and it becomes 2 smaller asteroids, they in turn become 2 yet smaller asteroids, and finally the smallest ones are removed when hit.  Clear the screen and you’ll have to face a larger, harder wave.

The player begins with 3 lives, they lose one if they crash into an asteroid, and the game is over when all lives are lost.  Pretty basic stuff right?

OK so the game will be written in a single class named Asteroids.as and we’ll also use a Flash file which will handle the intro/outro screens and hold our graphical assets etc.  In this video I’ll quickly show you how to set it up and then I’ll move on to actually coding the game, or simply click here to download all the source files.

Setting up the Asteroids game file

Writing the Asteroids game class

The following is taken from my article in Flash and Flex Developer’s Magazine January 2010 edition, reformatted slight for this blog but it is LONG!  I would highly recommend grabbing the FFDMag January edition and reading from that instead, which also includes full setup details for the Flash file!  Then just skip to the end of this post to grab the FLA and AS3 source files…

First create a new actionscript file and save it as Asteroids.as

Listing 1 (please download the AS files at the bottom of this page) shows the Asteroids class which extends MovieClip. It uses 4 imports, and has quite a number of class variables. Most of these are self explanatory such as lives or score. Some however need a little explanation.

We use 2 eponymous arrays to keep track of all the asteroids and bullets currently on screen, and we use a movieclip called gameField which will contain all the game objects (spaceship, asteroids, bullets).

The variable oldTime is used with our timer to calculate the new positions of each object on every frame, depending on their current speed and how long since the last frame.

The three booleans simply keep track of whether the ship is currently turning or thrusting, and then we have variables for all of the ship parameters, from how fast it rotates, to the maximum number of bullets it can fire.

Finally we declare 4 points, and another boolean. The points are the co-ordinates of the outer extremities of our ship and will be used when we write our collision detection function to see if the ship has crashed. The boolean simply tracks whether the game is currently playing (and the ship hasn’t already crashed!)

Beginning our game

You’ll notice that there is no constructor method. That is because we don’t want the game to start automatically, so instead we write a method called startGame() which we call frame 2 of our FLA file.

The startGame() method sets up our game by resetting variables such as level and score, creating new arrays to keep track of the asteroids and bullets, and creating our gameField movieclip which we move behind our control panel with the addChildIndex method.

We add 3 event listeners – one for ENTER_FRAME, which is our main game loop, and 2 for user input (KEY_DOWN and KEY_UP). We also call a method called addShip() which, as the name suggests, creates our ship object. We could also call nextLevel() from here to generate the first asteroid field, but instead we play the message movie clip, and add a listener which will call messageHandler() on each frame. The messageHandler() method in turn will call nextLevel() once the message “Get Ready…” has been shown on screen.

Main game loop

Asteroids in an action based game. Unlike a puzzle game or turn based game like Tic Tac Toe, or Sudoku, an action game has things happening all the time, on every frame, whether there is input from the user or not. To handle this we create a method called gameLoop() which is called every frame from the listener we declared above.

This gameLoop() method calculates the position of every object on screen, based on its velocity, and the time passed since the previous frame (see Time based animation post for more details). It does this by first getting the time in milliseconds since the game started and subtracting from that the time of the previous frame. This gives us the exact number of milliseconds since the last time the screen updated which is then passed to a number of methods to calculate the new positions of the ship, bullets and asteroids.

We also check for collisions (to see if an asteroid has been shot, or has crashed into the ship) and finally we update the text field for the score.

Game objects

We have 3 different types of game objects – our spaceship, the bullets it fires, and the asteroids. Each type of object has a method to create it, a method to move it (i.e. update its position on screen) and a method to remove it. Let’s look at each object type in turn.

Spaceship

Firstly the spaceship. This is what the user controls via keyboard inputs. It starts in the middle of the screen and there it remains until we give it some input. The addShip() method is very simple – it creates a new SpaceShip object, sets its position to the center of the screen, adds it as a child of the gameField object and sets the inGame variable to true.

The moveSpaceship() method is quite simple too, but involves just a little maths First it deals with the user input. If turnLeft or turnRight are true (set when the left/right cursor keys are pressed) then the rotation of the ship is either increased or decreased by the rotation speed.

If the thrust variable is set however there is a little more going on. We need to convert the thrust force into cartesian values for x and y. This is done with basic trigonometry If you think back to your trigonometry lessons from school you’ll remember that the x or y value can be found by using sine or cosine of the angle (rotation of the ship) multiplied by the hypotenuse (thrustAmt). We’re working in radians (rather than degrees) so we find the increase or decrease in x and y velocities like this:

1
2
shipDX += Math.sin(Math.PI*spaceship.rotation/180)*thrustAmt;
shipDY -= Math.cos(Math.PI*spaceship.rotation/180)*thrustAmt

Now that we know the velocities we can update the position of the ship by simply adding the new velocity values to the x and y co-ordinates of the ship. We also show frame 2 (the thrust frame) of the ship movie clip if thrusting, or frame 1 if not.

The last part of the moveSpaceship() method handles the edge of the screen. In Asteroids, the spaceship and asteroids “wrap” from one side of the screen to the other, and from top to bottom. To handle this we simply check to see if the ship’s position is outside of those boundaries, and if it is we wrap it to the opposite edge (with a little overlap of 20 pixels, roughly the width of the ship, which makes the transition look smooth!)

Removing the spaceship is actually handled by 2 methods – firstly we call explodeSpaceship() which sets inGame to false, moves the spaceship to the top of the gameField display list (to make sure it’s in front of the other graphics), and then plays the explode animation. We also take a life off at this point and update the lives field on the control panel.

An event listener is added which calls removeSpaceship() once the explode animation is completed. This removes the spaceship movie clip, then either calls addShip(), or if there are no lives remaining ends the game by playing the gameover frame in the messages clip.

Asteroids

At this point we have a spaceship flying around the screen, but that’s not much of a game on its own so lets add some asteroids! Again, we have methods to add, move, and remove, but we also have a method called nextLevel() which generates the entire asteroid field for the level.

Let’s begin with the addAsteroid() method. It accepts 3 parameters – asteroidType which is a string (big, medium or small) along with x and y co-ordinates. We declare a new MovieClip variable called newAsteroid, and depending on the asteroidType parameter we create a new big, medium or small asteroid object. We also give the new asteroid a random vertical and horizontal speed within certain limits (the smaller asteroids can move faster than the big ones!)

We then position the asteroid according to the x and y parameters, rotate it to a random angle and finally add it to both the asteroids array and the gameField movie clip.

Responsible for generating the asteroid field, and passing the parameters to addAsteroid is the nextLevel() method. It begins by incrementing the level variable (which we initially set to 0 in the startGame() method. We generate a number of asteroids, equal to the level number plus one so we open a for loop, and then create asteroids in random positions on the screen.

We don’t want asteroids to appear in the center (that’s where our ship is) or too close to the edges (otherwise they may instantly wrap which will cause a flicker) so we split the game field up into 4 quadrants. We randomly choose a quadrant, and then randomly generate a position within that quadrant to place the asteroid. That position, along with the size is passed to the addAsteroid() method to generate the asteroid field for the level.

Moving the asteroids is simpler than the ship since there is no user input to worry about, except that this time we loop through each asteroid in the asteroids array one by one. We again use the timeFrame parameter generated in gameLoop() but this time we simply move the asteroid based on its horizontal and vertical speed. We rotate it based on the difference between those 2 speeds (saves having to generate another random number, but keeps them all rotating differently) and we wrap at the edges just as we did with the spaceship.

While moving the asteroids is simpler than the spaceship, removing them is very slightly more complex. If it’s a small asteroid we can simply remove it, and increase the score. If it’s medium or large however we need to split it into 2 smaller asteroids. We do that by first checking the the type, and then calling addAsteroid() twice for the next size down. We also increase the score here, based on the size of asteroid hit, and finally we remove the asteroid both from the array and the game field.

At this point we also check the asteroids array to see if there are any remaining asteroids. If there are none then the level is over, and we play the messages clip from the “next level” frame, and add a listener which calls messageHandler() (and in turn the nextLevel() method) when the message finishes.

Bullets

Bullets are actually very simple since they don’t rotate, and they don’t wrap (we’ll remove them when they reach the edge of the screen). First we create a new bullet with the fireBullet() method which takes no parameters. It is called when the player hits the X key to shoot, and creates a new Bullet object. We calculate the new bullet’s velocity based on the current rotation of the ship in the same way we calculate the ship’s velocity. We then position the bullet just in front of the ship, add it to the gameField and the bullets array.

Moving the bullets is just like moving the asteroids in that we loop through the bullets array one by one. For each bullet we move it based on its velocity (multiplied by bulletSpeed) and we then check it against the edges of the gameField. Once the bullet goes beyond the edge of the screen we call removeBullet.

removeBullet() method accepts a single parameter, which is the index of the bullet in the bullets array. This method simply removes the bullet from the game field, and from the array.

Pulling it all together

OK so we now have a spaceship flying around the screen under the player’s control, we have asteroids floating through space, and we are able to shoot but there is one big element yet to code – the collision detection!

At the moment our spaceship is invincible, and our bullets pass right through the asteroids without making a dent. What we need is a final method added to our game loop which checks for collisions between the asteroids, and our ship and bullets.

So the checkColisions() method actually handles 2 different types of collision – asteroid/ship and asteroid/bullet. Let’s take a look at the ship collisions first.

First we check the inGame variable to ensure that the ship is still in play. If it is then we loop through the asteroids array and check each asteroid’s hit clip against each of the collision points on the ship using hitTestPoint with the shapeFlag parameter set to true (see collision detection box). The localToGlobal method is used to convert the collision points (which are relative to the ship) to global co-ordinates. If there is a match (i.e. if one of the collision points is within the boundary of an asteroid’s hit clip then there has been a crash and explodeSpaceship() is called.

For the bullet collisions we loop through the asteroids array, and for each asteroid we loop through the bullets array. Using hitTestPoint again, this time we simply check the bullet’s x and y co-ordinates against the asteroid’s hit clip. If there is a collision we call both removeAsteroid() and removeBullet(). We then break out of the inner for loop, using continue loopAsteroids; to prevent checking another bullet against the asteroid which has just been removed.

Finishing and running the game

The final methods, showScores(), restartGame(), keyIsDown() and keyIsUp() are self explanatory, and if you’ve followed the tutorial this far you should now have a simple but working game.

While this works as a great example for learning some of the fundamental principles of game development, and a few years ago it probably would have been enough to compete with many other Flash games on the web, these days players want something a little more refined.

{ End of magazine tutorial… }

Whew – I told you that was long!  OK, so rather than list all the actionscript here too I’ve put all the source files together in a zip which you can download here.

I really hope you enjoy tinkering with the game, and you learn a ton from it.  Please do give me some feedback, just leave a comment with any questions or suggestions and I will read them and resond.  Next week I’ll post a follow-up article which will extend the game, and audio and some other functionality, and basically turn it into a usable web game, so if you want to see specific features added do let me know!

In the meantime, have fun playing with it ;)

Download Flash Social Media Buttons
Download the Flash social media buttons components

Share |

5 Responses

  1. Upgrading Asteroids - audio and improvements | Flash Games Classroom Says:

    [...] Asteroids – audio and improvements This is a follow-up to the main tutorial from last week, How to write the arcade classic Asteroids in Flash, which originally appeared in the January edition of Flash and Flex Developer’s Magazine [...]

  2. Tom Brito Says:

    Where is Listing 1?

  3. admin Says:

    Hi Tom. Thanks for your comment. As stated in the post, the body of this tutorial is taken from the article I wrote for FFD Magazine. Since the listings are long I made them downloadable (just above the comments) rather than list them in the body of the article! Just click the download link above ;)

  4. Bryce Woodward Says:

    I have been doing your tutorial on the asteroids game and it is amazing. But i want to add a pause button to it. Because once i start playing i cant stop. Can you help me please.

  5. admin Says:

    Hi Bryce

    That’s quite simple. First just create a new class variable:

    private var gamePaused:Boolean;

    Set it to false in the startGame method, and then set up a way of turning it on/off. You could do that with a button, but probably better to do it when the player hits the P key so add these an extra if statement to the keyIsDown method:

    if(evt.keyCode==80) { if(gamePaused) { gamePaused = false; } else { gamePaused = true; }
    }

    Then just put if(!gamePaused) around the code in the moveSpaceship and gameLoop methods to prevent anything updating while the game is paused.

    Probably also a good idea to add a visual cue, like a “PAUSED” message on screen!

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.