-
Notifications
You must be signed in to change notification settings - Fork 30
/
rain-world-program.rkt
131 lines (94 loc) · 3.19 KB
/
rain-world-program.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#lang planet dyoo/whalesong
(require (planet dyoo/whalesong/world)
(planet dyoo/whalesong/image)
(planet dyoo/whalesong/js))
;; Occupy the whole screen.
(void (call-method body "css" "margin" 0))
(void (call-method body "css" "padding" 0))
(void (call-method body "css" "overflow" "hidden"))
;; Rain falls down the screen.
(define GRAVITY-FACTOR 1)
(define-struct posn (x y))
;; A drop particle describes where it is on screen, what color it is, and
;; how large it is.
(define-struct drop (posn velocity color size))
;; random-drop-particle: drop
;; Generates a random particle.
(define (random-drop)
(make-drop (make-posn (random (viewport-width)) 0)
(+ 5 (random 10)) ;; Get it falling at some random velocity
(random-choice (list "gray" "darkgray"
"white" "blue"
"lightblue"
"darkblue"))
(random 10) ;; with some random size
))
;; random-choice: (listof X) -> X
;; Picks a random element of elts.
(define (random-choice elts)
(list-ref elts (random (length elts))))
;; The world consists of all of the drops in the sky.
(define-struct world (sky ;; listof drop
))
(define (my-filter f l)
(cond
[(null? l)
'()]
[(f (car l))
(cons (car l)
(my-filter f (cdr l)))]
[else
(my-filter f (cdr l))]))
;; tick: world -> world
(define (tick w)
(make-world
(my-filter not-on-floor?
(map drop-descend (cons (random-drop)
(cons (random-drop)
(world-sky w)))))))
;; drop-descend: drop -> drop
;; Makes the drops descend.
(define (drop-descend a-drop)
(cond
[(> (posn-y (drop-posn a-drop)) (viewport-height))
a-drop]
[else
(make-drop (posn-descend (drop-posn a-drop) (drop-velocity a-drop))
(+ GRAVITY-FACTOR (drop-velocity a-drop))
(drop-color a-drop)
(drop-size a-drop))]))
;; posn-descend: posn number -> posn
(define (posn-descend a-posn n)
(make-posn (posn-x a-posn)
(+ n (posn-y a-posn))))
;; on-floor?: drop -> boolean
;; Produces true if the drop has fallen to the floor.
(define (on-floor? a-drop)
(> (posn-y (drop-posn a-drop))
(viewport-height)))
(define (not-on-floor? a-drop) (not (on-floor? a-drop)))
;; make-drop-image: color number -> drop
;; Creates an image of the drop particle.
(define (make-drop-image color size)
(circle size "solid" color))
;; place-drop: drop scene -> scene
(define (place-drop a-drop a-scene)
(place-image (make-drop-image (drop-color a-drop)
(drop-size a-drop))
(posn-x (drop-posn a-drop))
(posn-y (drop-posn a-drop))
a-scene))
(define (my-foldl f acc lst)
(cond
[(null? lst)
acc]
[else
(my-foldl f
(f (car lst) acc)
(cdr lst))]))
;; draw: world -> scene
(define (draw w)
(my-foldl place-drop (empty-scene (viewport-width) (viewport-height)) (world-sky w)))
(big-bang (make-world '())
(to-draw draw)
(on-tick tick))