-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcode
More file actions
236 lines (217 loc) · 11.1 KB
/
Copy pathcode
File metadata and controls
236 lines (217 loc) · 11.1 KB
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
;Program: Aliens Attack v5
(define (main a-name)
(big-bang INIT-WORLD ;init world
(on-draw draw-world) ;DONE
(on-key process-key) ;DONE
(on-tick create-new-world) ;DONE
(stop-when game-over? last-message)
(name a-name)))
; CONSTANTS
(define WIDTH 800)
(define HEIGHT 500)
(define ROCKET-IMG (scale .5 .)) ; our playermodel
(define E-SCENE (empty-scene WIDTH HEIGHT)) ;our scene, define in dimensions of W/H
(define ROCKET-Y (- HEIGHT (/ (image-height ROCKET-IMG) 2))) ;god knows
(define ROCKET-DELTA-X 5) ;the increment of movement for our rocket left/right
(define ALIEN (make-posn (/ WIDTH 2) (/ HEIGHT 2)))
(define ALIEN-DELTA-X 4)
(define ALIEN-DELTA-Y 8)
(define ALIEN-IMG (scale .20 .))
(define RIGHT-EDGE (- (sub1 WIDTH) (/ (image-width ROCKET-IMG) 2)))
(define LEFT-EDGE (/ (image-width ROCKET-IMG) 2))
(define ALIEN-WIDTH (image-width ALIEN-IMG))
(define ALIEN-HEIGHT (image-height ALIEN-IMG))
(define SHOT-START-Y (- (sub1 HEIGHT) (image-height ROCKET-IMG)))
(define SHOT-IMG (circle 3 "solid" "green"))
(define win-msg (text "The Earth was saved!" 24 "green"))
(define lose-msg (text "The Earth was subjugated!" 24 "red"))
(define ROCKET (/ WIDTH 2))
(define SHOT-DELTA-Y 3)
;Define init-aliens without typing each one
(define INIT-ALIENS ;3 rows of aliens with 9 aliens per row
(build-list 27 (lambda (n) (make-posn (local [(define rem (remainder n 9))]
(cond [(= rem 0) (- (/ WIDTH 2) 300)]
[(= rem 1) (- (/ WIDTH 2) 225)]
[(= rem 2) (- (/ WIDTH 2) 150)]
[(= rem 3) (- (/ WIDTH 2) 75)]
[(= rem 4) (/ WIDTH 2)]
[(= rem 5) (+ (/ WIDTH 2) 75)]
[(= rem 6) (+ (/ WIDTH 2) 150)]
[(= rem 7) (+ (/ WIDTH 2) 225)]
[else (+ (/ WIDTH 2) 300)]))
(local [(define quot (quotient n 9))]
(cond [(= quot 0) 50]
[(= quot 1) 125]
[else 200]))))))
(define (game-over? a-world)
(= 10 (length (world-shots a-world))))
;(define (game-over? a-world)
; (ormap (lambda (x) (first x)) (for/list ([alien (world-aliens a-world)])
; (list (cond [(>= (posn-y alien) (- (sub1 HEIGHT) (/ (image-height ALIEN-IMG) 2))) #true]
; [else #false])))))
;(check-expect (game-over? INIT-WORLD) false)
;(check-expect (game-over? (make-world ROCKET (list (make-posn 50 HEIGHT)) "down" '())) true)
;(check-expect (game-over? (make-world ROCKET (list (make-posn 50 (- 1 HEIGHT))) "down" (make-posn 2 2))) false)
;(define (game-over? a-world)
; (local [
; (define (alien-reached-earth? an-alien)
; (>= (posn-y an-alien) (- (sub1 HEIGHT) (/ (image-height ALIEN-IMG) 2))))
; (define (any-alien-reached-earth? loa)
; (cond [(empty? loa) #false]
; [else
; (cond [(alien-reached-earth? (first loa)) #true]
; [else (any-alien-reached-earth? (rest loa))])]))]
;(or (empty? (world-aliens a-world)) (any-alien-reached-earth? (world-aliens a-world)))))
(define (last-message a-world)
(cond [(empty? (world-aliens a-world)) (place-image win-msg (/ WIDTH 2) (/ HEIGHT 2) E-SCENE)]
[else (place-image lose-msg (/ WIDTH 2) (/ HEIGHT 2) E-SCENE)]))
(define-struct world (rocket aliens dir shots))
(define INIT-WORLD (make-world ROCKET INIT-ALIENS "right" '()))
;SCRIVE MONDO
;draw-world: world --> scene
(define (draw-world w)
(local [;draw-world: world --> scene
(define (draw-world w) (draw-shots (world-shots w) (draw-loa (world-aliens w) (draw-rocket (world-rocket w) E-SCENE))))
;draw-shots: los --> scene
(define (draw-shots a-los scn)
(local [ ;draw-shot: shot scene --> scene
(define (draw-shot a-shot scn) (place-image SHOT-IMG (posn-x a-shot) (posn-y a-shot) scn))]
(foldl (lambda (a-shot a-scene) (draw-shot a-shot a-scene)) scn a-los)))
;draw-loa: loa scene --> scene
(define (draw-loa a-loa scn)
(local [;draw-alien: alien scene --> scene
(define (draw-alien a scn)
(place-image ALIEN-IMG (posn-x a) (posn-y a) scn))]
(foldl (lambda (an-alien a-scene) (draw-alien an-alien a-scene)) scn a-loa)))
;draw-rocket: rocket scene --> scene
(define (draw-rocket a-rocket scn) (place-image ROCKET-IMG a-rocket ROCKET-Y scn))
]
(draw-world w)))
;PROCESSA TASTO
;process-key: a-world + a-key --> a-world
;purpose: manages keyboard interactions with the game world.
(define (process-key a-world a-key)
(local [
;compute-shot: los + world -> shots
;purpose: adds a shot to the list of shots on key-stroke
(define (compute-shot shots world)
(cons (make-posn (world-rocket a-world) SHOT-START-Y) (world-shots a-world)))
; move-rocket: rocket string -> rocket
; Purpose: to move the rocketi n the given direction
(define (move-rocket a-rocket direction)
(cond [(and (string=? direction "right")
(<= (+ a-rocket ROCKET-DELTA-X) (sub1 WIDTH)) (< (+ a-rocket ROCKET-DELTA-X) (- WIDTH (/ (image-width ROCKET-IMG) 2))))
(+ a-rocket ROCKET-DELTA-X)]
[(and (string=? direction "left")
(>= (- a-rocket ROCKET-DELTA-X) 0) (> (- a-rocket ROCKET-DELTA-X) (/ (image-width ROCKET-IMG) 2)))
(- a-rocket ROCKET-DELTA-X)]
[else a-rocket]))
]
(match a-key
[(or "left" "right") (make-world (move-rocket (world-rocket a-world) a-key)
(world-aliens a-world)
(world-dir a-world)
(world-shots a-world))]
["up" (make-world (world-rocket a-world)
(world-aliens a-world)
(world-dir a-world)
(compute-shot (world-shots a-world) (world-rocket a-world)))])))
;CREARE NUOVO MONDO
(define (create-new-world w)
(local [
;ALIEN (LOA) FUNCTIONS
;move-loa: loa direction --> loa
;purpose: moves the aliens in the given loa in the given direction
(define (move-loa a-loa dir)
(local [;move-alien: alien dir --> alien
;purpose: moves the given alien in the given direction
(define (move-alien a d)
(match d ["right" (move-posn a ALIEN-DELTA-X 0)]
["left" (move-posn a (* -1 ALIEN-DELTA-X) 0)]
["down" (move-posn a 0 ALIEN-DELTA-Y)]))
;move-posn: posn number number --> posn
;purpose: moves the given posn by the given amounts on x and y
(define (move-posn p xdelta ydelta)
(match p [(posn x y) (make-posn (+ x xdelta) (+ y ydelta))]))]
(for/list ([a a-loa])
(move-alien a dir))))
;------------------------------------------------------------------------------------------------------------
;DIR FUNCTIONS
;any-alien-at-right-edge?: loa-->boolean
;Purpose: determines if any alien in the given loa is at the right edge
(define (any-alien-at-right-edge? a-loa)
(cond[(empty? a-loa) false]
[else (or (alien-at-right-edge? (first a-loa))
(any-alien-at-right-edge? (rest a-loa)))]))
;any-alien-at-left-edge?: loa-> boolean
;Purpose: determines if any alien in the given loa is at the left edge
(define (any-alien-at-left-edge? a-loa)
(cond[(empty? a-loa) false]
[else (or (alien-at-left-edge? (first a-loa))
(any-alien-at-left-edge? (rest a-loa)))]))
;alien-at-right-edge?: alien -> boolean.
;purpose: Sees if the alien has approached the right edge of the scene
(define (alien-at-right-edge? alien)
(>= (+ (posn-x alien) ALIEN-DELTA-X) RIGHT-EDGE))
;alien-at-left-edge?: alien --> boolean
;purpose: sees if the alien has approached the left edge of the scene
(define (alien-at-left-edge? alien)
(<= (- (posn-x alien) ALIEN-DELTA-X) LEFT-EDGE))
;compute new direction: loa direction --> direction
;purpose: to determine the new direction of the given alien using its old direction.
(define (compute-new-direction loa dir)
(cond [(or (and (string=? dir "right") (any-alien-at-right-edge? loa))
(and (string=? dir "left") (any-alien-at-left-edge? loa)))
"down"]
[(and (string=? dir "down") (any-alien-at-right-edge? loa)) "left"]
[(and (string=? dir "down") (any-alien-at-left-edge? loa)) "right"]
[else dir]))
;-------------------------------------------------------------------------------------
;move-los: a-los -> a-los
;purpose: moves the list of shots up and removes out of bounds shots.
(define (move-los a-los)
(local [
;move-shot: shot -> shot
;purpose: moves a shot up
(define (move-shot a-shot)
(cond [(< (- (posn-y a-shot) SHOT-DELTA-Y) 0) (remove a-shot a-los)]
[else (move-posn a-shot 0 (* -1 SHOT-DELTA-Y))]))
(define (move-posn p xdelta ydelta)
(make-posn (+ (posn-x p) xdelta) (+ (posn-y p) ydelta)))
]
(for/list ([shot a-los])
(move-shot shot))))
;----------------------------------------------------------------------------------------
;alien-hit?: alien + shot --> boolean
;purpose: determines if a shot hits an alien.
(define (alien-hit? an-alien a-shot)
(and
(<= (abs (- (posn-x a-shot) (posn-x an-alien))) (/ ALIEN-WIDTH 2))
(<= (abs (- (posn-y a-shot) (posn-y an-alien))) (/ ALIEN-HEIGHT 2))))
;remove-hit-aliens: loa + los --> loa
;purpose: removes aliens hit by shots during the game.
(define (remove-hit-aliens loa los)
(cond [(empty? los) loa]
[else
(for*/list ([aliens loa]
[shots los])
(cond [(alien-hit? aliens shots) (remove aliens loa)]
[else loa]))]))
;remove-hit-shots: loa + los --> los
;purpose: removes shots that hit aliens during the game.
(define (remove-hit-shots loa los)
(cond [(empty? los) los]
[else
(for*/list ([aliens loa]
[shots los])
(cond [(alien-hit? aliens shots) (remove shots los)]
[else loa]))]))
;----------------------------------------------------------------------------------------
]
(make-world (world-rocket w)
(remove-hit-aliens (move-loa (world-aliens w) (world-dir w))
(move-los (world-shots w)))
(compute-new-direction (move-loa (world-aliens w) (world-dir w))
(world-dir w))
(remove-hit-shots (move-loa (world-aliens w) (world-dir w))
(move-los (world-shots w))))))