首先你需要了解这个主循环中的世界是如何被处理的:
- 系统采用 big-bang-100 的第一个参数,并将其记住为WorldState。
- 然后它将它传递给 on-tick ( sub1 ) 函数,前提是它存在于每个滴答上。
- 当按键被按下时,它会调用 on-key ( change ) 并将woldState作为 aw 参数传递到那里。
- 在那里你画一些图片并在按下箭头键的情况下返回它。所以当一个箭头被按下时,它会返回ball-image的结果 = place-image的结果- image
- 系统将其记住为当前的worldState,并在下一个滴答声中将新值传递给旧过程:sub1。
- 由于该值现在是image,因此sub1拒绝它。
--
如果要在两个方向上移动球,则必须存储至少两个坐标 (x . y)。所以现在让WorldState成为两个数字的对。我们不需要即时功能,因为它本身没有任何变化。此外,我们不需要在键盘处理器中绘制球,所以让我们简单地更改对 ( worldState ) 中的相应值,并仅在将球放入新位置的调用 ( ball-image ) 期间绘制它 (请记住,x = (car t)、y = (cdr t) 和 (x . y) = (cons xy)):
(require 2htdp/image)
(require 2htdp/universe)
(define (ball-image t) ;<-- the t-parameter is our WorldState
(place-image (circle 10 "solid" "red")
(car t) ;<-- here now x variable coordinate
(cdr t) ;<-- here now y variable, instead of 150
(empty-scene 300 300)))
(define (change w a-key)
(cond ;w - is the previous worldState, V here we change it
[(key=? a-key "left") (cons (sub1 (car w)) (cdr w))];and
[(key=? a-key "right") (cons (add1 (car w)) (cdr w))];return
[(= (string-length a-key) 1) w] ;<-- this line is excess
[(key=? a-key "up") (cons (car w) (sub1 (cdr w)))]
[(key=? a-key "down") (cons (car w) (add1 (cdr w)))]
[else w])) ;<-- If the key of no interest, just
return the previous WorldState
(big-bang '(150 . 150) ;<-- initial state
(to-draw ball-image) ;<-- redraws the world
(on-key change)) ;<-- process the event of key press