1.2 Simulations and Animations: world.ss
The teachpack provides two sets of tools. The first allows students to create and display a series of animated scenes, i.e., a simulation. The second one generalizes the first by adding interactive GUI features.
1.2.1 Basics
The teachpack assumes working knowledge of the basic image manipulation primitives and introduces a special kind of image: a scene.
(lambda (i) |
The teachpack can display only Scenes, which are images whose pinholes are at position (0 ,0).
(empty-scene width height) → Scene |
width : natural-number/c |
height : natural-number/c |
{Creates a width x height Scene.}
(place-image img x y s) → Scene |
img : image? |
x : number? |
y : number? |
s : Scene |
{Creates a scene by placing img at (x ,y) into s; (x ,y) are comp. graph. coordinates, i.e., they count left and down from the upper-left corner.}
1.2.2 Simple Simulations
(run-simulation w h r create-image [gifs?]) → true |
w : natural-number/c |
h : natural-number/c |
r : number? |
create-image : (-> natural-number/c scene) |
gifs? : boolean? = #f |
creates and shows a canvas of width w and height h , starts a clock, making it tick every r (usually fractional) seconds. Every time the clock ticks, drscheme applies create-image to the number of ticks passed since this function call. The results of these applications are displayed in the canvas.
The fifth (and last) argument is optional. Providing true as the fifth argument causes drscheme to collect the scenes that the animation generates and to create an animated GIF from the results. Both the intermediate images as well as the final animated GIF are saved in a user-specified directory. This is useful for writing documentation and for describing students work.
In addition,
(define (create-UFO-scene height) |
(place-image UFO 50 height (empty-scene 100 100))) |
|
(define UFO |
(rectangle 40 4 'solid 'green))) |
|
(run-simulation 100 100 (/ 1 28) create-UFO-scene) |
1.2.3 Interactions
An animation starts from a given “world” and generates new ones in response to events on the computer. This teachpack keeps track of the “current world” and recognizes three kinds of events: clock ticks; keyboard presses and releases; and mouse movements, mouse clicks, etc. Your program may deal with such events via the installation of handlers. The teachpack provides for the installation of three event handlers: on-tick-event, on-key-event, and on-mouse-event. In addition, it provides for the installation of a draw handler, which is called every time your program should visualize the current world.
World any/c
For animated worlds and games, using the teachpack requires that you provide a data definition for World. In principle, there are no constraints on this data definition. You can even keep it implicit, even if this violates the Design Recipe.
width : natural-number/c |
height : natural-number/c |
r : number? |
world0 : World |
width : natural-number/c |
height : natural-number/c |
r : number? |
world0 : World |
animated-gif? : boolean? |
Creates and displays a width x height canvas, starts the clock, makes it tick every n seconds, and makes w the current world. If it is called with five instead of four arguments and the last one (animated-gif?) is true, the teachpack allows the generation of images from the animation, including an animated GIF image.
(on-tick-event tock) → true |
Tell DrScheme to call tock on the current world every time the clock ticks. The result of the call becomes the current world.
A KeyEvent represents key board events, e.g., keys pressed or released, by the computer’s user. A char? KeyEvent is used to signal that the user has hit an alphanumeric key. Symbols such as 'left, 'right, 'up, 'down, 'release denote arrow keys or special events, such as releasing the key on the keypad.
(on-key-event change) → true |
Tell DrScheme to call change on the current world and a KeyEvent for every keystroke the user of the computer makes. The result of the call becomes the current world.
Here is a typical key-event handler:
(define (change w a-key-event) |
(cond |
[(char? a-key-event) w] |
; else (symbol? a-key-event) holds |
[(symbol=? a-key-event 'left) (world-go w -DELTA)] |
[(symbol=? a-key-event 'right) (world-go w +DELTA)] |
[(symbol=? a-key-event 'up) (world-go w -DELTA)] |
[(symbol=? a-key-event 'down) (world-go w +DELTA)] |
[else w])) |
MouseEvent (one-of/c 'button-down 'button-up 'drag 'move 'enter 'leave)
A MouseEvent represents mouse events, e.g., mouse movements or mouse clicks, by the computer’s user.
(on-mouse-event clack) → true |
clack : (-> World natural-number/c natural-number/c MouseEvent World) |
Tell DrScheme to call clack on the current world, the current x and y coordinates of the mouse, and and a MouseEvent for every action of the mouse by the user of the computer. The result of the call becomes the current world.
Tell DrScheme to call to-scene whenever the canvas must be redrawn. The canvas is usually re-drawn after a tick event, a keyboard event, or a mouse event has occurred. The generated scene is displayed in the world’s canvas.
Tell DrScheme to call last-world? whenever the canvas is drawn. If this call produces true, the clock is stopped; no more tick events, KeyEvents, or MouseEvents are forwarded to the respective handlers. As a result, the canvas isn’t updated either.
1.2.4 Scenes and Images
For the creation of scenes from the world, use the functions from Manipulating Images: image.ss. The following two functions have turned out to be useful for the creation of scenes, too.
(nw:rectangle width height solid-or-filled c) → image? |
width : natural-number/c |
height : natural-number/c |
solid-or-filled : Mode |
c : Color |
Creates a width x height rectangle, solid or outlined as specified by solid-or-filled and colored according to c, with a pinhole at the upper left corner.
(scene+line s x0 y0 x1 y1 c) → Scene |
s : Scene |
x0 : number? |
y0 : number? |
x1 : number? |
y1 : number? |
c : Color |
Creates a scene by placing a line of color c from (x0 ,y0) to (x1 ,y1) into scene; (x ,y) are comp. graph. coordinates; in contrast to the add-line function, this one cuts off those portions of the line that go beyond the boundaries of the given s.