Terrapin Resources

Animations

If you want to advance from regular drawings to drawings that actually move, this is the right section for you. In this section, you will create an small movie of a sailboat sailing into the sunset.

Special thanks goes to Paolo Ruiz, who created this wonderful program. The entire program is also available in our Logo Library.

Apart from animation, this section als shows how to work with bitmaps instead of turtles as moving objects.

But first, let us dive into animation in general.

The Basics

Let the Turtle Move

The trick behind animation is to move your turtle independently from a running program. The easiest way to move a turtle is to let it advance, then wait for a little while, and repeat everything over and over again:

If you run this code, the turtle starts moving, and stops only when you click the Stop button. Easy enough, but what if you need to move more than one turtle at a time? Then things become really complicated really quickly.

SETVELOCITY

Thankfully, Logo offers a way to let a turtle move independently. The SETVELOCITY command does just that. It expects a single input, which is the number of pixels (dots) the turtle should move per second. A value of 100, for example, lets the turtle move with a speed of 100 dots per second:

SETVELOCITY 100

Setting it back to 0 stops the turtle.

Right-click your turtle and open the Properties dialog; then play with the Velocity and Heading settings to get a feeling for the velocity.

Using SETVELOCITY, you can move multiple turtles around without having to loop and wait and loop and wait…

Using Shapes

You probably already know that you can drop a shape onto the turtle to change its shape to, say, a bird or a car. Moving a bird around looks so much more fun than just having the turtle move!

Problems arise when you want the turtle to move in a direction different from straight up. Your shape rotates just nicely as well. This may be fine if you, for example, want to steer a racing car, but rotating an elephant, for example, does not look right. An elephant would not want to walk on its tusk.

Logo also has a solution to this problem. The LOCKSHAPE command locks the shape in whatever heading it points so regardless of the underlying turtle’s heading, and the UNLOCKSHAPE command makes the shape rotate with the turtle’s heading again.

Try this for yourself. Drop an elephant on the turtle, make it become an elephant. Then, enter the LOCKSHAPE command. Now you can move and turn the elephant without having it rotate.

The Turtle Size

Let us assume that your turtle’s shape is now an elephant. Elephants are big animals, and the elephant shape is also big. What if you want the elephant to be much smaller?

Again, Logo comes to your rescue. The SETTURTLESIZE (or SETTS) command changes the size of your shape. A size of 1 is the original size. Make it smaller by using a smaller value, like 0.5 for half the size, for example, or double its size my using SETTS 2. The TURTLESIZE command reports the current size of the shape.

You could even change the actual size of the shape by setting the turtle’s SIZE property. This property takes a two-element list containing the shape’s width and height in pixels.

The elephant shape, for example, reports a width of 249 and a height of 200 pixels:

GPROP 0 "SIZE
Result: [249 200]

You think that the elephant is too skinny? Well, make it wider:

PPROP 0 "SIZE [400 200]

Try for yourself!

Did you know that many Logo commands just manipulate a trutle’s properties? The SETTS commmand, for example, alters the turtle’s SCALE property, and the SETVELOCITY command changes the turtle’s VELOCITY property. That’s why you can change most of these values when your right-click a turtle to display the property editor.

Sailing Into the Sunset

Now let us get to our beautiful sunset movie.

For this movie, you will not actually use the turtle other than to draw the actual objects that move. In the animation world, they call objects that move “sprites”, and this is what we will be calling them.

How do we create sprites?

  1. Draw the sprite
  2. SNAP the drawing into a bitmap
  3. TELL the bitmap and issue commands

First, let us look art the SNAP command. This command expects two or three inputs. The first two inputs are the width and height of the area to snap. The third input instructs the command to either snap both the drawing and the background (which is the default), the drawing only, or the background only. The command returns the name of the snapped bitmap. The turtle’s position is used as the lower left corner of the area to snap.

An example:

SETXY [10 20]
(SNAP 50 100 "DRAWING)

Here, the lower left corner is at 10 horizontal and 20 vertical. The area to snap is 50x100 pixels, which puts the upper right corner at 60 horizontal and 120 vertical. In our case, we do not want any of the white background to be snapped, so we use the optional value “DRAWING as the third input.

The return value is the name of the snapped bitmap, which could e.g. be BITMAP.1. In the procedures below, we store that name into a more descriptive variable, like for example:

MAKE "CLOUD1 (SNAP 60 30 "DRAWING)

This lets us use the variable to activate the bitmap later. The TELL command instructs Logo to forward all turtle and movement commands to the name or list of widgets given as input.

Examples:

TELL 0 ; activate turtle #0
TELL [0 1 2 3 4 5] ; turtles 0-5 will listen to commands
TELL :CLOUD1 ; the bitmap whose name is in :CLOUD1 will listen

The Sailboat

First, we need the sailboat. There is no sailboat in the Toolbox to speak of, so we need to draw our own. Here is the Logo procedure:

It is a good idea to clean the screen after the drawing so the next drawing can happen.

A word about this command:

PPROP :SHIP "WRAPMODE "WINDOW

Usually, turtles and sprites wrap to the other side of the Graphics panel when they hit any boundary. The sailboat should start off-screen and sail into the horizon at about the center of the picture. If the sailboat would wrap, we would not be able to really place it outside of the drawing area. Therefore, we set the sailboat’s WRAPMODE property to WINDOW, which lets the sprite sail outside of the drawing area.

For more wrap modes, see e.g. the WINDOW command.

The Clouds

We want the clouds to move slowly acress the screen; therefore, clouds need to be sprites as well. Here is how:

Then, we create the procedures that make the clouds, and initialize them:

These procedures position the clouds; they use the LOCKSHAPE command, because we want the clouds to move from left to right, which needs a heading of 90 degrees without the could turning as well. Finally, we use SETVELOCITY to have them start moving on their own.

Note how we use the TELL command to activate each sprite and have it listen to Logo commands.

The ship also need some initialization:

The ship needs to adjust the size while moving, which is a bit more complex than SETVELOCITY. We’ll talk about this in more detail below.

The Scenery

Finally, we can put it all together and create the scenery. A small procedure for a few waves, and another procedure for the horizon and the sun is needed.

Note that we first need to make the clouds and the ship; after that, we are free to draw the rest.

Moving the Sailboat

We are almost there. The tricky part is to move the sailboat. It needs to move forward and at the same time become smaller, and all in a smooth fashion.

Now it is time to talk about the core of animation. You would not want to use the SETVELOCITY command, because you need to shrink and move the boat at the same time, both in certain time intervals.

Usually, this would require some sophisticated programming with wait loops or the like.

You do not want to do this. Instead, Logo uses a concept called “Animation Frames”. You may remember that movies in a cinema are actually a sequence of pictures, often with 24 pictures per second. The human eye is too slow to distinguish between these pictures, creating the illusion of continous movement in the brain. If you, for example, were from Mars with a much sharper eyesight, you could not watch a movie without getting a Martian headache, because the flickering would drive you crazy.

Logo uses the same concept to animate turtles, shapes and the like. It acts like a movie with 30 pictures, or frames, per second. And Logo offers to call a list of your Logo commands 30 times a second.

How convenient! Now, we just need to create a procedure that Logo needs to call 30 times a second, and both advance and shrink the sailboat during each of these procedure calls. Here it is:

The first line stops the animation frames for the ship and exits the procedure when the ship has reached the horizon.

You can now use the WHEN command. This is a very powerful command that lets you attach Logo commands to a lot of events, like when you press a mouse button, or the mouse moves, and much more. The Logo manual has an entire chapter dedicated to the WHEN command. Click here for more information.

For now, we just use the WHEN command to make Logo call our movement procedure:

WHEN [ANIMATION FRAME] [MOVE.SHIP]

As you saw before, to stop Logo from calling MOVE.SHIP repeatedly, use the WHEN command without a runlist:

(WHEN [ANIMATION FRAME])

The Main Program

That’s it. Well, almost.

We need the main program that puts everything together:

The last command WAIT -1 needs an explanation. All Logo commands that Logo should execute on certain events like an animation frame stop when a program ends. If you do not wait forever, the WHEN command simply ceases working before the first animation frame is executed. So the only solution is to wait forever so Logo can call the animation frame commands repeatedly.

But how to end the program then, apart from clicking the Stop button?

If you look at the MOVE.SHIP procedure, the first line reads

IF :SHIP.POS <= 1 THEN (WHEN [ANIMATION FRAME]) STOP

If you want the whole movie to stop, including the clouds, use the TOPLEVEL command instead. This command causes Logo to return to toplevel, ending the program, and stopping all independent movement.

IF :SHIP.POS <= 1 THEN TOPLEVEL

Right now, we stop the program by clicking the Stop button so we can admire the clouds.

Finishing Touches

Are we done?

Almost.

If you run the ANIMATE procedure, everything runs just fine, but you see an annoying flicker when you draw the sailboat and the clouds. It would be great if the turtle could draw the sprites without disrupting the movie.

Again, Logo is there to help you. The FREEZEPIC command freezes the output of the Graphics panel. You can still draw, but the drawing will not display anymore. This is exactly what the doctor ordered. The UNFREEZEPIC revives the Graphics panel, and all drawings that have been made while the picture was frozen will appear.

What is needed is the following:

  1. Call FREEZEPIC
  2. Do all the drawing and creation of the sprites
  3. Erase the drawing and call UNFREEZEPIC

Let us alter the ANIMATE procedure to include FREEZEPIC and UNFREEZEPIC:

Now, we are really done! Enjoy!