9  Friday Morning: Games

See ’net, HtDP+

9.1  Goal

to understand the world of reactive programming in the draw.ss teachpack

9.2  Calling Functions on Events


World

A World is a collection of things, which can also be displayed on a canvas. Usually we represent a world as struct.


Show and tell: (start Number Number)

Display the canvas for the world.


(big-bang Number World)

The function big-bang “creates” the world. The number tells it how fast to tick the real clock; the given world is the first world. Every tick of the clock can update the world.


tick, (on-tick-event tock)

DrScheme calls the function tock for every tick of the clock.


click, (on-key-event react)

DrScheme calls the function react for every key stroke on the keyboard.


(draw (draw-solid-rect (make-posn 0 0)
                       100 100
                       'blue)
      produce 
      1)

draw something, then return a value (note: produce is a new keyword)

9.3  Example: Flying a Rocket

Rockets:

(define RKT-WD 3)
(define RKT-HT 8)
(define RKT-X 16)
(define FLM 20)

;;  N  →  Number
;; the height of the rocket at t
(define (rocket-y t) (- HEIGHT (* 1/2 G (sqr t))))

;;  N  →  true
;; draw a rocket 
(define (rocket-draw t)
  (local ((define y (rocket-y t)))
    (and
     (draw-solid-rect (make-posn RKT-X y) RKT-WD RKT-HT 'blue)
     (draw-solid-rect
       (make-posn RKT-X (+ y RKT-HT)) RKT-WD FLM 'red))))

World is: a natural number (time in ticks)

(define G 3)
(define WIDTH 100)
(define HEIGHT 300)

;; World  →  true
(define (world-draw w) (rocket-draw w))

;; World  →  true
(define (world-clear w) 
  (draw-solid-rect (make-posn 0 0) WIDTH HEIGHT 'white))

;; World  →  World
;; erase old world, draw new one, return new one 
(define (tock w)
  (local ((define new-w (+ w 1)))
    (draw (world-clear w) (world-draw w) produce new-w)))

Run, program run!

(start WIDTH HEIGHT) ;; show the canvas
(big-bang .2 0) ;; create the world, start the clock
(on-tick-event tock)

9.4  The Nature of Keystroke Events

Data definition:

;; The KeyEvent is one of: 
;; --- Character 
;; --- Symbol
;; Interpretation: a character denotes an ordinary alpha-numeric key
;; a symbol denotes arrow keys ('left, 'right, 'up, 'down) or other events.  

Data examples: #\a, #\-, 'up

Template:

;; KeyEvent  →  ???
(define (process-event ke)
  (cond
    [(char? ke) ...]
    [(symbol? ke) ...]))

Example:

(define-struct kc (l r u d))
;; Kc = (make-kc N N N N)

;; KeyEvent Kc  →  Kc
;; add 1 to the appropriate part of ct
(define (arrow-key-counting ke ct)
  (cond
    [(char? ke) ct]
    [(symbol? ke) 
     (cond
       [(symbol=? 'left ke)
	(make-kc (+ (kc-l ct) 1) (kc-r ct) (kc-u ct) (kc-d ct))]
       [(symbol=? 'right ke)
	(make-kc (kc-l ct) (+ (kc-r ct) 1) (kc-u ct) (kc-d ct))]	
       [(symbol=? 'down ke)
	(make-kc (kc-l ct) (kc-r ct) (+ (kc-u ct) 1) (kc-d ct))]	
       [(symbol=? 'up ke)
	(make-kc (kc-l ct) (kc-r ct) (kc-u ct) (+ (kc-d ct) 1))]
       [else ct])]))

;; test:
(equal? (arrow-key-counting 'left (make-kc 1 0 2 9))
        (make-kc 2 0 2 9))