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

BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
5.09Mb size Format: txt, pdf, ePub
ads
Managing complex code

This is a long program but notice that the bulk of the code has nothing to do with the mechanics of the game. About 70% of it has to do with setting up, displaying, and managing the text fields and buttons. In a big game project you'll find that most of your code will be about displaying graphics and managing the user interface, just like in this game.

Part of the reason why it's important to modularize your code using bite-sized methods is so that you can separate the programming of the visual elements from the programming of the game logic. Doing so makes the game much easier to write because when you finish programming one method, you don't need to look at it again. You can concentrate on the code in another method.

Still, in a complex game with hundreds of different graphic elements, this approach will only take you so far. You're going to need to learn how to modularize your code even further so that you can completely bury code that you no longer need to work on. In
Chapter 7
you'll be looking at how to make games using multiple classes, which will partially solve the problem. The ultimate solution is to use a more advanced approach using a programming
design pattern
called the Model View Controller (MVC). It's beyond the
scope of this book to cover the MVC, but you can find out all about it in the sequel to this book,
Advanced Game Design with Flash
.

While you're still learning, however, modularizing your code using methods will take you quite far, and you'll learn a lot in the process. Here are some ideas for making your games and programs easier to manage:

  • Create very specific methods that perform one or two tasks—and no more.
  • Keep all the setting up and displaying of your visual elements (like buttons, text, game characters, game objects, and backgrounds) in their own methods. This is important so that they don't clutter up the delicate logic programming that makes your game work.
  • Keep all your event handlers at the end of the program. You rarely need to look at event handlers after you've written and tested then. If they're all sitting at the end of your program then they're neatly out of the way.

You'll see all these techniques at work in the code in the chapters ahead.

Project extensions

This is the first complete game in this book. But is it really done?

Game design is a funny thing. Games, even complex ones, are never really finished. Designers just stop working on them when they seem to play well enough that no one complains. There are usually many deep layers of complexity or added functionality that
could
be added to games if the designer had enough time, patience, and imagination to do so. Patience and imagination are things game designers seem to have in endless supply. It's usually
time
that throws the spanner in the works.

There's quite a bit more that you could add to this game. Here are some ideas.

Make a Play again button

Display a button at the end of the game that allows the player to play again. I'm not going to explain how to do this because you already know how! You know how to make buttons, set object properties, and create and call methods. By creating a Play again button on your own, you're going to practice all the skills you've learned over the last four chapters: everything from designing the graphics to writing the code. You'll also run into some problems you never imagined existed, eventually solve them, and feel like you're walking on clouds when everything is finally working properly.

When you're done, your number guessing game might look something like
Figure 4-36
.

Figure 4-36.
Create a Play again button to restart the game.

Here are a few hints to help you on the way:

  • The Play again button will need to be disabled and invisible when you first create and add it to the game.
  • The
    endGame
    method should enable the Play again button.
  • You need to disable the Play again button after it's been clicked. You can do this directly in its CLICK event handler.
  • The Play again button will need to restart the game when you click it. You can do this by calling the
    startGame
    method in the play again button's CLICK event handler
  • You'll need to re-enable the Enter key and guess button when the game restarts. Where will you add the code to do this?

If you get terminally stuck, you'll find the finished game with a Play again button in the PlayAgain folder in this chapter's source files.

Good luck!

Tracking guesses

You set the game up to allow ten guesses, but some players might not have the patience to remember what their previous guesses were. You can add another text field that displays all their previous guesses for them and adds the new guess when they make it.

To do this, you'll need a new text field, perhaps called
guessHistory
. You can create a new string variable called
previousGuesses
that stores all the guesses as a string of text with each number separated by a blank space. Whenever the player makes a new guess, you can add it to the
previousGuesses
variable and then update the
guessHistory
text field. Here's a sample of what the core of this code will look like:

previousGuesses += currentGuess + "  ";
guessHistory.text = previousGuesses;

This line of code will work well in the
playGame
method. Can you see how the code in the first directive would separate each number with a blank space?

Adding a visual display

A hangman-style visual display of how well (or poorly!) the player is doing is an interesting enhancement. You could create ten images showing ten different hangman states. Use the visible property to selectively display or hide each state depending on how the game is going. Each state can incrementally show the player how close they are to impeding peril, like the addition of limbs to the chalk figure in game of Hangman.

Turning the tables

A more advanced project that's fun to try is to change the game so that the program needs to guess a number that
you're
thinking of. This will be a completely new program, but you currently have all the skills you need to make it work.

Want to give it a try? Here's a hint: to get this game working, you'll need to use a
division operator
. You've already seen the multiplication operator.

*

You used the multiplication operator to multiply the random number by 100. The division operator looks like this:

/

It's a simple forward slash. You can use it in any directive to divide two numbers.

100 / 2

This example gives a result of 50. You can then assign this calculation to variable in a directive. Here's an example:

computersGuess = (100 / 2);

Can you see where I'm going with this? I'm not going to spoil your fun of figuring out the rest! This will be a difficult project for you, but you can do it. And what you'll learn along the way will give you an invaluable insight into your own developing skills and style as a game programmer.

A quick guide to embedding fonts

If you want the fonts in your games to display correctly on computers other than yours, you'll need to
embed
them. An embedded font is stored inside the SWF file and doesn't require the person who's playing the game to have that same font installed on his or her computer. Here are the steps you need to follow to embed a font:

  1. Create a folder called fonts in your Project directory. Copy a font file into it. (Font files usually have the file extensions .ttf, .otf, or .ttc.)
  2. Fonts are embedded using a metatag. Add the following code at the top of your class definition:
    public class EmbeddedFonts extends Sprite
    {
      [Embed
        (
          source="../fonts/Optima.ttc",
          embedAsCFF="false",
          fontName="embeddedFont",
          fontWeight="normal",
          advancedAntiAliasing="true",
          mimeType="application/x-font"
        )
      ]
      private var EmbeddedFontClass:Class;

The most important thing about this code is that the source parameter needs to provide the exact path to the font file in your project directory.

  1. Set the
    format
    object's font property to “embeddedFont”. This should match the name you provided in the
    fontName
    parameter in your code.
    format.size = 32;
    format.color = 0x000000;
    format.font = "embeddedFont"
  2. Set the text field's
    embedFonts
    property to true.
output.embedFonts = true;

Your published SWF will now display the font correctly on any computer.

In the chapter's source files you'll find a folder called EmbeddedFonts with a working example of this system. It displays a line of text using an embedded font. Here's the entire
EmbeddedFont
class:

package
{
  import flash.display.Sprite;
  import flash.text.*;
  public class EmbeddedFonts extends Sprite
  {
    [Embed
      (
        source = "../fonts/Optima.ttc",
        embedAsCFF = "false",
        fontName = "embeddedFont",
        fontWeight = "normal",
        advancedAntiAliasing = "true",
        mimeType = "application/x-font"
      )
    ]
    private var EmbeddedFontClass:Class;
    //Create the format and text field objects
    public var format:TextFormat = new TextFormat();
    public var output:TextField = new TextField();
    public function EmbeddedFonts()
    {
      //1. Configure the format
     format.size = 32;
     format.color = 0x000000;
      //The name of the font should match
      //the "name" parameter in the Embed tag
      format.font = "embeddedFont";
      //2. Configure the text field
      output.defaultTextFormat = format;
      output.embedFonts = true;
      output.autoSize = TextFieldAutoSize.LEFT;
      output.antiAliasType = flash.text.AntiAliasType.ADVANCED;
      output.border = false;
      output.defaultTextFormat = format;
      output.text = "The text you want to display.";
      stage.addChild(output);
      output.x = 50;
      output.y = 175;
    }
  }
}

Embedded fonts can sometimes behave in quirky ways, and this often depends on the specific font file you're trying to embed. If you have any problems, first try removing this line from the Embed metatag:

embedAsCFF = "false",

This often does the trick.

Summary

The number guessing game that you looked at in this chapter is extremely important for a few reasons:

  • It's the first complete and “real” game in the book. It's small in size, but it contains everything that a fully working game should have. Even though you can and will build more complex larger-scale games, this number guessing game is a model for the kinds of problems your games need to solve. If you understand the problems of game design and the solutions you found for them here, you'll be in a very strong position when you attempt something a bit more ambitious.
  • You now understand input and output, variables, methods, if/else statements, button and keyboard events, and how to modularize a program using methods. These topics represent the core concepts of computer programming. You have a lot of programming power now at your disposal to build a wide variety of logic-based games.
  • To keep things as simple as possible, the focus of this chapter has been on the internal logic and structure of games. There's no reason, however, why you shouldn't combine these techniques with the techniques you looked at in the previous chapter for controlling visual objects on the stage. In fact, you should definitely combine these techniques! With a bit of creativity, you'll be able to build complex puzzle and logic-based mystery adventure games that can be completely visual.

Before you continue in this book, take a short break to create a game of your own based on the techniques covered so far. There's no better way to learn than by trying things out in your own way, and it will give you a greater appreciation for some of the more advanced techniques you'll be looking at in the chapters ahead.

In
Chapter 5
, you'll take a detailed look at how to control objects on the stage with the keyboard. It will be the stepping stone you need to progress from designing
games
to designing
video games
.

Chapter 5
Controlling A Player Character

One of the first things your games should do is allow game players to move an object around the stage. A game object could be moved with either the mouse or the keyboard. In this chapter, you'll look at techniques for controlling an object with the keyboard.

This chapter covers the following topics:

  • Using the KEY_DOWN, KEYUP, and ENTER_FRAME events.
  • Stopping the player character at the edges of the stage and screen wrapping.
  • Scrolling: vertical, horizontal, and parallax scrolling
  • How to embed images into a game.
Controlling a player character with the keyboard

One of the most basic things a game should do is allow players to control a game character with a keyboard. It's not hard to do. It's a technique that makes use of two of AS3.0's built-in classes: the
KeyboardEvent
class and the
Keyboard
class. To use them, you simply import them into the top of your program, along with your other imported classes.

import flash.events.KeyboardEvent;
import flash.ui.Keyboard;

You used both of these classes in
Chapter 4
to allow players to enter text into the input text field by pressing the Enter key on the keyboard. The
KeyboardEvent
and
Keyboard
classes contain methods and properties that you can use to help your players interact with your games using the keyboard. And, like the
MouseEvent
class properties, you'll be using all these new methods and properties with your eyes closed in no time at all.

Controlling with the keyboard'the wrong way!

There are two ways to control an object with the keyboard: the right way and the wrong way. Let's look at the wrong way of doing it first.

Why would you learn the wrong way? Well, the nice thing about doing player keyboard control incorrectly is that it's very straightforward and easy to understand. And, oh yeah, it kind of works, too. But even if you never use it to control a player character in one of your games, you'll find endless other uses for it as a general technique for figuring out which keys your players are pressing on the keyboard. It's also the basis for understanding the right way to do keyboard control, which adds a few extra layers of flexibility and polish to the same underlying system. If you understand how the wrong way works first, you'll be better able to understand and appreciate the right way to do things. But don't worry, I'll take things a step at a time. You'll be surprised at how simple the process is when you put all the pieces together.

Let's write a simple program that demonstrates this.

  1. Create a new ActionScript project called SimpleKeyboardControl.
  2. In the project folder, create a subfolder called images.
  3. Copy the character.png file that you created in
    Chapter 2
    into the images folder. When you're done, your project folder should look like
    Figure 5-1
    .

    Figure 5-1.
    Copy the character.png file into the images folder.

  4. Write the following program in the code editor window. (If you don't feel like typing it all out, you'll find the finished program in the SimpleKeyboardControl folder in the chapter's source files.)
    package
    {
      import flash.net.URLRequest;
      import flash.display.Loader;
      import flash.display.Sprite;
      import flash.events.KeyboardEvent;
      import flash.ui.Keyboard;
      [SWF(width="550", height="400",
        backgroundColor="#FFFFFF", frameRate="60")]
      public class SimpleKeyboardControl extends Sprite
      {
        
    //Create the game character objects
        public var characterURL:URLRequest
          = new URLRequest("../images/character.png");
        public var characterImage:Loader = new Loader();
        public var character:Sprite = new Sprite();
        public function SimpleKeyboardControl()
        {
          
    //Load the image and add the character to the stage
          characterImage.load(characterURL);
          character.addChild(characterImage);
          stage.addChild(character);
          character.x = 225;
          character.y = 150;
          
    //Add a KeyboardEvent listener
          stage.addEventListener
            (KeyboardEvent.KEY_DOWN,  keyDownHandler);
        }
        public function keyDownHandler(event:KeyboardEvent):void
        {
          if (event.keyCode == Keyboard.LEFT)
          {
            character.x -= 10;
          }
            else if (event.keyCode == Keyboard.RIGHT)
          {
            character.x += 10;
          }
          else if (event.keyCode == Keyboard.DOWN)
          {
            character.y += 10;
          }
          else if (event.keyCode == Keyboard.UP)
          {
            character.y -= 10;
          }
        }
      }
     }
  5. Compile the program. Your game character will appear on the stage. You can move it around the stage using the arrow keys, as shown in
    Figure 5-2
    .

    Figure 5-2.
    Move the game character around the stage with the keyboard arrow keys.

I'm sure you noticed some obvious problems with this player character control scheme already, but before I show you the solutions, let's have a quick look at how it works. The first thing you had to do was import the
KeyboardEvent
and
Keyboard
classes into the program.

import flash.events.KeyboardEvent;
import flash.ui.Keyboard;

The
Keyboard
class's primary job is to make it easier to figure out which keys the player is pressing. The
KeyboardEvent
class allows you to add an event listener to the stage to listen for key presses. That's exactly what this bit of code in the constructor method does:

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);

This is the same event listener you used in
Chapter 4
, and it works in the same way. Its job is to detect when any keys are pressed on the keyboard. It calls the
keyDownHandler
, whose job is to process this event.

public function keyDownHandler(event:KeyboardEvent):void
{
  if (event.keyCode == Keyboard.LEFT)
  {
    character.x -= 10;
  }
  else if (event.keyCode == Keyboard.RIGHT)
  {
    character.x += 10;
  }
  else if (event.keyCode == Keyboard.DOWN)
  {
    character.y += 10;
  }
  else if (event.keyCode == Keyboard.UP)
  {
    character.y -= 10;
  }
}

As you learned in
Chapter 4
,
Keyboard.LEFT
,
Keyboard.RIGHT
,
Keyboard.DOWN
, and
Keyboard.UP
represent numbers that AS3.0 links to keys on the keyboard. These numbers are called key codes.

The key codes that AS3.0 uses are based on ASCII, which is a fixed standard for interpreting numbers as characters. For example, the ASCII number 65 refers to the uppercase letter A. However, different operating systems don't map these codes to the keyboard keys in exactly the same way. If you design and test a game using key codes on a Windows computer and then run the SWF on another operating system such as OS X, the key codes that you used might not match OS X's keyboard mapping. For this reason, it's preferable to use the
Keyboard
class's built-in key properties (such as LEFT and RIGHT,) instead of the actual key code numbers.

If you need to use a key that isn't represented by these properties, you have to use a key code number. Make sure that you test these key codes carefully on each operating system your game will run on to ensure that it's mapped to the correct keys on every one.

If you're building a game using Flash Professional software, some keys may not work while you're building and testing the game. Flash Professional reserves some keys for shortcuts (for example, Ctrl and S to save a file). So if you used any of these keys or key combinations in your game, you need to hold down Shift while testing the keys to override Flash Professional's own use of them. The keys will work fine in the published SWF.

Very simply, the
keyPressHandler
contains an if/else statement that figures out which key is being pressed and then moves the character left, right, down, or up by adding or subtracting 10 pixels from its x or y positions.

That's easy enough, but why is it working so badly? When you tested the program, you might have noticed a few big problems:

  • The movement of the character is jittery.
  • When you press one of the arrow keys, there's a slight delay before the character starts moving.
  • You can move the character in only one axis (x or y) at a time. You can move the character left and right, or up and down, but not diagonally. Try pressing both the up arrow and the left arrow at
    the same time; it just moves the character in the direction of whichever key you pressed last. How can you move the character on the diagonal?

These problems are due to your computer keyboard's
key buffer
. When you press a key on the keyboard, the keyboard tells the computer that the key has been pressed down only once; it doesn't know if the key is being
held down.
The computer's operating system has a key repeat feature built into it that resends the KEY_DOWN event at regular intervals. The key repeat is needed for word processors, for example, so that you can hold down a key to repeat a character on the screen. You don't have any control over how the key repeat runs, and the result with a Flash game is the jittery movement you see on the stage.

To solve this problem, you need to work around the key buffer so the keys don't directly move the object. You can use the keys to determine the object's direction and speed, but you need to find another way to actually move the object.

Controlling the keyboard'the right way!

Now that you know how AS3.0 can find out which keys you're pressing, you can use this same basic system to refine the keyboard control program.

There's a lot of new stuff here, but don't panic! I'll break everything down step by step once you have the program running to show you exactly how it works. But for now, here's a quick summary of what you need to do:

  • You have to import AS3.0's
    Event
    class so that you can use its ENTER_FRAME property.
  • You have to create two new variables:
    vx
    and
    vy
    . These variables will store the vertical and horizontal velocities of the object.
  • You have to change the
    keyDownHandler
    so that it no longer changes the position of the character. Instead, it updates the
    vx
    and
    vy
    variables with the speed and direction that the object should move in.
  • You have to add an event handler called
    keyUpHandler
    . Its job is to detect when the arrow keys are released. When they are, it sets the character's speed to 0.
  • You have to create a new event handler called
    enterFrameHandler
    that uses the
    vx
    and
    vy
    variables to actually move the character.
BOOK: Foundation Game Design with ActionScript 3.0, Second Edition
5.09Mb size Format: txt, pdf, ePub
ads

Other books

Be Mine by Sabrina James
Circles of Time by Phillip Rock
Enslaved by Brittany Barefield
Raylan by Leonard, Elmore