-
Notifications
You must be signed in to change notification settings - Fork 39
/
Deep.fs
444 lines (390 loc) · 11.1 KB
/
Deep.fs
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
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
######################################################
##
## Deep:
##
## Yet another vaguely original game. Attempts to
## fuse together mechanics from Space Invaders and
## Missile Command in a nautically-themed
## depth-charge-'em-up.
##
## John Earnest
##
######################################################
:include <Grid.fs>
:include <Sprites.fs>
:include <String.fs>
:include <Util.fs>
:include <Math.fs>
:include "Entities.fs"
:image grid-tiles "deeptiles.png" 8 8
:image sprite-tiles "boat.png" 32 16
:image others "sprites.png" 16 16
:const clear-color 0xFF90C6C8
:array sprites 1024 0
:array bogus 4 0 # this is where 'bogus' entities will map
:data grid
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 -1
9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 9 -1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -1
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 -1
8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 -1
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 -1
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 -1
3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 -1
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 -1
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 -1
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 -1
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 -1
-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
:const player 0
:const light1 1
:const light2 2
:const bomb 8
:const explosion 12
:const bubbles 16
:const monsters 20
:const crab 24
:const player-gibs 28
:const blastradius 32
:const killradius 16
:var dropped
:var gameover
:var ended
:var direction
:var speed
:var score
######################################################
##
## A rolling waves animation
##
## Much of the rest of the game sort of crusted
## around the wave system as a global timer. hm.
##
######################################################
:data wave-tiles 1073741836 1073741837 1073741838 1073741839 1073741836 1073741837 1073741838 1073741839
:data wave-tiles2 9 9 11 11 9 9 11 11
:data wave-tiles3 10 10 8 8 8 8 10 10
:data wave-height 32 31 30 31 32 31 30 31
:var wave
:var wave-timer
: waves
wave-timer @ if wave-timer dec@ exit then
50 wave-timer ! wave @ 1 + 8 mod wave !
0 5 tile-grid@ 40 wave @ wave-tiles + @ fill
0 15 tile-grid@ 40 wave @ wave-tiles2 + @ fill
0 22 tile-grid@ 40 wave @ wave-tiles3 + @ fill
wave @ wave-height + @ player py!
;
: wave-time
wave-timer @ swap mod if r> 2drop then
;
######################################################
##
## Potentially reusable bits
##
######################################################
: spawn (frame rel-x rel-y src-id -- id)
dup py swap px
>r + swap r> +
alloc >r
i sprite@ .sprite-x !
i sprite@ .sprite-y !
i sprite@ .sprite-t !
16x16 i sprite@ !
r>
;
######################################################
##
## Game over animations
##
######################################################
: sink-player
dup py 240 > if
free
16 1 "THE END" grid-type
true ended !
exit
then
8 wave-time
dup sprite@ .sprite-y inc@
32 wave-time
sprite@ .sprite-x brownian swap +@
;
: sink-hat
16 wave-time
dup sprite@ .sprite-y inc@
32 wave-time
sprite@ .sprite-x brownian swap +@
;
: can-capsize
dup px player px - dup *
swap py player py - dup *
+ killradius killradius * <
;
: disperse
32 wave-time
dup px player px >
if dup sprite@ .sprite-x inc@
else dup sprite@ .sprite-x dec@ then
dup sprite@ .sprite-y inc@
sprite@ .sprite-t dup @ 1 xor swap !
;
:proto seek-player
:proto swim
: is-monster
dup types + @ ' seek-player =
over types + @ ' swim = or
swap types + @ ' disperse = or
;
: disperse-monster
' disperse type!
;
: capsize
gameover @ if exit then
true gameover !
' is-monster ' disperse-monster whoever
1 1 tile-grid@ 38 0 fill
2 player tile!
20 for waves think sync next
1 player tile!
20 for waves think sync next
2 player tile!
20 for waves think sync next
3 player tile!
player-gibs 12 5 player spawn ' sink-player type!
player-gibs 1 + 12 5 player spawn ' sink-hat type!
;
######################################################
##
## Entity scripts
##
######################################################
: bubble
dup py 48 < if free exit then
4 wave-time
dup sprite@ .sprite-y dec@
16 wave-time
dup sprite@ .sprite-x brownian swap +@
32 wave-time
sprite@ .sprite-t 4 random bubbles + swap !
;
: menace
32 wave-time
sprite@ .sprite-t dup @ 1 xor swap !
;
: seek-player
dup can-capsize if capsize then
speed @ 2 / wave-time
dup py 40 > if dup sprite@ .sprite-y dec@ then
dup px player px < if 2 else -2 then
over sprite@ .sprite-x +@
menace
;
: swim
dup py 64 < if ' seek-player type! exit then
4 wave-time
direction @ over sprite@ .sprite-x +@
speed @ wave-time
dup sprite@ .sprite-y dec@
menace
;
: sink
dup py 240 > if free 0 dropped ! exit then
dup sprite@ .sprite-y inc@
dup timers + @ 1 + 80 mod
2dup 20 / bomb + swap tile!
over timers + !
drop
;
: explode
dup timers + @ if
dup timers + dec@
dup timers + @ 10 / explosion +
swap tile!
exit
then
free
;
######################################################
##
## Core game logic
##
######################################################
: left+ px >r swap r> min swap ;
: leftmost 320 ' is-monster ' left+ whoever ;
: right+ px >r swap r> max swap ;
: rightmost 0 ' is-monster ' right+ whoever ;
: bounce
direction @ 0 > if
rightmost 303 > if direction neg@ then
else
leftmost 1 < if direction neg@ then
then
;
: draw-score
35 1 tile-grid@ 4 -1 fill
38 1 score @ draw-number
;
: move-player
gameover @ if exit then
keys dup
key-lf and if -2 player +px then
key-rt and if 2 player +px then
player px 0 max 288 min player px!
;
: drop-charge
bomb 0 12 player spawn
dup ' sink type!
dup 0 timer!
dropped !
;
: in-radius
dup px dropped @ px - dup *
swap py dropped @ py - dup *
+ blastradius blastradius * <
;
: kill-monster
dup is-monster -if drop exit then
' bubble type!
;
: detonate
dropped @ ' explode type!
dropped @ 40 timer!
explosion dropped @ tile!
2 for
bubbles 4 random +
48 random 24 -
48 random 24 -
dropped @ spawn ' bubble type!
next
' in-radius ' kill-monster whoever
0 dropped !
;
:var pressed
: fire
gameover @ if exit then
keys key-a and if
pressed @ -if
dropped @
if detonate
else drop-charge 1 player tile! then
pressed on
then
else
0 player tile!
pressed off
then
;
:var skycolor
:data skies
0xFF90C6C8
0xFF8C94C8
0xFFBC5FC8
0xFFD43353
0xFFA10F33
0xFF55081B
0xFF000000
: spawn-wave
7 for
10 for
16x16
monsters j i + 4 mod +
i 22 *
j 18 * 240 +
alloc dup >r >sprite
r> ' swim type!
next
next
1 direction !
speed @ 8 > if 4 speed -@ then
score inc@
skycolor @ 6 < if skycolor inc@ then
skycolor @ skies + @ CL !
;
:var crabctr
: spawn-crab
gameover @ if exit then
crabctr @ if crabctr dec@ exit then
500 200 random + crabctr !
16x16
crab
320 random
240
alloc dup >r >sprite
r> ' seek-player type!
;
: reset-game
32x16 0 144 32 player >sprite
16x16 invisible 30 100 0 light1 >sprite
16x16 invisible 31 200 0 light2 >sprite
36 speed !
0 dropped !
0 score !
0 crabctr !
0 skycolor !
skies @ CL !
gameover off
ended off
' always ' free whoever
1 1 tile-grid@ 38 -1 fill
50 for waves sync next
;
:var light
: storm
skycolor @ 6 < if exit then
# create flashes
light @ -if
320 random light1 px!
320 random light2 px!
10 random 5 > if light1 show then
10 random 5 > if light2 show then
500 random 300 + light !
0xFFFEFEFE CL !
then
light dec@
# hide lightning
CL @ 0xFF and 0xBB < if
light1 hide
light2 hide
then
# decay flashes
CL @ 0xFF and if
CL @ 0xFF and 2 -
dup dup 256 * or 256 * or 0xFF000000 or
CL !
then
;
: main
reset-game
loop
move-player
fire
waves
bounce
think
draw-score
spawn-crab
storm
' is-monster count -if spawn-wave then
ended @ gameover @ keys key-a and and and if reset-game then
sync
again
;