Note About This Book: Advanced Lingo For Games was written by Gary Rosenzweig in 2000 for users of Macromedia Director 7. It is presented here for free on an as-is basis, with no updating. Most of the information and code here can be used in the most recent version of Director. The book has been reproduced from the final editing files archived in 2000, and not the final proof galleys. So some minor differences between this version and the printed version my exist. The entire contents of this book are Copyright 2000, Gary Rosenzweig. No part may be reproduced or copied without written permission. The text here is provided for individual use only.
Want to thank me for making this book available for free? Just buy Special Edition Using Macromedia Director MX and we'll call it even!

Advanced Lingo For Games
by Gary Rosenzweig


Chapter 1 Section 2

Game Lingo

The purpose of this book is two-fold: to show you how to make games with Director and Lingo, and to teach advanced Lingo along the way.

As mentioned in the introduction, this book is not meant for absolute beginners. You should have a good understanding of how the Stage, Score, and Cast work together. You should also know how to write basic and intermediate Lingo scripts.

That said, I don't want to bog the first few chapters of the book down by going over Lingo basics. There are plenty of other good books on the market that do this. This book assumes that you already know the basics found in the first half of any general Director and Lingo book.

If you feel you need some more Lingo training, try the Special Edition Using Director 7, or Special Edition Using Director 8 books by the same author. They both start at the beginner level and advance the reader up to the level of this book.

One of the purposes of this chapter is to look at some intermediate and advanced Lingo techniques so that you can begin creating games.

Programming Step By Step

When someone asks me for Lingo programming help, I find that there is one answer that covers most of the questions. This is that the person is trying to tackle too big of a problem all at once. They need to break the problem down into smaller ones. If they can't solve those problems, then they need to break them down into still smaller ones.

This is a basic principle of programming. Every large problem is really several smaller ones.

Take, for instance, the case where a beginner programmer wants to have a button that changes when the user moves the mouse over it. However, the programmer is not sure how to do this with Lingo.

So, he breaks it down into smaller pieces. The first piece is, can he detect when the mouse moves over the sprite? The on mouseEnter command turns up when searching the Lingo dictionary. So he tries it:


on mouseUp
  put "Here!"
end

This is as simple as a handler can get. The programmer then runs the movie and sees that when the cursor enters the sprite area, the word "Here!" appears in the Message window.

Next, the programmer wants the sprite to change. So he creates the second member that represents the changed button. A little more research turns up that he can set the member property of a sprite. So he adds this to the script:


on mouseUp
  sprite(1).member = member("rollover button")
end

Step, by step, the programmer discovers the on mouseLeave handler to turn off the rollover state, the me parameter which is used by the handlers so that they can use me.spriteNum instead of hard-coding the sprite number, and he can keep on going until the script meets his needs.

Although this is a simple example that may already seem easy to you, it demonstrates the power of breaking down programming problems to their basic parts. It is important to understand this technique and use it while creating games.

One Frame Movies

The Score is an animator's tool. It is used by non-programmer Director developers to create presentations involving many screens.

However, for a game developer, the Score is not nearly as important. It is mostly used for the arrangement of sprites vertically, rather than the arrangement of frames horizontally.

This is because most games take place in one frame. If there are any other frames at all, they are for things such as introductions, instructions, and "game over" screens. Most of the work goes into the main game frame.

When you create a sprite by dragging a member to the Stage or Score, Director creates a long sprite span, usually 28 frames long. This is a useful starting point for animators, but not for game developers. You will probably want to change this preference to create new sprites with a single frame sprite span. You can modify this preference by choosing File, Preferences, Sprite.

This main frame is a looping frame. At the least, its frame script channel contains the simple looping behavior that all Lingo programmers should be familiar with.


on exitFrame me
  go to the frame
end

The purpose of such a behavior is to catch the movie just as it is about to leave the current frame and advance to the next. Then, to send it back to replay the frame again. This way, the frame loops over and over.

The on exitFrame handler is also used to set off certain timed events and to check to see if any keys are depressed.

Object-Oriented Thinking

Since Director 6, you can't help but program in an object-oriented manner. As a matter of fact, you would have to go out of your way to program any other way.

Each sprite is an object. Each frame is an object. You use behavior scripts to control these objects.

Even though most programming in Director is already object oriented, it helps to think in an object-oriented way when planning your game.

For instance, if the game has various moving pieces, is each an object? Or, are these elements controlled by the frame, which is an object? Are the elements similar enough to be controlled by the same behavior, but with different parameter settings? Or, should you write unique behaviors for each?

Using Behaviors

Many old-school Lingo programmers have still not adjusted to the modern behavior-style programming. But behaviors are great for game programming. They are a much better way to organize your code than the old style of using a large movie script and a lot of global variables. Even if the result is the same as the old school programming, your code will be easier to create, understand, and reuse.

If you are not familiar with behaviors, here is a quick primer. Behaviors are script members that can be attached to an individual sprite, many sprites, a frame, or a span of frames.

Behaviors control the object that they are attached to. So a sprite behavior controls the sprite, while a frame behavior controls a frame. Director makes no distinction between these two types of behaviors. That is up to you and how you code the behavior.

One of the key elements of a behavior is the capability to have parameters that can be set when the behavior is added to the Score. You can set the parameters differently for different sprites.

So, for instance, you could have a behavior that controls an alien spaceship in a game. The behavior could have a parameter that determines the speed of the spaceship. When you assign it to one sprite, you could set the speed to one value. Then, when you assign it to another sprite, you could use another value. It is the same behavior, but the sprites exhibit different traits because the parameters are set differently.

The key to using parameters is to understand the on getPropertyDescriptionList handler. This handler allows you to specify parameters that will be defined when a behavior is first attached to a sprite. For instance, you could have the pSpeed property start off with different values. Here is an example:


on getPropertyDescriptionList me
  list = [:]
  addProp list, #pSpeed, [#comment: "Speed", #format: #integer, #default: 25]
  return list
end

The property ÒpSpeedÓ would have been declared at the top of the behavior script. The handler works by populating and returning a list with each property to be set, and a smaller list as the values. Each of these small lists has at least the standard properties of #comment, #integer, and #default. They are all used to compile a dialog box that appears when the behavior is attached to a sprite. Figure 1.1 shows the dialog box created by this example.

Figure 1.1
A behavior property settings dialog box changes depending on what the on getPropertyDescriptionList handler contains.

After a behavior is created, it can be used on many different sprites or frames in the movie. It can even be used in other movies. In fact, the behavior library that comes with Director is simply a collection of premade behaviors that Macromedia has included for novices. You'll see many examples of handlers in the chapters of this book.

Lists

Most beginner Lingo programmers can do a lot of work before they have to figure out lists. However, to make games, you really need to be able to use and understand them.

Lists are groups of values held together in a single variable. They are called arrays in other programming languages. Here are some examples:


[1,2,3,4,5]
[4.5,23.2,12.2]
["Gary", "Debby", "Lucy", "Natasha"]

Each of these is an example of a simple linear list. A linear list is just a list of values. You can even store lists inside of lists, or lists that have all sorts of different types of values.


[[1,4],[5,6],[3,7],[5,2]]
[6,7.2,"games"]

Another type of list is called a property list. A property list contains pairs of information. The first part of any item is the property and the second part is the value. Here is an example:


[#speed: 7, #power: 4, #defense: 9]

This example uses symbols as the properties, and integers as the values. You can actually use any type of data for either.

Symbols, which always start with a "#", are used frequently in property lists. Some of Director's functions, such as the on getPropertyDescriptionList handler seen earlier in this chapter, require them. In addition, symbols are useful for creating object-oriented lists and variables values.

To handle lists, you refer to item numbers with brackets and properties with dot syntax. There also are a variety of functions and commands. Here is an example from the Message window:


myList = [101,103,104]
put myList[2]
-- 103
myList = [#this: 101, #that: 106, #other: 108]
put myList.that
-- 106
put getProp(myList,#that)
-- 106
put getPropAt(myList,2)
-- #that
deleteProp(myList,#this)

The code above starts by creating a linear list, and then getting an item from it. Then, it created a property list and gets a property from it in two different ways. Finally, it gets a property name at a specific location and then shows you how to remove a property.

Lists are useful structures for storing such things as game boards, game pieces, moves, and so on.