Accessibility

Table of Contents

Insult Dueler: Building a Flash game on Adobe AIR

Building the engine

As mentioned earlier, this game is all about insults and comebacks. As you progress you unlock content. Although this is an extraordinarily simple game, the key to realizing this is keeping my code organized. I don’t want to wade through a hundred lines of game code to determine when a user selects a character. I want my character selection to be separate from my game. That way, if there’s a bug with a character selection screen I know just where to look. I want all the major pieces of functionality divided in a way that will allow me to describe specific functionality.

I follow a very loose organizational model for my code. The engine that drives this game is broken up to serve three types of classes: screens, game data, and user interface (UI).

  • Screen is the term I use at Big Spaceship to define a class that currently occupies the majority of the user's attention. Each screen will be passed a movie clip housing all of the artwork and animation visually displayed to the gamer.
  • Game data is all of the content related to the game. Game data classes won't have any graphic elements to them; they simply manage information behind the scenes.
  • UI is anything that will allow the user constant (or near constant) control of the user interface—a navigation at the top of a site, for example. In this case, it relates to dragging the window, the Minimize and Close buttons, and alpha transparency. UI classes will also be passed a movie clip containing artwork and animation.

To tie it all together, I have a Document Root class called Main. This class instantiates (new MyClass()) all of the other classes and listens for any events. Main is the hub that tells the other classes how to work together. In addition, Main is responsible for any preliminary loading.

The Constants class (for the stuff that never changes)

The Constants class contains all of the permanent, never-changing variables needed for the game to work. This class contains the entire script for the game in array format. The INSULTS array looks like this:

public static const INSULTS   :Array = [ "This is the -END- for you, you gutter-crawling cur!",
"Soon you'll be wearing my sword like a shish kebab!",
"My handkerchief will wipe up your blood!",
"People fall at my feet when they see me coming.",
"I once owned a dog that was smarter than you.",
"You make me want to puke.",
"Nobody's ever drawn blood from me and nobody ever will.",
"You fight like a dairy farmer.",
"I got this scar on my face during a mighty struggle!",
"Have you stopped wearing diapers yet?",
"I've heard you were a contemptible sneak.",
"You're no match for my brains, you poor fool.",
"You have the manners of a beggar.",
"I'm not going to take your insolence sitting down!",
"There are no words for how disgusting you are.",
"I've spoken with apes more polite then you.",
"You're as repulsive as a monkey in a negligee.",
"You're the ugliest creature I've ever seen in my life!",
"I'll hound you night and day!"];

Every other class imports Constants. If I want to output "You fight like a dairy farmer.", I can type trace(Constants.INSULTS[7]).

I have a similar array called COMEBACKS and yet another called BOSS_INSULTS. I'm not going to give those away so easily, though—you'll have to play the game to find the comebacks.

To offer the user a clue as to when the computer answers with an incorrect comeback, I added an array of guaranteed wrong comebacks. These comebacks are always wrong. Use 'em and you'll lose every time.

public static const GENERIC_WRONG_COMEBACKS :Array = [ "I am rubber you are glue.",
  "Oh yeah?",
  "This is going to hurt, isn't it?",
  "Uh... chicken parm?",
  "Golly, that's a good one!",
  "Look behind you! A three-headed monkey!",
  
  // these next two are really, really cheesy. I'm sorry. I can't resist the urge to cheese it up.
  "I'm terrible at this. I'm going to quit swordfighting and learn ActionScript instead.",
  "Well, I'm going to lose this battle... but at least I'll lose it in a transparent window."
];

So… how do I tell which character is which?

Constants also contains an array called CHARACTER_DATA. CHARACTER_DATA is the single most important variable in the site. Each value in the array is an object with the following properties:

  • KEY: The index number of this object can be found in the array. Constants.CHARACTER_DATA[0].KEY should be 0. This way I have the flexibility to reference an object by its place in the array or by the object. I know what each character object's key is because I know that I'm never going to move the array around. It will remain constant. Hence the aptly named class!
  • SWF: The SWF file of the character's artwork (guybrush.swf). I'll go over this file later. Main loads this file and passes it to the game screen.
  • JPG: The character's portrait JPG (babar.jpg). Main loads this and passes it to the menu screen.
  • SHORT_NAME: A way of getting the character's first name, or nickname if I need it for a smaller text area (Babar).
  • LONG_NAME: The character's full name (Babar, Lord of the French Bulldogs).
  • TEXT_FOREGROUND and TEXT_BACKGROUND: The color of the text that displays over the character's SWF file in the game screen. A hexadecimal value, like 0xFFFFFF for white.
  • UNLOCKED: Is the character unlocked by default? True or false.
  • BOSS: Is this character a boss? True or false.

In code, it looks a little like this:

public static var KEY_BABAR:int = 0; // now I can reference Guybrush from Constants by using Constants.KEY_BABAR
		    
public static var CHARACTER_DATA :Array = [{
KEY: KEY_BABAR,
SWF: "babar.swf",
PORTRAIT: "babar.jpg",
SHORT_NAME: "Babar",
LONG_NAME: "Babar, Lord of the French Bulldogs”,
TEXT_FOREGROUND: 0x000000,
TEXT_BACKGROUND: 0xFFFFFF,
BOSS: false,
UNLOCKED: true },
];

All I need to do is add additional objects for all the other characters.

You might be wondering about Constants.KEY_BABAR. I know I can access all the Guybrush data from Constants.CHARACTER_DATA[0], so why bother with the extra variable? There are two reasons. First, to protect myself. If I accidentally write Constants.CHARACTER_DATA[1] somewhere, the site uses the wrong character data, creating a bug. However, if I accidentally type Constants.CHARACTER_DATA[Constants.KEY_BABARR] (with an extra R), that variable doesn't exist and the compiler will tell me there's an error. Way easier to diagnose.

The second reason is to make the code easier to read for other developers. Don't you hate looking at code like this:

var a1 = b26;
b26 += mClip352["stuff_" + temp];

To another programmer, this is a meaningless mess of letters and numbers. KEY_BABAR, although more to type, is more eloquent. Another programmer will see that and know right away that whatever is going on is happening specifically to Guybrush.