为什么Racket的big-bang框架将#<void>而非状态传入处理函数?
问题原因说明
核心触发逻辑
- Racket的
2htdp/universe模块的big-bang框架有强制约定:所有注册的事件回调函数(on-tick、on-key、on-mouse等绑定的处理函数)必须返回新的世界状态值,返回值会直接覆盖当前的世界状态,供后续所有回调、渲染、终止判断逻辑使用。 - 你编写的
set-delta按键处理函数仅执行了set! DX (+ DX 10)修改全局变量的操作,Racket中set!赋值语句的返回值为#<void>空值,你没有显式返回状态值,触发按键后#<void>就被设置为了新的世界状态。 - 后续
stop-when绑定的state-is-500函数收到#<void>作为入参,和数字做>=比较时触发了类型不匹配的契约错误。
修复方案
最简单的修复是在set-delta函数末尾显式返回当前的Y轴状态值即可:
(define (set-delta current-state key) (set! DX (+ DX 10)) current-state)
如果要实现左右方向键分别控制左右移动,可以补充按键判断逻辑:
(define (set-delta current-state key) (cond [(key=? key "left") (set! DX (- DX 10))] [(key=? key "right") (set! DX (+ DX 10))]) current-state)
内容的提问来源于stack exchange,提问作者Avrohom Yisroel
相关产品推荐
相关产品推荐

