Please send questions to st10@humboldt.edu .

; DON'T TRY TO RUN THIS TEXT VERSION!
; ...it has a . where the bird image should be! 8-)


; CIS 130 - in-class examples - 2-8-10

; creating animated scenes...
;    an example of several functions and definitions working together
;    to achieve a desired end;

(define bird .)
bird

; the universe.ss teachpack has a way to create an
;   image called a scene;

; (looks a lot like a rectangle with its pinhole
;     at the top left...)

; to get an empty scene, use the empty-scene function

; contract: empty-scene: number number -> scene
; purpose: expects a desired scene width and height in
;   pixels, and its produces an instance of a scene
;   with that height and width

(empty-scene 300 200)

; to place an image into a scene, use the place-image
;    function:

; contract: place-image: image number number scene -> scene
; purpose: expects an image you want in a scene,
;          the x-coordinate where you want the image's center,
;          the y-coordinate where you want the image's center,
;          and the scene you want to put the image in,
;          and produces a scene with that image in that location

; BUT NOTE: in the universe.ss teachpack, (0, 0) is the TOP-LEFT
;    corner of a scene ---
; and as x gets BIGGER, you go to the RIGHT,
; and as y gets BIGGER, you go DOWN

(place-image bird 0 0 (empty-scene 300 200))
(place-image bird 150 100 (empty-scene 300 200))

; consider: a movie can be considered as a sequence
;    of images rapidly displayed in order

; ...and also consider:
; remember when you graphed functions in algebra:

; x = 1  2  3  4  5
; y = 1  4  9 16  ?

; you can tell that when x is 5,  y should be 25;
; ...and if you thought about this as saying,
; at time 1, draw a dot at (1, 1)
; at time 2, draw a dot at (2, 4)
; at time 3, draw a dot at (3, 9)
; ...you could imagine half a parabola being "drawn"

; and you don't want to compute all of these,
; you want an expression - hey! a function! -- that represents
; the entire sequence -- y = x * x

; or -- f(x) = x * x

; let's use the design recipe to quickly write this function:

; contract: square: number -> number
; purpose: it expects a number, and produces the square of that number

(check-expect (square 5) 25)
(check-expect (square 3) 9)

(define (square a-number)
  (* a-number a-number)
)

(square 123)

(place-image bird 150 0 (empty-scene 300 200))
(place-image bird 150 10 (empty-scene 300 200))
(place-image bird 150 20 (empty-scene 300 200))
(place-image bird 150 30 (empty-scene 300 200))

; if I produced a sequence of images such as the above,
;    the bird would appear to be moving downward;

; SO: all we need is a way to produce lots of these scenes
;    easily, and to display them all in rpaid order;

; for the FIRST part of that ... we need a function!

; a function that produces a scene of a bird at a given y-coordinate
;    in a scene;

; ; contract: create-bird-scene: number -> scene
; ; purpose: expects a y-coordinate for a scene, and
; ;   it produces a scene of a bird whose pinhole is
; ;   at the scene location (150, that y-coordinate)
; 
; (check-expect (create-bird-scene 30)
;               (place-image bird 150 30 (empty-scene 300 200)))
; (check-expect (create-bird-scene 100)
;               (place-image bird 150 100 (empty-scene 300 200)))
; 
; (define (create-bird-scene y-coord)
;   (place-image bird 150 y-coord (empty-scene 300 200))
; )
; 
; (create-bird-scene 100)
; (create-bird-scene 30)
; 
; ; now, the universe teachpack provides a function, animate,
; ;   which expects a function (that expects a number and produces
; ;   a scene), and has the major side-effect of opening
; ;   a CANVAS, and calling that function about 28 times a second
; ;   with 1, then 2, then 3, ...,
; ;   displaying the resulting scene on the canvas,
; ;   UNTIL you close the canvas;
; ;   then it produces the last number it called the function with;
; 
; (animate create-bird-scene)


; in extreme programming: there is a term, refactoring
;    that's when you improve your code,
;    to make it easier to read, or easier to modify,
;    or more elegant, etc.;
; (as opposed to DEBUGGING, which is when you are fixing
;     code that has some problem;)

; ; let's refactor this a little;
; 
; ; how about giving a name to the WIDTH and HEIGHT of this scene?
; ;   let's make them named constants;
; ;   (written in all-uppercase, as is a frequence style for named
; ;   constants)
; ;   (so they look different from, say, your parameters...)
; ;
; 
; ; see how this makes it easier to change the WIDTH and HEIGHT later,
; ;    as well as being to read...
; 
; (define WIDTH 300)
; (define HEIGHT 300)
; 
; ; I decide I'd like the bird to be in the "middle" of the scene,
; ;   x-coordinate-wise;
; 
; (define BIRD-X (/ WIDTH 2))
; 
; ; I'd like the bird to move through a scene with a sun
; ;    instead of blank white scene;
; ; ...I could define a "static" backdrop scene;
; 
; (define BACKDROP
;         (place-image (circle 20 "solid" "yellow")
;                      (- WIDTH 50)
;                      50
;                      (place-image 
;                          (nw:rectangle WIDTH HEIGHT "solid"
;                                        "blue")
;                          0
;                          0
;                          (empty-scene WIDTH HEIGHT))))
; 
; 
; ; contract: create-bird-scene: number -> scene
; ; purpose: expects a y-coordinate for a scene, and
; ;   it produces a scene of a bird whose pinhole is
; ;   at the scene location (150, that y-coordinate)
; 
; (check-expect (create-bird-scene 30)
;               (place-image bird BIRD-X 30 BACKDROP))
; (check-expect (create-bird-scene 100)
;               (place-image bird BIRD-X 100 BACKDROP))
; 
; (define (create-bird-scene y-coord)
;   (place-image bird BIRD-X y-coord BACKDROP)
; )
; 
; (create-bird-scene 100)
; (create-bird-scene 30)
; 
; (animate create-bird-scene)
; 


(define WIDTH 300)
(define HEIGHT 300)

; I decide I'd like the bird to be in the "middle" of the scene,
;   y-coordinate-wise;

(define BIRD-Y (/ HEIGHT 2))

(define BACKDROP
        (place-image (circle 20 "solid" "yellow")
                     (- WIDTH 50)
                     50
                     (place-image 
                         (nw:rectangle WIDTH HEIGHT "solid"
                                       "blue")
                         0
                         0
                         (empty-scene WIDTH HEIGHT))))


; modulo: is the REMAINDER from integer division

(modulo 15 7)

(modulo 157 100)  ; remainder is 57
(modulo 1034 100) ; remainder is 34
; ...remainder can NEVER exceed the divisor minus 1!

; so, (modulo anything WIDTH) can never get bigger than (- WIDTH 1)!
; and, (modulo anything HEIGHT) can never get bigger than (- HEIGHT 1)!
; ...what if I used that in my function?

; contract: create-bird-scene: number -> scene
; purpose: expects  the current clock-tick
;   of a time counter, that will be be used to determine both
;   the x AND y coordinate for a scene, and
;   it produces a scene of a bird whose pinhole is
;   at the scene location ((modulo time-counter WIDTH), 
;                          (modulo time-counter HEIGHT))

(check-expect (create-bird-scene 30)
              (place-image bird 30 30 BACKDROP))
(check-expect (create-bird-scene 100)
              (place-image bird 100 100 BACKDROP))
(check-expect (create-bird-scene 1034)
              (place-image bird 134 134 BACKDROP))

(define (create-bird-scene time-counter)
  (place-image bird (modulo time-counter WIDTH) 
                    (modulo time-counter HEIGHT)
                    BACKDROP)
)

(create-bird-scene 100)
(create-bird-scene 30)

(animate create-bird-scene)