Realm Of Racket - (big-bang)

(big-bang)

上一次的程序是命令行式的,这次写一些GUI(gooey)的程序
这次使用Racket里自带的2htdp/universe 2htdp/image

#lang racket
(require 2htdp/universe 2htdp/image)

(big-bang 0
	(on-tick add-3-to-state)
	(to-draw draw-a-ufo-onto-an-empty-scene))  
	

big-bang 创造了一个World, World是由状态和视图组成

(define (add-3-to-state current-state)
	(+ current-state 3))  
	

add–3-to-state 把当前状态+3,然后返回,big-bang会把add–3-to-state返回的值标记为下一个状态

(define (draw-a-ufo-onto-an-empty-scene current-state)
	(place-image IMAGE-of-UFO (/ WIDTH 2) current-state
		(empty-scene WIDTH HEIGHT)))  
		

draw-a-ufo-onto-an-empty-scene 把ufo的图片根据 current-state 绘制到特定位置
当图片落地时,动画得停下来

(define (state-is-300 current-state)
	(>= current-state 300))
	
(big-bang 0
	(on-tick add-3-to-state)
	(to-draw draw-a-ufo-onto-an-empty-scene)
	(stop-when state-is-300))
	

使用state-is–300和big-bang的stop-when来修改World的状态和视图

(big-bang state-expression
	(to-draw draw-function)
	(on-tick tick-function)
	(on-key key-function)
	(stop-when stop-function optional-last-scene))
	
	

big-bang大致长这样,state-expression是WOrld的初始状态,to-draw是把当前状态绘制到屏幕上,on-tick就是每tick调用的函数,on-key是当有输入操作,如键盘鼠标或者其他输入设备,调用的函数,在key-function里可以对状态进行修改,stop-when就是想让世界停下来的一个函数判断

该示例的完整源码在 {Racket的安装目录}/share/pkgs/realm/chapter5/ufo-source.rkt里

写一个GUI版本的猜数字游戏

好的数据结构会让程序有很大的不同

struct interval (small big))

代表猜数字的上下限

(define HELP-TEXT
	(text " for larger numbers, for smaller ones"
		TEXT-SIZE
		"blue"))
(define HELP-TEXT2
	(text "Press = when your number is guessed; q to quit."
		TEXT-SIZE
		"blue"))
(define COLOR "red")

游戏指令

(define MT-SC
	(place-image/align
		HELP-TEXT TEXT-X TEXT-UPPER-Y "left" "top"
		(place-image/align
			HELP-TEXT2 TEXT-X TEXT-LOWER-Y "left" "bottom"
			(empty-scene WIDTH HEIGHT))))
			

定义常量,作为游戏的背景

(define (start lower upper)
	(big-bang (interval lower upper)
		(on-key deal-with-guess)
		(to-draw render)
		(stop-when single? render-last-scene)))
		

这个可以作为Main函数

(define (deal-with-guess w key)
	(cond [(key=? key "up") (bigger w)]
		[(key=? key "down") (smaller w)]
		[(key=? key "q") (stop-with w)]
		[(key=? key "=") (stop-with w)]
		[else w]))  
		

deal-with-guess 根据不同的key返回不同的状态

(define (smaller w)
	(interval (interval-small w)
		(max (interval-small w) (sub1 (guess w)))))  
		
(define (bigger w)
	(interval (min (interval-big w) (add1 (guess w)))
		(interval-big w)))  
		

smaller和bigger都是创建了新的interval结构体

(define (guess w)
	(quotient (+ (interval-small w) (interval-big w)) 2))  
	

guess函数取结构的上下限,加起来然后/2

(define (render w)
	(overlay (text (number->string (guess w)) SIZE COLOR) MT-SC))  
	

render把猜的数字展示到MT-SC定义的背景上

(define (render-last-scene w)
	(overlay (text "End" SIZE COLOR) MT-SC))
	

当游戏结束调用的函数

(define (single? w)
	(= (interval-small w) (interval-big w)))  
	

single?比较上下限,决定是否结束游戏

猜数字的GUI版本的完整代码在 {Racket的安装目录}/share/pkgs/realm/chapter5/source.rkt