/
pacmanstubes.bmx
359 lines (313 loc) · 5.9 KB
/
pacmanstubes.bmx
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
'Pacman is a Series of Tubes
'or
'Water on a G-String
Const lightscale#=3000,maxlight=150
Const maxp#=.005
Global ghosts:TList=New TList
Type mover
Field x#,y#
Field vx#,vy#
Field rx#,ry#
Field tick
Field an
Method update()
rx=rx+vx
ry=ry+vy
ox=x
oy=y
x=Int(rx/20)
y=Int(ry/20)
If x<0 x=27
If x>27 x=0
If y<0 y=29
If y>29 y=0
If Not map[x,y]
vx=0
vy=0
x=ox
y=oy
rx=x*20
ry=y*20
EndIf
If ox<>x Or oy<>y
makemove()
EndIf
End Method
Method move(dx,dy)
If dx=vx And dy=vy Return
vx=dx
vy=dy
tick=0
an=((vx-1)*Abs(vx)+vy)*90
End Method
Method makemove()
End Method
End Type
Type ghost Extends mover
Field ox#,oy#,tx#,ty#
Field state
Field red,green,blue
Field prob#[28,30]
Field coalesce#
Field poss[200,2],observed
Field fade#
Field ovx,ovy
Method New()
num=Rand(1,7)
'red=(num & 1)*255
'blue=(num & 2)*255
'green=(num & 4)*255
x#=Rnd(0,27)
y#=Rnd(0,29)
vx#=Rnd(-.1,.1)
vy#=Rnd(-.1,.1)
state=0
coalesce#=1
ghosts.addlast Self
End Method
Function create:ghost(red,green,blue)
g:ghost=New ghost
g.red=red
g.green=green
g.blue=blue
Return g
End Function
Method update()
Select state
Case 0 'chasing pacman
closest:pacman=Null
mindist=-1
For pm:pacman=EachIn pacmen
d#=Abs(pm.x-x)+Abs(pm.y-y)
If d<mindist Or mindist=-1
closest=pm
EndIf
Next
If closest
dx#=Sgn(closest.x-x)
dy#=Sgn(closest.y-y)
If Abs(closest.x-x)>Abs(closest.y-y)
dy=0
Else
dx=0
EndIf
px=x+dx
py=y+dy
If px<0 px=27
If px>27 px=0
If py<0 py=29
If py>29 py=0
If map[px,py]
move(dx,dy)
ElseIf vx=0 And vy=0
Select Rand(0,1)
Case 0
vx=Rand(0,1)*2-1
Case 1
vy=Rand(0,1)*2-1
End Select
EndIf
EndIf
tick:+.0001
super.update()
End Select
End Method
Method makemove()
For pm:pacman=EachIn pacmen
If pm.x=x And pm.y=y
finito=1
EndIf
Next
End Method
Method draw()
px=x*20+tick*vx
py=y*20+tick*vy
SetBlend ALPHABLEND
SetAlpha 1-fade
SetColor red*255,green*255,blue*255
DrawOval px+3,py+3,15,15
SetAlpha 1
SetColor 255,255,255
DrawOval px+5,py+6,4,4
DrawOval px+12,py+6,4,4
SetColor 0,0,0
DrawRect px+7+vx,py+7+vy,1,1
DrawRect px+14+vx,py+7+vy,1,1
End Method
End Type
Global pacmen:TList=New TList
Type pacman Extends mover
Field score,mouthopen,mouthdir
Method New()
x=15
y=17
pacmen.addlast Self
mouthdir=1
End Method
Method update()
'tick:+.1
super.update()
If vx Or vy
mouthopen:+5*mouthdir
If mouthopen<0 Or mouthopen>70
mouthdir=-mouthdir
mouthopen:+mouthdir*5
EndIf
EndIf
End Method
Method makemove()
If pills[x,y]
pills[x,y]=0
score:+100
totalpills:-1
If totalpills=0
finito=1
EndIf
EndIf
End Method
Method draw()
SetBlend ALPHABLEND
cx#=x*20+10+tick*vx
cy#=y*20+10+tick*vy
ox#=cx+Cos(mouthopen+an)*8
oy#=cy+Sin(mouthopen+an)*8
SetColor 0,0,0
DrawLine cx,cy,ox,oy
For pan=mouthopen To 360-mouthopen Step 10
px#=cx+Cos(pan+an)*8
py#=cy+Sin(pan+an)*8
Local poly#[]=[cx,cy,ox,oy,px,py]
SetColor 255,255,0
DrawPoly poly
SetColor 0,0,0
DrawLine ox,oy,px,py
ox=px
oy=py
Next
SetColor 0,0,0
DrawLine cx,cy,px,py
End Method
End Type
file:TStream=OpenFile("schroedingersmap.txt")
Global map[28,30]
For y=0 To 29
line$=ReadLine(file)
For x=0 To 27
If line[x]-48 Then map[x,y]=1
Next
Next
AppTitle="Schroedinger's Ghost!"
Graphics 560,600,0
Global finito=0
Global restart=1
Global observedmap[28,30]
Global pills[28,30]
Global totalpills
Global player:pacman
Global musicch:TChannel
Global musicogg:TSound=LoadSound("bambasamba.ogg")
Function initgame()
totalpills=0
For x=0 To 27
For y=0 To 29
If map[x,y]
pills[x,y]=1
totalpills:+1
EndIf
Next
Next
ghosts=New TList
pacmen=New TList
ghost.create(0,0,1)
ghost.create(1,0,0)
ghost.create(0,1,0)
player:pacman=New pacman
finito=0
musicch=PlaySound(musicogg)
End Function
Function rungame()
If Not ChannelPlaying(musicch)
musicch=PlaySound(musicogg)
EndIf
While Not finito
mx=MouseX()
my=MouseY()
'draw map
For x=0 To 27
For y=0 To 29
If map[x,y]
If observedmap[x,y]
SetBlend LIGHTBLEND
SetColor 100,100,0
DrawRect x*20,y*20,20,20
observedmap[x,y]=0
EndIf
Else
SetBlend ALPHABLEND
SetColor 100,100,100
DrawRect x*20,y*20,20,20
EndIf
If pills[x,y]
SetBlend ALPHABLEND
SetColor 255,255,255
DrawOval x*20+8,y*20+8,5,5
EndIf
Next
Next
If KeyHit(KEY_LEFT)
player.move(-1,0)
ElseIf KeyHit(KEY_RIGHT)
player.move(1,0)
ElseIf KeyHit(KEY_UP)
player.move(0,-1)
ElseIf KeyHit(KEY_DOWN)
player.move(0,1)
EndIf
'do ghosts
yoff=0
For g:ghost=EachIn ghosts
g.update()
g.draw()
x=mx/20
y=my/20
'SetColor 255,255,0
'DrawText g.prob[x,y],x*20,y*20+yoff
'yoff:+15
Next
'do pacmen
For p:pacman=EachIn pacmen
p.update()
p.draw()
Next
SetBlend LIGHTBLEND
SetColor 255,255,255
txt$=String(player.score)
DrawText txt,280-TextWidth(txt)/2,0
'quitting
If KeyHit(KEY_ESCAPE)
finito=1
restart=0
EndIf
Flip
Cls
Wend
End Function
While restart
initgame()
rungame()
Cls
If totalpills
txt$="You were eaten! Your score was "+String(player.score)
Else
txt$="YOU WON!"
EndIf
StopChannel musicch
If restart
DrawText txt,280-TextWidth(txt)/2,300-TextHeight(txt)/2
txt$="Press a key to play again"
DrawText txt,280-TextWidth(txt)/2,330-TextHeight(txt)/2
Flip
Delay 500
WaitKey()
EndIf
Wend