SB-world Teachpack
1 About this teachpack
The sb-world teachpack resembles the built-in world
teachpack, but is used in a more functional, less imperative way.
To wit, rather than calling big-bang to start an animation, and
then calling on-tick, on-mouse-event, etc. to
install its handlers, you’ll call run-animation with the handlers
as arguments.
2 Installation
If you’re reading this, you’ve probably already installed the teachpack successfully,
but if you need to install it on a different machine, ...
start DrScheme
switch languages to Module and click "Run"
in the Interactions pane, type
after a few seconds, you should see the message
"Wrote file "sb-world.ss" to installed-teachpacks directory."
switch languages back to one of the HtDP languages, like Beginning Student
from the Language menu, choose "Add Teachpack..." and select "sb-world.ss"
click "Run"
3 Data types and functions
model any/c
When you write an animation, one of your first decisions is usually
"what type is the model?" If you don’t choose a data definition for
model, it will default to "image", but this is rather limiting.
key-event or/c char? symbol?
Key presses are represented as either characters (for ordinary keys: letters, digits,
punctuation) or as symbols (for function keys, arrow keys, delete, page-up, page-down, etc.)
In addition, when a key is released, you get a 'release event, also a symbol.
The teachpack provides two useful functions for this data type: key-event?, which
tells whether something is a key-event, and key=?, which compares two
key events for equality.
(run-animation | | width | | | | | | | height | | | | | | | initial-model | | | | | | | tick-interval | | | | | | | handler1 ...) | | → | | true |
|
width : number? |
height : number? |
initial-model : model |
tick-interval : number? |
handler1 : handler? |
The most important function in the teachpack. You give it the width and
height that you want for the animation window, an initial model, how
many seconds between clock ticks, and possibly some "handlers" (see
below), and it will run an animation for you. For details, see Chapter
7 of my textbook.
(run-saveable-animation | | width | | | | | | | height | | | | | | | initial-model | | | | | | | tick-interval | | | | | | | handler1 ...) | | → | | true |
|
width : number? |
height : number? |
initial-model : model |
tick-interval : number? |
handler1 : handler? |
Just like "run-animation", except that it records the sequence of
events and, after it’s finished,
allows you to save it as an animated GIF picture.
Places the center of the foreground image at the specified location on the background
image, treating (0,0) as the top-left corner of the background.
Note: Unlike the version of "place-image" in the standard
world teachpack, this version accepts any image as the
background, regardless of pinholes.
An easy way to create a white box, outlined in black, of the specified
width and height, generally to use as a background image.
Stops the animation from which it was called, and returns the specified
value (usually a string, but could be an image, a number, etc.)
Note: This function should only be called from within a tick, mouse, or
key handler. If you call it from "run-animation", you’ve basically
stopped the animation before it can start.
(key=? event1 event2) → boolean? |
event1 : key-event? |
event2 : key-event? |
Compares two
key-events for equality; won’t crash even if one
happens to be a character and the other a symbol.
4 Handlers
handler
When you run an animation, you can provide handler functions to tell the
animation how to do various things: how to redraw the screen from the
model, how to change the model at every clock tick, how to change the
model when the user uses the mouse or keyboard, etc. Once you’ve written
a function to be used as a handler, you specify what kind of handler it
is by calling "on-redraw", "on-tick", "on-mouse",
"on-key", or "stop-when", and
passing the result to run-animation.
(on-redraw redraw-handler) → handler? |
redraw-handler : (-> model image) |
To specify how the animation is to be shown on the screen (and in
particular if your
model is anything other than an image), you
need to write a function from
model to image, and supply it as an
argument to
"on-redraw". This function will be called on the
current model every time the model changes, and the resulting image will
appear on the screen.
Note: If you don’t provide a redraw handler, the system will
assume that your
model is simply an image, and will show that
image itself in the animation window.
(on-tick tick-handler) → handler? |
tick-handler : (-> model model) |
If you want your animation to do something at regular time intervals,
you need to write a function from
model to
model, and
supply it as an argument to
"on-tick". Every time the clock
ticks, this function will be called on the current model, and its result
will become the new model.
If you want your animation to respond to the mouse, you need to write
a function that takes in a
model, two numbers, and a symbol, and
returns a
model, and provide this function as an argument to
"on-mouse". Every time the mouse is moved or clicked, your
function will be called on the current
model, the coordinates of
the mouse, and what was done to the mouse, and its result will be the
new
model.
Possible events are ’button-down, ’button-up, ’move, ’drag, ’wheel-up, ’wheel-down, ’enter, and ’leave.
If you want your animation to respond to the keyboard, you need to write
a function that takes in a
model and a
key-event
and returns a
model, and provide this function as an
argument to
"on-key". Every time a key is pressed or released on
the keyboard, your function will be called with the current model and
the relevant key (or the symbol
"'release"), and its result will
be used as the new model.
Possible keys, in addition to ordinary characters, are
’release,
’up,
’down,
’left,
’right,
’next,
’prior,
’home,
’numpad-enter,
’separator,
’f1,
’f2,
...
If you want your animation to stop when a particular thing happens, you
have two choices. One is to use
"end-of-time", as discussed
above. The other is to write a function from
model to boolean,
and provide this function as an argument to
"stop-when". This
function will be called on the current
model every time the
model changes; if it returns true, the animation will end.
Note: There should be no problem with using both features at once,
i.e. installing a
"stop-when" handler and also having some other
handler call
"end-of-time".