Chapter 7: Bitmaps and Animation
Bitmaps are colorful objects created from pictures. Like many of the objects in Logo, bitmaps respond to certain commands and they have a set of properties that you can manipulate. Bitmaps can be an exciting addition to your projects, not just for their colorful image, but also for the real-life quality they give to animation sequences. They can be confusing at first, but by the end of this chapter, you’ll be circling the globe - or at least making it look that way!
What is a Bitmap Object?
A bitmap object is a bitmap created from a bitmap image. A bitmap image is a picture. A bitmap is a Logo classification of certain types of objects. A bitmap object has certain properties that make it behave somewhat like a turtle - but it’s not a turtle. A turtle is a bitmap but it’s not a bitmap object - it’s a turtle with a pen that can draw lines, stamp shapes, type text and rotate its shape. To avoid some of the confusion, type the following command so you’ll only have one turtle in your workspace while you work your way through the rest of this chapter.
SETTURTLES 1
Of course, the SETTURTLES command requires at least the number 1, but you may as well get rid of all of the turtles so they don’t get in your way. Type:
ERASE 0
Logo Without a Turtle
Turtles are an important part of your Logo environment, especially for making drawings. However, to appreciate how bitmap objects are similar to turtles, it’s best to work without a turtle for a while. Type:
CS
The TELL list is empty
Fog is everywhere now, but the world is not so bleak! Drag the Earth bitmap image from the Other Pictures panel of the Toolbox to the center of the Graphics window and drop it. You have just created a bitmap object. Logo displays the message:
EARTH dropped.
When
you drag a bitmap image to the Graphics window, you can refer to the
bitmap object by the word in the message - EARTH
in this example.
The word is not a name, but you use it in the same way you used
turtle names, which were not really names either. Type:
PONS
There are no names in the workspace:
TELL EARTH
EARTH is neither a procedure nor a name
EARTH
is a word, not a name. Actually, it’s the value of the
NAME
property in the bitmap object’s property list You can think of
the word as the name anyway (after all, that’s how you used turtle
names). Type:
GPROP "EARTH "NAME
Result: EARTH
Type:
SETTNAME "EARTH "TERRAFIRMA
EARTH is not a Turtle
A bitmap object is not a turtle, but you can tell it to do what you want. Type:
TELL "EARTH
WHO
Result: EARTH
The EARTH
is now listening to your commands. A bitmap object
responds to many of the commands you normally use for turtles. Type:
PENDOWN SLOWTURTLE REPEAT 4 [FORWARD 100 RIGHT 90]
No lines are drawn because a bitmap object does not have a pen. Pen-related commands are ignored by bitmap objects rather than causing an error message. The movement of a bitmap object is just like the movement of a turtle. SLOWTURTLE makes bitmap objects move slowly. Bitmap objects move in turtle steps. They also have a turtle compass for measuring turns and knowing which way they are headed. However, it’s as if a permanent LOCKSHAPE has been requested - the image of a bitmap object does not rotate to show the direction it’s heading.
Bitmap objects use the same Cartesian coordinate system that is used by the turtles. Type:
HOME
The EARTH
moves to the center of the Graphics window. The position of
a bitmap object is the coordinate point under its center. You can use
the same coordinate movement commands for bitmap objects that you used
for turtles - SETXY,
SETX, SETY and
so on. You can hide and show bitmap objects with
HIDETURTLE and
SHOWTURTLE, but you might want to use
HT
and ST
and think of them as “hide thyself” and “show thyself”
since bitmap objects are not turtles.
A bitmap object is not a part of your drawing - neither was your
turtle. Drawings are actually created on a layer of the Graphics
window underneath the bitmaps. There are as many layers as there are
bitmaps plus one more for the actual drawing. Each bitmap in the
Graphics window is on its own layer above the drawing layer. The layer
number is the value of the property called Z.ORDER
. It’s like a third
dimension in space - it indicates the depth of the Graphics window and
is used to control the way bitmaps appear when their images overlap.
Define the following procedure for getting the layer number of an object. Of course, with the Extended properties option checked, you can see all of the properties of an object when you right-click (on a PC) or Ctrl-click (on a Mac). However, using procedures to manipulate properties is much more useful, at times.
TO LAYER? :OBJECT
OUTPUT GPROP :OBJECT "Z.ORDER
END
After you’ve defined LAYER?
, type:
LAYER? "EARTH
Result: 0
Layer number 0 is the topmost layer. The object on layer 0 will appear to be on top of all the other bitmaps. (Actually, the bitmap with the lowest number appears on top.) To see all of the bitmaps in your workspace, type:
EVERY "BITMAP
Result: [EARTH]
The EVERY command outputs a list of all of the objects belonging to the classification that you give as input. Drag another Earth bitmap image from the Toolbox and drop it on top of the original image so they overlap. Then type:
EVERY "BITMAP
Result: [EARTH EARTH.1]
When you drag the same bitmap image to the Graphics window, Logo puts a number after the name so that they are unique. With more than one bitmap, it would be handy to find all of the layer numbers at once. Define the following procedure:
TO LAYERS?
FOREACH EVERY "BITMAP [(PRINT "? LAYER? "?)]
END
After defining LAYERS?
, type:
LAYERS?
EARTH 1
EARTH.1 0
The new EARTH.1
bitmap object in now on layer 0 because it was the
most recently selected. It appears on top of the original EARTH
bitmap object which has been moved automatically to layer number 1.
Clicking on an object does not change its layer - you have to click
and drag it to select it which automatically puts it on layer 0 (on top
of the other bitmaps).
Drag out a third Earth bitmap image and play around with all three
Earths. Drag one, check the LAYERS?
and then try the others. If you
think of the layers as a stack of books, you can see how they maintain
their relationship to each other. When you pull out a book in the middle
of a stack, the books above it drop down to a “deeper layer” but they
stay in the same relative order they were in. The books below the one
you pulled out are not affected.
Here is a sample procedure you can define to change the layer number of an object. To use it, give it the object name and the layer you want it on.
TO LAYER. :OBJECT :LAYER
PPROP :OBJECT "Z.ORDER :LAYER
END
Making a bitmap appear to be in front of the others is a simple matter of assigning it to layer 0. However, making a bitmap appear in back of every other bitmap is another matter. It depends on how many bitmaps you have. Here is a sample procedure to force a bitmap to appear in front of the others:
TO INFRONT :OBJECT
PPROP :OBJECT "Z.ORDER 0
END
Here is a sample procedure to force a bitmap to appear in back of the others:
TO INBACK :OBJECT
PPROP :OBJECT "Z.ORDER COUNT EVERY "BITMAP
END
Just for fun, define the following procedure to cycle through all of the bitmaps:
TO CYCLE
FOREACH EVERY "BITMAP [INFRONT "? WAIT 100]
END
The WAIT 100
is needed for you - not Logo - because the change happens
so quickly. To see a simple animation, type:
REPEAT 10 [CYCLE]
Of course, sometimes you want to control who it is that runs your commands. Type:
TELL [EARTH EARTH.1]
EACH [INFRONT WHO WAIT 100]
If you do not check the Extended
Properties option, then when you right-click (on a PC) or Ctrl-click
(on a Mac) on a bitmap object, you will see the Properties of dialog
showing some of the most common properties. It’s similar to the Turtle
Center dialog.
You can get rid of a bitmap
object by clicking on the Delete button. Logo will display a second
dialog to verify your request. You can also get rid of a bitmap with
the ERASE command. Be careful with
CLEARSCREEN
- it erases all of your bitmap objects. Use
CLEAN or DRAW
- neither of them erases the bitmap objects.
Get rid of EARTH.1
and EARTH.2
but leave the EARTH
on the screen.
Use the dialog or the following command:
ERASE EARTH.1 EARTH.2
The Earth bitmap object appears round, but the Earth bitmap image is really a square of 200 by 200 pixels. Type:
SETBG "SILVER
PPROP "EARTH "TRANSPARENT [-1 -1 -1]
All bitmap images are a rectangular shape, with a width and height,
although the part you want to see is not usually square at all. The
unwanted area can be visually eliminated by setting the TRANSPARENT
property to the RGB color value that matches it. That doesn’t always
have to be the outside edge of an image. If the clouds on the Earth’s
image were white, you’d be able to see through them. By default, Logo
sets the TRANSPARENT
property to [255 255 255]
(or white) when you
drag a bitmap image to the Graphics window. The special value of [-1
-1 -1]
forces all of the colors of the bitmap image to appear. The
special value is not stored in the property list, however.
Don’t enter the special value of [-1 -1 -1] into the properties dialog directly - you will not be able to click or right-click on the bitmap object.
The size of a bitmap object is determined by the size of the bitmap
image. You can change it by setting the SIZE
property to a list with
the new width and new height. Or, with the Extended Properties not
checked, you can use the Scale slider control in the Properties of
dialog. It works in a similar fashion to the Scale slider in the Turtle
Center dialog - a scale of 2 would make the EARTH
bitmap object 400
by 400.
A bitmap object will respond to the SETTURTLESIZE command - however, the new size will be scaled to the normal turtle size of 31 by 31 pixels - not necessarily what you want, but useful in the right situation. Try this:
TELL "EARTH HOME
FOR "SIZE 0 8 [SETTSIZE SIZE WAIT 100]
(FOR "SIZE 8 0 [SETTSIZE SIZE WAIT 100] -1)
Initially, the SIZE
property is set to the same value as the
ORIGSIZE
property. The ORIGSIZE
property can not be changed; use it
to reset a bitmap object to its original size. Type:
PPROP "EARTH "SIZE GPROP "EARTH "ORIGSIZE
You can find the current size of a bitmap with the SNAPSIZE command. It needs the name of the bitmap as input. (For turtles, you can use the turtle number.) Type:
SNAPSIZE "EARTH
Result: [200 200]
The image of a turtle can be copied to the drawing layer with STAMP. However, a bitmap object can not copy itself to the drawing layer - it needs the help of a turtle, of all things!
Warning: From now on, a turtle is a turtle and a bitmap is any one of bitmap, bitmap object or bitmap image. People do not always use the precise word to say what they mean, but you should be able to tell which is which by the context in which it is used.
The Turtle Returns
Type in the following instructions to make sure the SHELL.GAME
runs
properly.
CS
The TELL list is empty
SETTURTLES 1
Drag one Earth image to the Graphics window - make sure you don’t drop
it on the turtle! Then define the SHELL.GAME
procedure. It’s a simple
game, but impossible to win every time (unless you cheat and leave the
Show Hints option checked). You can probably figure out what each
command is for. However, this format of the
STAMP command requires the parentheses so
that the turtle stamps a copy of the bitmap instead of a copy of itself.
The coordinates for the bitmap and the turtle allow for the bitmap to be
positioned based on its center while the turtle stamps the rectangular
image in the same way that it does
STAMPRECT.
TO SHELL.GAME
ASK "EARTH [HOME HT]
PPROP "EARTH "RUN [PLAY "AHHA SHELL.GAME]
TELL 0 CLEAN PU HT SETH 90
SETXY [-300 -100]
REPEAT 3 [(STAMP "EARTH) FD 200]
ASK "EARTH [SETX PICK [-200 0 200] ST]
END
SHELL.GAME
runs very fast and then stops. You will notice that the
Traffic Light buttons go on and off very quickly. What’s happening? The
turtle cleans the screen, then stamps three images of the Earth in a
line across the screen. Then, the Earth is moved to a randomly chosen
position that exactly lines up with a stamped image. You can’t tell
which is the bitmap and which is the stamped image until you click on
the right one. It will respond by saying “Ah ha!” and then run the game
again automatically. If you want to save it in a workspace file, type:
SAVE "SHELLGAME
You could modify it to use a different graphic image or a different sound. You could make it more realistic by hiding another image under the “covers” and then allow the mouse click to “lift” the selected cover off.
More About Bitmaps
You can’t drag a bitmap to the Graphics window in a procedure, but you
can put one there with the LOADSNAP
command. It needs the path name to the bitmap image file as input. It
outputs the value of the NAME
property of the bitmap’s property list.
This name is always in the format of BITMAP.n
, where n begins with the
number 1 and is incremented for each additional bitmap that you load. If
you erase a bitmap, then the next bitmap loaded will get the name of the
one you just erased. It’s similar to how the turtle names work. Type:
CS SETTURTLES 1
LOADSNAP "~HOME/TOOLBOX/ANIMALS/ELEPHANT
Result: BITMAP.1
The image of an elephant is loaded to the Graphics window from the Animals folder of the Toolbox folder which is in Logo’s home directory (that’s a tilde character in front of the word HOME). You can read more about file names in the Reference Manual in Chapter 2 - Logo Environment in the section titled File Name Conventions.
Put the elephant at the home position. Type:
ASK "BITMAP.1 [HOME]
The poor turtle is under the elephant now because the new bitmap is loaded to layer 0. Change things around by putting the turtle back on layer 0. Type:
LAYER. 0 0
You can create a bitmap object of your own with the
SNAP command (think of it as taking a
snapshot). It needs two numbers as input: the width and height that
define the area above and to the right of the turtle’s position. The
output of SNAP is the same as
LOADSNAP - the value of the NAME
property of the bitmap’s property list. Type:
SNAP 100 100
Result: BITMAP.2
You won’t see your bitmap until you set its WINDOW
property to the
name of the Graphics window (which just happens to be the word
GRAPHICS
). Type:
PPROP "BITMAP.2 "WINDOW "GRAPHICS
The turtle disappeared along with a chunk of elephant! What’s going on
here? Your new bitmap is on the top layer of the Graphics window. It’s a
solid block of white but the TRANSPARENT
property is set to black by
default. Put the turtle back on top. Type:
LAYER. 0 0
Even though the elephant was under the turtle when you did
SNAP, there was nothing on the drawing layer
except the white background color. What do you think will happen to a
solid block of white if you change the TRANSPARENT
property to
[255 255 255]
? Type:
PPROP "BITMAP.2 "TRANSPARENT [255 255 255]
Your bitmap is still there, but you can’t see it. You can’t even click on it because there is nothing for Logo to find either - it can’t see the invisible (transparent) color. Type:
LAYERS?
BITMAP.1 2
BITMAP.2 1
TURTLE.0 0
A fun project is turning a bitmap into a puzzle. The MAKE.PUZZLE
procedure does just that. It may look very complicated, but give it a
try. You can make a puzzle of any bitmap image in the toolbox. Just give
MAKE.PUZZLE
the folder name, the file name and the number of pieces
you want in your puzzle. For example:
MAKE.PUZZLE "ANIMALS "ELEPHANT 8
If you want to use the images in the Other Pictures folder, you have to enter the folder name with a special format - using the vertical bar characters - that allows for the space between the words. For example:
MAKE.PUZZLE "|OTHER PICTURES| "EARTH 9
The background color, while stamping, is set to silver so the pieces are
easier to line up. The CS
command at the beginning makes sure that the
new bitmap will get the name BITMAP.1
. The position for stamping the
image may seem tricky, but it puts the upper-right corner of the bitmap
image at [0 0]. Since each file is different, a fixed location for
stamping did not seem to be a good choice. The
FOR command runs SNAP
as many times as the pieces you request. Each puzzle piece is a vertical
slice that is defined by the height of the bitmap and the width divided
by the number of pieces you specify. Don’t get too carried away - an
image of 100 slices is almost impossible to put back together. The
WORD command uses four inputs to build the
full path name to the bitmap image. The parentheses are required to
force it to use more than the normal two inputs. To save MAKE.PUZZLE
and its helper procedures, type:
SAVE "MAKEPUZZLE
TO MAKE.PUZZLE FOLDER PICTURE PIECES
SETTURTLES 1 TELL 0 CS HT SETH 90 PU SETBG "SILVER
IGNORE LOADSNAP (WORD "|~HOME/TOOLBOX/| FOLDER "|/| PICTURE)
ASK "BITMAP.1 [HT]
SETXY GPROP "BITMAP.1 "SIZE
SETX -1 * XCOR SETY -1 * YCOR
(STAMP "BITMAP.1)
FOR "I 1 PIECES [
IGNORE SNAP SLICE.WIDTH PIECES SLICE.HEIGHT
FD SLICE.WIDTH PIECES
]
CLEAN ERASE "BITMAP.1
TELL EVERY "BITMAP
EACH [PPROP WHO "WINDOW "GRAPHICS]
EACH [SETH 90 FD RANDOM 150]
END
TO SLICE.WIDTH PIRCES
OUTPUT (FIRST GPROP "BITMAP.1 "SIZE) / PIECES
END
TO SLICE.HEIGHT
OUTPUT LAST GPROP "BITMAP.1 "SIZE
END
Animation with Bitmaps
Bitmap objects and turtles work well together. Although bitmap objects can’t draw or stamp, they are much more colorful than turtles. Of course, sometimes you don’t need a lot of color to make an interesting animation. Type:
CS SETTURTLES 1
Drag out the Bee image from the Animals panel of the Toolbox and place it to the right of the turtle. Logo displays the message:
BEE dropped.
Right-click (on a PC) or Ctrl-click (on a Mac) with the mouse pointer on
the bee to display the bee’s properties. Make the bee half-size - either
click the Scale slider to read .50 or change the SIZE
property to
read 45 51.
Any bitmap object in your workspace can be used as a turtle shape. Type:
SETSHAPE "BEE LOCKSHAPE SETPC "SILVER PENUP
Normally, the SETSHAPE command looks in
the Shapes panel for turtle shapes. However, it knows that the
silhouette of a bitmap object works fine, too. With the SILVER
color,
doesn’t the turtle bee look like a shadow? Your shadow follows you
everywhere, so make the turtle shadow follow the bee. Define the
SHADOW
procedure and then type:
TO SHADOW
ASK 0 [SETXY LIST (ASK "BEE [XCOR]) - 25 (ASK "BEE [YCOR]) - 25]
END
LAUNCH [SHADOW]
The turtle shadow will stay with the bee wherever it goes. Drag the bee to the center of the Graphics window and then type:
TELL "BEE SETHEADING 90 SETVELOCITY 20
Now, drag out two roses from the Plants panel of the Toolbox. Place one to the left and one to the right of the center of the Graphics window. As the bee and its shadow move across the screen, they fly behind the roses because, as each rose was dropped, it was placed on layer 0. You can make the bee fly in front of the roses by putting the bee on the top layer. Type:
INFRONT "BEE
If you play a waveform sound file, the automatic movement is suspended
while the sound plays. When the sound is done, the images “jump” to
where they would have been if the sound had not played. With a little
planning for sound, it’s not really a problem. Define the BUZZ
procedure. It stops the bee, plays the WASP
waveform sound file, and
then starts the bee moving again. You don’t have to worry about the
shadow because it’s following the bee’s every move. When the bee is over
a rose, type:
BUZZ
Drag out more flowers and make a garden scene. Play another kind of
“target” game with the bee. See if you can direct it to a particular
flower and then BUZZ
when it gets there. Try command lines like this:
LT 45 WAIT 2000 RT 45 BUZZ
If you make a typing error, the SHADOW
procedure will stop the turtle
shadow, but the bee will keep moving. You don’t need a shadow to play
the target game, but if you want it back, just type LAUNCH [SHADOW]
again.
To save your workspace, type:
SAVE "SHADOW
Circling the Globe
Animation is an illusion - your eyes see one thing but your brain sees something else. Type:
CS SETTURTLES 1 ERASE 0
Drag out one Earth image from the Other Pictures panel of the Toolbox and drop it. Then type:
ASK "EARTH [HOME]
Now, drag out one football (soccer ball?) image and drop it next to the Earth. Type:
TELL "FOOTBALL SETXY [150 0] SETH 270 SLOWTURTLE
The FOOTBALL
is on the top layer and it’s the active bitmap (listening
to your commands). Type:
FD 300 BK 300
Pretending that the football is really the moon, shouldn’t it go “around” the Earth instead of just back and forth? Type:
FD 300 INBACK "FOOTBALL BK 300
Of course, after this command has been run, the football is on the bottom layer! You need to alternate between being in front of the Earth with being in back of it. Type:
INFRONT "FOOTBALL FD 300 INBACK "FOOTBALL BK 300
The illusion of orbiting is quite real, but the football is still just going back and forth. Drag the Earth out of the way to convince yourself.
Try using SETVELOCITY to move the
football. You’ll have to play around with the timing of the orbit. Try
the following commands. The name of the football is changed to MOON
-
that requires another TELL command to let
Logo know who it’s talking to. The ALIAS
commands are just a convenience - no one wants to type too much.
PPROP "FOOTBALL "NAME "MOON
TELL "MOON
ALIAS "SETVELOCITY "V
ALIAS "INFRONT "F
ALIAS "INBACK "B
F "MOON V 40 WAIT 4000 B "MOON V -40 WAIT 4000 V 0