我正在使用大爆炸功能和四种结构在Racket中创建一个小游戏。我的结构如下:
(define-struct game_main (tank missile UFO))
(define-struct tank (x aim-x aim-y))
(define-struct missile (x y vel))
(define-struct UFO (x y))
(define a-game
(make-game_main
(make-tank 370 100 100)
(make-missile 500 500 1)
(make-UFO 100 100)))
当为大爆炸功能创建一个键事件处理程序时,我使用a来向左移动坦克的x位置,d将其向右移动,就像这样。包括大爆炸功能以供参考:
(define (controls a-game a-key)
(cond
[(key=? a-key "a")
(struct-copy game_main a-game [tank (make-tank (- (tank-x (game_main-tank a-game)) 7)
(tank-aim-x (game_main-tank a-game))
(tank-aim-y (game_main-tank a-game)))])]
[(key=? a-key "d")
(struct-copy game_main a-game [tank (make-tank (+ (tank-x (game_main-tank a-game)) 7)
(tank-aim-x (game_main-tank a-game))
(tank-aim-y (game_main-tank a-game)))])]
)
)
(big-bang a-game (to-draw game_init) (on-key controls))
这很有效;但是,它很冗长。我想定义一个函数,比如“move-tank-left”,它只包含世界状态转换器,但在事件处理程序之外定义。但是,它不是直接编辑由big-bang操纵的结构,而是返回到我的全局设置的游戏game_main结构并恢复它开始的x值。 如何引用当前的大爆炸功能世界状态,以便您可以在大爆炸功能之外建立将编辑临时状态的功能?
这是有问题的功能:
(define move-tank-left
(make-tank
(- (tank-x (game_main-tank a-game)) 5)
(tank-aim-x (game_main-tank a-game))
(tank-aim-y (game_main-tank a-game))))
答案 0 :(得分:3)
您无法引用当前“大爆炸”状态,因为它在big-bang
之外不存在。
(即使big-bang
也没有真正编辑当前状态 -
(struct-copy game_main a-game ...
不会修改a-game
参数,但会创建新状态。)
您可以从controls
函数传递整个游戏状态:
(define (controls a-game a-key)
(cond
[(key=? a-key "a")
(struct-copy game_main a-game [tank (move-tank-left a-game)])]
...
(define (move-tank-left game-state)
(make-tank
(- (tank-x (game_main-tank game-state)) 5)
(tank-aim-x (game_main-tank game-state))
(tank-aim-y (game_main-tank game-state))))
但只是在坦克周围传递产生的依赖性更少,让你更容易添加坦克:
(define (controls a-game a-key)
(cond
[(key=? a-key "a")
(struct-copy game_main
a-game
[tank (move-tank-left (game_main-tank a-game))])]
...
(define (move-tank-left tank)
(make-tank
(- (tank-x tank) 5)
(tank-aim-x tank)
(tank-aim-y tank)))