Scripting (Animation) FAQ

Notes: You will need to set the language level to Pretty Big.

In this assignment, you will use macros to implement a scripting language for animations. For example, consider the following program:

  (400 400) ; width and height of window, in pixels
  ([x 100] [y 100]) ; initial values of animation parameters
    (make-posn x y) 50 50 "blue") ; draw a blue 50x50 rectangle at (x, y)
    5.0          ; over 5 seconds,
    [x -> 300]   ; smoothly change x to 300
    [y -> 200])) ; and y to 200 (the position of the rectangle changes accordingly)

If we run this program, we should see a blue rectangle move across the screen for 5 seconds. In general, an animation expression has the following form:

  (width height)
  ([var init] ...)
  motion-command ...)

The drawing command is constructed from the following:

Note that the color arguments are optional and default to "black". Also, note that using the solid- procedures causes the shapes to be filled in (otherwise, only outlines are drawn). The draw-multiple procedure combines any number of simpler drawing commands into a single command. This is necessary since the animation construct takes only a single drawing command.

Each motion command has the following form:

(motion duration
  [var -> value]

The duration can be an arbitrary expression, so long as it reduces to a number, which is interpreted as a time in seconds. Over this duration, each variable's value should change smoothly (linearly) from its current value to the new value. The window should update frequently (approximately 30 times per second) to show the changing sizes, positions, and colors of shapes that depend on the variables. Your program should approximate the duration as closely as possible, without falling short (i.e., in general you should exceed the specified time, though by as little as possible). Note that a duration of 0 (or less) is legal, in which case the variables should change immediately. Likewise, a motion command with no [var -> value] clauses should pause for the given duration without changing any variables.

Larger Example

The following example is more complicated. It consists of a small red octogon inside of a large blue hexagon. They move across the window together, rotating in opposite directions:

(define (reg-poly radius sides rotation)
    (lambda (i)
      (make-posn (* radius (cos (+ rotation (/ (* 2 pi i) sides))))
                 (* radius (sin (+ rotation (/ (* 2 pi i) sides))))))))

  (400 400)
  ([a 0] [b 100])
    (polygon (reg-poly 100 6 a) (make-posn b 200) "blue")
    (polygon (reg-poly 50 8 (- a)) (make-posn b 200) "red"))
    [a -> (* 4 pi)]
    [b -> 300]))

Here are a few screenshots:



Nothing yet.