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 3 Section 1

Game Overview

A typical scenario is to have objects on the left and right side of the screen. The player's objective is to drag items on the right to items on the left. However, the items are not in order and there is only one correct pairing for each item.

Figure 3.1 shows a sample screen for the completed game. The items on the right, in this case some text members, can be moved to the graphics on the left. If a player moves the item to the wrong place, the item is rejected and it snaps back to its original position. However, if a match is correct, then the item should lock in to place and remain there for the rest of the game.

Figure 3.1
A possible screen layout for a click and drag matching game.

Try the game out before reading any further. It can be found on the book's CD-ROM, named 03matching.dir.

Close Enough for a Match

This game sounds simple, but there are a lot of details to be worked out. For instance, how close does the player have to get to make a match? If we require the player to place the item in the exact right location, with pixel precision, then it will be a very hard game to play. Instead, we should make it so that if the player is relatively close, the sprite should snap into location automatically. This should be good enough to convince the player that, if a match is rejected, it is rejected because the match was incorrect, not because the player did not place the item close enough.

Each sprite has two properties that can come in handy when deciding if one sprite has been dropped onto the other. The first property is its location, or loc. This is the point on the Stage where the registration point of a bitmap, or the upper-left corner of a text member, is located. The other property is the rectangle, or rect, of the sprite. This is the bounding box of the entire sprite. Figure 3.2 shows both the registration point and the bounding box of a sprite.

Bounding Box Registration Point
Figure 3.2
This diagram shows the bounding box, or rect of the sprite, as well as the registration point, which corresponds to the sprite's exact location on the Stage.

The registration point is the location in a bitmap sprite that is used to decide its placement on the Stage. If a sprite is placed at location 75, 125 on the Stage, it's actually its registration point that is located at 75, 125. By default the registration point for bitmaps is at the center of the bitmap, but this can be changed in the Paint window. For text sprites, the registration point is always set to the upper-left corner of the text.

The simplest way to determine if two sprites are being brought together is by examining their loc properties. However, the loc properties will only match up if the two sprites are in the exact same location. So this is not a good method to use unless you want to drive the player crazy.

Another method is to compare the rects of the two sprites. You can use the intersects comparison in Lingo to determine if two sprites overlap. However, this method is too vague. Large sprites can appear to be quite far away, and yet still have their bounding boxes touching at one point. More importantly, it's easy to have one sprite's bounding box overlap the bounding boxes of several other sprites. Determining which sprite the user meant as the destination can be a problem.

A good compromise is to compare the location of one sprite to the rectangle of another. You can do this with the Lingo inside function. This tells you if the loc of the dragged sprite is inside the rect of the destination sprite.

Correct Matches

Another factor to take into consideration is how the items on the right know which item on the left they are supposed to match. The Lingo code cannot magically know which items are meant for each other. The person creating the game must establish this sometime, preferably without having to change any Lingo code.

Both the draggable item and the destination item are really just sprites on the Stage. One way to go about matching items up is by developing a system in which an item in one sprite channel is matched with an item in either the sprite channel before it or after it. For instance, the item on the right can be in sprite channel 7. The item that it matches on the left can then be in sprite channel 6. The Lingo code knows that these two sprites match up, because the moveable sprite should always match the sprite one channel away. Figure 3.3 shows what the Score might look like with such a system.

Figure 3.3
This Score window shows a group of sprites. Sprites 6, 10, 14, and 18 are the moveable sprites, and sprites 5, 9, 13, and 17 are the sprites they are mean to match.

Remember that just because the sprites are arranged in a certain way in the Score, it does not mean that they have to be arranged in a similar way on the Stage. Two sprites can be in adjacent channels in the Score, but on totally different parts of the Stage.

It's also a good idea to offer a few options that can be changed when the behavior is used. We can make our code adjust to one of three situations. The first is when the sprite is meant to match the sprite in the previous channel. The second is when the sprite matches the sprite in the next channel. The third option should allow the author to specify any sprite at all by number. Building versatility into your code like this can make your behaviors much more useful. They can also cut down on the number of times that a non-Lingo Director user utilizing your code needs to request changes to the behavior.

Locking Sprites in Place

After a user drags a moveable sprite on to another one, and it has been determined that a match has been made, the next step is to lock the moveable sprite to its final position. A simple way to do this is to set the moveable sprite to the same location as the destination sprite. If the two sprites are identical in size and shape, then the moveable sprite locks to a position on top of the destination sprite. However, by playing around with the registration points of both of these sprites, you can have them lock into position in many different ways.

For instance, the destination sprites can look as if they are missing a piece. The moveable sprites can look just like that missing piece. When a correct match is made, the two sprites are positioned so that they appear to be a complete graphic.

One problem that this presents is what happens if both the destination and the moveable sprites are text? In that case, you can't easily adjust either of the sprites' registration points. The code must make a decision about what to do in this case. In the game we will develop here, we will assume that when two text members are matched, that the moveable one gets placed just to the right of the destination one.

Game Over

A game like this usually ends when the user correctly matches all the items. We need to recognize this event in our code.

The perfect time to test for this game over condition is just after a match has been made. After all, this is the only point in the game where the end can possibly be reached. It cannot be reached when the user is doing nothing, nor when the user makes an incorrect match.

At this point we need to check through all the possible matches and verify that they are all complete. If even one is not complete, then the game is not yet over and no action needs to be taken.

If the game is found to be complete, then we can specify a frame that the movie will go to. This can be a "game over" frame, or possibly the next level of the game.

Special Effects

In addition to the standard functionality like dragging, dropping, matching and locking, our game can have a little more pizzazz. Quite simply, we can add sound.

There should be at least two sounds associated with the actions in the game. They should be the sounds that play when the user is done dragging a sprite. One sound signifies a completed match, and the other signifies an incorrect match.

More sounds could be added as well. You can have a "pick up" sound when the user first clicks on an item to drag it. You could also have a sound that plays when the game is complete.