Foundation Game Design with ActionScript 3.0, Second Edition (99 page)

BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
7.93Mb size Format: txt, pdf, ePub
ads

Button Fairy can fly around the screen and shoot the bee. The Killer Bee flies toward her and fires bullets if she's within range. The scoreboards at the top of the stage keep track of the number of hits each has achieved.

All the objects in the game are made using the general
GameObject
class, so there are no custom classes to keep track of. That keeps the game structure and code really simple, and you can find out everything you need to know about how the game works just by looking at the application class. The application class doesn't contain any new code at all; it's just an everything-but-the-kitchen-sink example using most of the code we've already covered in this chapter. The one thing to keep an eye on, however, is the loops that move the star and bullet projectiles and check them for collisions. The loops have to make sure that they don't check for collisions with projectiles that they've already removed. We'll take a closer look at how this works ahead.

Here's the
KillerBeePandemonium
application class. You'll see that all the sections of code that move the different kinds of objects are in their own methods. Each of these methods is being called by the
enterFrameHandler
. This is just to help organize the code so that it's easier to find and work with these different sections.

package
{
  import flash.display.DisplayObject;
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.events.TimerEvent;
  import flash.text.*;
  import flash.ui.Mouse;
  import flash.utils.Timer;
  [SWF(width="800", height="600",
  backgroundColor="#FFFFFF", frameRate="60")]
  public class KillerBeePandemonium extends Sprite
  {
    //The images
    [Embed(source="../images/fairy.png")]
    private var FairyImage:Class;
    [Embed(source="../images/wand.png")]
    private var WandImage:Class;
    [Embed(source="../images/star.png")]
    private var StarImage:Class;
    [Embed(source="../images/background.png")]
    private var BackgroundImage:Class;
    [Embed(source="../images/bee.png")]
    private var BeeImage:Class;
    [Embed(source="../images/bullet.png")]
    private var BulletImage:Class;
    //Properties
    private const SPEED:Number = 3;
    private const TURN_SPEED:Number = 0.3;
    private const RANGE:Number = 500;
    private const FRICTION:Number = 0.96;
    private const EASING:Number = 0.1;
    private var _fairyImage:DisplayObject = new FairyImage();
    private var _wandImage:DisplayObject = new WandImage();
    private var _backgroundImage:DisplayObject
      = new BackgroundImage();
    private var _beeImage:DisplayObject = new BeeImage();
    private var _fairy:GameObject = new GameObject(_fairyImage);
    private var _wand:GameObject = new GameObject(_wandImage);
    private var _bee:GameObject = new GameObject(_beeImage);
    private var _background:GameObject
      = new GameObject(_backgroundImage, false);
    private var _angle:Number;
    private var _beeAngle:Number;
    private var _stars:Array = new Array();
    private var _bullets:Array = new Array();
    private var _bulletTimer:Timer;
    private var _format:TextFormat = new TextFormat();
    private var _fairyScoreDisplay:TextField = new TextField();
    private var _beeScoreDisplay:TextField = new TextField();
    private var _fairyScore:int;
    private var _beeScore:int;
    public function KillerBeePandemonium()
    {
      //Add game the objects
      stage.addChild(_background);
      setupTextFields();
      stage.addChild(_fairy);
      stage.addChild(_wand);
      stage.addChild(_bee);
      _bee.x = 275;
      _bee.y = 175;
      //Initialize the timer
      _bulletTimer = new Timer(500);
      _bulletTimer.addEventListener
        (TimerEvent.TIMER, bulletTimerHandler);
      //Hide the mouse
      Mouse.hide();
      //Add the event listeners
      stage.addEventListener
       (Event.ENTER_FRAME, enterFrameHandler);
      stage.addEventListener
       (MouseEvent.MOUSE_DOWN, mouseDownHandler);
    }
    private function setupTextFields():void
    {
      //Set the text format object
      _format.font = "Helvetica";
      _format.size = 44;
      _format.color = 0x000000;
      _format.align = TextFormatAlign.CENTER;
      //Configure the fairy's score  text field
      _fairyScoreDisplay.defaultTextFormat = _format;
      _fairyScoreDisplay.autoSize = TextFieldAutoSize.CENTER;
      _fairyScoreDisplay.border = false;
      _fairyScoreDisplay.text = "0";
      //Display and position the fairy's score text field
      stage.addChild(_fairyScoreDisplay);
      _fairyScoreDisplay.x = 180;
      _fairyScoreDisplay.y = 21;
      //Configure the bee's score  text field
      _beeScoreDisplay.defaultTextFormat = _format;
      _beeScoreDisplay.autoSize = TextFieldAutoSize.CENTER;
      _beeScoreDisplay.border = false;
      _beeScoreDisplay.text = "0";
      //Display and position the bee's score text field
      stage.addChild(_beeScoreDisplay);
      _beeScoreDisplay.x = 550;
      _beeScoreDisplay.y = 21;
    }
    private function enterFrameHandler(event:Event):void
    {
      moveFairy();
      moveBee();
      moveStars();
      moveBullets();
    }
    private function moveBullets():void
    {
      //Move the bullets
      for(var i:int = 0; i < _bullets.length; i++)
      {
        var bullet:GameObject = _bullets[i];
        bullet.x += bullet.vx;
        bullet.y += bullet.vy;
        //check the bullet's stage boundaries
        if (bullet.y < 0
        || bullet.x < 0
        || bullet.x > stage.stageWidth
        || bullet.y > stage.stageHeight)
        {
          //Remove the bullet from the stage
          stage.removeChild(bullet);
          bullet = null;
          _bullets.splice(i,1);
          i--;
        }
        //Check for a collision with the fairy
        if(bullet != null
        && bullet.hitTestObject(_fairy))
        {
          //Update the score, the score display
          //and remove the bullet
          _beeScore++;
          _beeScoreDisplay.text = String(_beeScore);
          stage.removeChild(bullet);
          bullet = null;
          _bullets.splice(i,1);
          i--;
        }
      }
    }
    private function moveStars():void
    {
      //Move the stars
      for(var i:int = 0; i < _stars.length; i++)
      {
        var star:GameObject = _stars[i];
        star.x += star.vx;
        star.y += star.vy;
        //check the star's stage boundaries
        if (star.y < 0
        || star.x < 0
        || star.x > stage.stageWidth
        || star.y > stage.stageHeight)
        {
          //Remove the star from the stage
          stage.removeChild(star);
          star = null;
          _stars.splice(i,1);
          i--;
        }
        //Check for a collision with the bee
        if(star != null
        && star.hitTestObject(_bee))
        {
          //Update the score, the score display
          //and remove the bullet
          _fairyScore++;
          _fairyScoreDisplay.text = String(_fairyScore);
          stage.removeChild(star);
          star = null;
          _stars.splice(i,1);
          i--;
        }
      }
    }
    private function moveBee():void
    {
      //Get the target object
      var target_X:Number = _fairy.x;
      var target_Y:Number = _fairy.y;
      //Calculate the distance between the target and the bee
      var vx:Number = target_X - _bee.x;
      var vy:Number = target_Y - _bee.y;
      var distance:Number = Math.sqrt(vx * vx + vy * vy);
      if (distance <= RANGE)
      {
        //Find out how much to move
        var move_X:Number = TURN_SPEED * vx / distance;
        var move_Y:Number = TURN_SPEED * vy / distance;
        //Increase the bee's velocity
        _bee.vx += move_X;
        _bee.vy += move_Y;
        //Find the total distance to move
        var moveDistance:Number
          = Math.sqrt(_bee.vx * _bee.vx + _bee.vy * _bee.vy);
        //Apply easing
        _bee.vx = SPEED * _bee.vx / moveDistance;
        _bee.vy = SPEED * _bee.vy / moveDistance;
        //Rotate towards the bee towards the target
        //Find the angle in radians
        _beeAngle = Math.atan2(_bee.vy, _bee.vx);
        //Convert the radians to degrees to rotate
        //the bee correctly
        _bee.rotation = _beeAngle * 180 / Math.PI + 90;
        //Start the bullet timer
        _bulletTimer.start();
      }
      else
      {
        _bulletTimer.stop();
      }
      //Apply friction
      _bee.vx *= FRICTION;
      _bee.vy *= FRICTION;
      //Move the bee
      _bee.x += _bee.vx;
      _bee.y += _bee.vy;
    }
    private function moveFairy():void
    {
      //Find the angle between the center of the
      //fairy and the mouse
      _angle
      = Math.atan2
       (
          _fairy.y - stage.mouseY,
          _fairy.x - stage.mouseX
        );
      //Move the wand around the fairy
      var radius:int = -50;
      _wand.x = _fairy.x + (radius * Math.cos(_angle));
      _wand.y = _fairy.y + (radius * Math.sin(_angle));
      //Figure out the distance between the
      //mouse and the center of the fairy
      var vx:Number = stage.mouseX - _fairy.x;
      var vy:Number = stage.mouseY - _fairy.y;  
      var distance:Number = Math.sqrt(vx * vx + vy * vy);
      //Move the fairy if it's more than 1 pixel away from the mouse
      if (distance >= 1)
      {
        _fairy.x += vx * EASING;
        _fairy.y += vy * EASING;
      }
    }
    //Let the bee fire bullets using a timer
    private function bulletTimerHandler(event:TimerEvent):void
    {
      //Create a bullet and add it to the stage
      var bulletImage:DisplayObject = new BulletImage();
      var bullet:GameObject = new GameObject(bulletImage);
      stage.addChild(bullet);
      //Set the bullet's starting position
      var radius:int = 30;
      bullet.x = _bee.x + (radius * Math.cos(_beeAngle));
      bullet.y = _bee.y + (radius * Math.sin(_beeAngle));
      //Set the bullet's velocity based on the angle
      bullet.vx = Math.cos(_beeAngle) * 5 + _bee.vx;
      bullet.vy = Math.sin(_beeAngle) * 5 + _bee.vy;
      //Push the bullet into the _bullets array
      _bullets.push(bullet);
      //Find a random start time for the next bullet
      var randomFireTime:Number
        = Math.round(Math.random() * 1000) + 200;
      _bulletTimer.delay = randomFireTime;
    }
    //Let Button Fairy fire stars when the mouse is clicked
    private function mouseDownHandler(event:MouseEvent):void
    {
      //Create a star and add it to the stage
      var starImage:DisplayObject = new StarImage();
      var star:GameObject = new GameObject(starImage);
      stage.addChild(star);
      //Set the star's starting position
      //to the wand's position
      star.x = _wand.x;
      star.y = _wand.y;
      //Set the star's velocity based
      //on the angle between the center of
      //the fairy and the mouse
      star.vx = Math.cos(_angle) * -7;
      star.vy = Math.sin(_angle) * -7;
      //Push the star into the _stars array
      _stars.push(star);
    }
  }
}

As I mentioned, the important thing to keep aware of in this code is that the loops that check for collisions between the projectiles and the game objects have to make sure that the projectile hasn't already been removed from the game earlier, if it had crossed a stage boundary. That's why the
if
statement that checks for a collision also has to make sure that the object isn't
null
.

if(bullet != null
&& bullet.hitTestObject(_fairy))
{…

This is just a small technical detail to take care of, but will ensure that your game doesn't generate any runtime errors while it's playing.

Flash animation and publishing your game

Most of this book has been about writing the computer code you need to know to make video games. That's been the hardest part, but there's much more that you can and should do with your games besides just program them. How can you easily create animated objects for your games, and how can you publish your game after you've created it? You'll find out how to do both these things in the bonus chapter “Flash
Animation and Publishing Your Game” that you'll find in the book's download package. You'll learn how to use Flash Professional software to quickly make game animations that you can control using AS3.0 code. In addition, if you want to make games for mobile phones and tablets, you'll find out how to use Flash Builder to publish your games to those platforms.

Summary

Hey, is the book finished already? It is, but it seemed like all the fun was only just starting! If you've reached this last section in the book, congratulate yourself: You're a game designer! With the skills you've acquired throughout this book, there are few game design scenarios that you won't be able to approach with confidence.

However, if you're like everyone else who's ever started learning game design, you'll find that the desire to learn more is insatiable. Although you've accomplished so much already, there's a great universe of learning ahead of you. Here's a quick roundup of some of the areas you might want to explore:

  • Adobe's online help documentation:
    Adobe maintains excellent online documents detailing most aspects of AS3.0 programming. You can access these documents by pointing your web browser to Adobe's ActionScript Technology Center:
    www.adobe.com/devnet/actionscript.html
    . There you'll find links to the ActionScript 3 Developer's Guide and ActionScript 3 Reference for the Flash Platform. I've made numerous references to sections of these documents throughout this book, and they remain the most comprehensive primary source for all things Flash and AS3.0. Although many of the topics they deal with and the approaches they take are reasonably advanced, they should match your current level of ability. Spend some time going through some of the hundreds of articles and you're sure to find great food to fuel your developing programming skills.
  • 3D:
    With the release of Flash Player 11 and Stage 3D, Flash has become a superb platform for building interactive 3D worlds and games. You can find out how to program 3D games with AS3.0 at Adobe's Stage 3D web site here:
    www.adobe.com/devnet/flashplayer/stage3d.html
    . There are some 3D game engines you can use to help you create 3D games with AS3.0 and Flash: Alternativa, Flare3D, Away 3D, and Adobe's own Proscenium. You can also use Stage 3D to make 2D games with full access to the computer or mobile devices Graphics Processing Unit (GPU) for great performance. The easy-to-use Starling framework can help you do this, as well as ND2D.
  • Physics:
    There are some excellent packages of classes available for doing precise physics simulations with AS3.0. They include Box2D, Motor2, APE, Foam, Flave, World Construction Kit, JigLib, and Glaze.
  • Tile-based games:
    In this style of game design, all objects on the stage are assigned to squares in a grid. The code then creates an abstract model of the game behind the scenes in arrays, and that model is used to update the objects on the stage. Board games, strategy games, and certain puzzle games really benefit from the tile-based approach. Tile-based games run very efficiently, use relatively little CPU power and memory, and are easy to extend if you want to add new game
    levels. Because of this, the tile-based approach also works well for platform and adventure games.
  • Vector math and geometry:
    If you want to create games that involve some degree of physics simulation, it is really beneficial to spend a bit of time learning some vector math and 2D geometry. Even if you don't think you're good at math, give it a try—you might just surprise yourself. You can immediately apply what you learn to your games.
  • Saving game data:
    If you want to save some data in your game (such as a score or a game level) so the player can quit the game and continue it later, you need to create a
    shared object
    . This is covered in detail in the section “Storing local data” in the chapter “Networking and Communication” from Adobe's online document
    Programming ActionScript 3.0 for Flash
    .
  • Multiplayer games:
    It's always more fun to play games with friends. To make multiplayer games, you need to store game data on a server on the Web so that other players can access that data to update their own game screens. There are quite a few ways you can do this, but all require some research into additional “server- side technologies.” Your Flash games will be able to communicate with these server-side technologies, but to implement most of them you'll need to learn new programming languages such as PHP or Java. Do a bit of research into Java socket servers such as SmartFoxServer, ElectroServer, and Pulse, among many others. (Java is very closely related to AS3.0, so you won't find it completely unfamiliar.) You can create a high-score list for your games using PHP, and you can store game data using a MySQL database. You can avoid Java and PHP directly by storing game data in a content management system (CMS) and accessing the data in Flash using XML. Adobe also provides its own Flash Media Servers. The Media Development Server is free, and although limited, is a great way to get your feet wet with multiplayer technologies in a familiar environment. As you can see, there's a lot to learn! But it's all well worth the time you'll put into it.
BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
7.93Mb size Format: txt, pdf, ePub
ads

Other books

Counterfeit Son by Elaine Marie Alphin
The Last Gift by Abdulrazak Gurnah
Alistair’s Bed by Susan Hayes
Dreams Take Flight by Dalton, Jim
Bartholomew Fair by Ann Swinfen
Teen Angel by Pilcer, Sonia
Apocalypsis 1.04 Baphomet by Giordano, Mario
Defiance by Beth D. Carter