Lingo basics

-- exercise III, March 15, 2000 --


I. Controlling navigation.
II. Text input.
III. Animation by cast member shifting.
IV. Rubberbanding.
V. Autonomous time-based behavior.


The Suspicious Alien. Won't take his eyes off the cursor.


A quite common way of creating animation is to substitute cast members in the same sprite. This provides flexibility beyond the tweenable properties in score animation and the Lingo-controllable properties of sprites. The downside is, of course, the extra work involved in creating all the cast members needed for the animation cycle.


The playback of the movie loops in one single frame.

The cast contains nine different versions of the alien's eyes: one normal and eight looking in different directions. They all have the same size; only the pixels of the eyes are changed.

In the start setup, the normal version of the eyes if placed on top of the sprite containing the whole alien. The reason for swapping only the eyes is that we want the cast members to be as small as possible. Only the eyes move, and nine versions of the whole alien would make the movie heavier.

The background of the movie is filled with a white rectangle. The rectangle is given a sprite script that makes the alien look at the cursor as long as it is inside the sprite. When the cursor leaves the sprite, the alien looks straight ahead.

Making the alien look at the cursor requires a bit of trigonometry. First, we need to compute the angle between the center point of the eyes sprite and the current position of the cursor. Then, we select a cast member for the eyes sprite based on the angle.

Let's say that Xe and Ye are the coordinates of the eyes sprite in Director's coordinate system. Xc and Yc are the coordinates of the cursor.

We compute x = Xc - Xe and y = Ye - Yc. As you can see, the expression for y is backwards. The reason is that the y axis in Director runs the wrong way: from the top of the window and down. In normal coordinate systems, the y axis runs upwards.

Now, we can find the angle between the alien's eyes and the cursor. We want it in degrees because it is more familiar to us. The trigonometric function we need is called arctan. In Lingo, it returns a result in radians. To convert radians to degrees, we need to multiply by 360 and divide by 2*pi. Moreover, the arctan function is a bit tricky because it is only defined when x is greater than zero. Here are the necessary equations:

if x > 0:
angle = arctan(y/x)*180/pi

if x=0 and y>=0:
angle = 90

if x<0 and y>=0:
angle = arctan(y/x)*180/pi + 180

if x=0 and y<0:
angle = -90

if x<0 and y<0:
angle = arctan(y/x)*180/pi - 180

Now we have an angle between -180 and 180 degrees. 0 is straight to the right; 90 is straight up; 180 is straight to the left; -90 is straight down.

To get the alien to look in the right direction, all we need to do is to select the right cast member for the angle and substitute it into the eyes sprite.

Relevant Lingo  

The sprite in the background needs a handler that is called as long as the cursor is within it. You can use on mouseWithin. It is called repeatedly until the cursor leaves the sprite. Very suitable for continuous update of the angle between the alien eyes and the cursor.

on mouseLeave is called when the cursor leaves the sprite. You can use it to reset the alien's eyes to the normal cast member.

the mouseH and the mouseV are properties that return the current position of the cursor on the stage. H is for horizontal and V is for vertical, i.e., Xc and Yc in the expressions above.

the locH of sprite and the locV of sprite return the stage coordinates of a sprite's registration point. Bitmap cast members (such as the alien's eyes) get their registration points in the center by default, which suits us fine.

set the member of sprite <number> to member <name or number>. This is the core command of this exercise. It is used to substitute cast members in a sprite.

set <variable> = <value>. You can use as many local variables as you want in a Lingo handler. You do not need to declare them in advance; the first time you give them a value, the come into existence within the handler.

atan(z). Computes the arctan function and returns a result in radians.

Some mathematical operators: + - * / = >= <= pi. Notice that Lingo makes a difference between integers and floating-point numbers! If you divide two integers (such as screen coordinates), the result is an integer. This is not what you want for the arctan computation. To make the division return a float (with decimals), you can use the following trick:

set angle = atan(1.0*y/x)*180.0/pi

By multiplying y by 1.0, it turns into a float. That in turn makes the division y/x return a float.

You will also need a multi-way selection statement. if can be used with several branches as follows.

if (angle >= -22.5) and (angle < 22.5) then
  set the member of sprite 5 to ...
else if (angle >= 22.5) and (angle < 67.5) then
  set the member of sprite 5 to ...
else if (angle >= 67.5) and (angle < 112.5) then
  set the member of sprite 5 to ...

... etc ...

end if