View difference between Paste ID: 7Pb01L21 and 84KRr5Q4
SHOW: | | - or go back to the newest paste.
1
[<ReflectedDefinition>]
2
module Program
3
4
open FunScript
5
open FunScript.TypeScript
6
7
type ts = Api<"../Typings/lib.d.ts">
8
9
let cyand =
10
    14, 14,
11
    let A, B, C, D = 0x00000000, 0xFF00FFDE, 0xFFDEDEDE, 0xFF2121DE
12
    [|
13
    A; A; A; A; A; B; B; B; B; A; A; A; A; A
14
    A; A; A; B; B; B; B; B; B; B; B; A; A; A
15
    A; A; B; B; B; B; B; B; B; B; B; B; A; A
16
    A; B; B; B; B; B; B; B; B; B; B; B; B; A
17
    A; B; B; C; C; B; B; B; B; C; C; B; B; A
18
    A; B; C; C; C; C; B; B; C; C; C; C; B; A
19
    B; B; C; C; C; C; B; B; C; C; C; C; B; B
20
    B; B; C; D; D; C; B; B; C; D; D; C; B; B
21
    B; B; B; D; D; B; B; B; B; D; D; B; B; B
22
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
23
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
24
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
25
    B; B; A; B; B; B; A; A; B; B; B; A; B; B
26
    B; A; A; A; B; B; A; A; B; B; A; A; A; B
27
    |]
28
let oranged =
29
    14, 14,
30
    let A, B, C, D = 0x00000000, 0xFFFFB847, 0xFFDEDEDE, 0xFF2121DE
31
    [|
32
    A; A; A; A; A; B; B; B; B; A; A; A; A; A
33
    A; A; A; B; B; B; B; B; B; B; B; A; A; A
34
    A; A; B; B; B; B; B; B; B; B; B; B; A; A
35
    A; B; B; B; B; B; B; B; B; B; B; B; B; A
36
    A; B; B; C; C; B; B; B; B; C; C; B; B; A
37
    A; B; C; C; C; C; B; B; C; C; C; C; B; A
38
    B; B; C; C; C; C; B; B; C; C; C; C; B; B
39
    B; B; C; D; D; C; B; B; C; D; D; C; B; B
40
    B; B; B; D; D; B; B; B; B; D; D; B; B; B
41
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
42
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
43
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
44
    B; B; A; B; B; B; A; A; B; B; B; A; B; B
45
    B; A; A; A; B; B; A; A; B; B; A; A; A; B
46
    |]
47
let pinkd =
48
    14, 14,
49
    let A, B, C, D = 0x00000000, 0xFFFFB8DE, 0xFFDEDEDE, 0xFF2121DE
50
    [|
51
    A; A; A; A; A; B; B; B; B; A; A; A; A; A
52
    A; A; A; B; B; B; B; B; B; B; B; A; A; A
53
    A; A; B; B; B; B; B; B; B; B; B; B; A; A
54
    A; B; B; B; B; B; B; B; B; B; B; B; B; A
55
    A; B; B; C; C; B; B; B; B; C; C; B; B; A
56
    A; B; C; C; C; C; B; B; C; C; C; C; B; A
57
    B; B; C; C; C; C; B; B; C; C; C; C; B; B
58
    B; B; C; D; D; C; B; B; C; D; D; C; B; B
59
    B; B; B; D; D; B; B; B; B; D; D; B; B; B
60
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
61
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
62
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
63
    B; B; A; B; B; B; A; A; B; B; B; A; B; B
64
    B; A; A; A; B; B; A; A; B; B; A; A; A; B
65
    |]
66
let redd =
67
    14, 14,
68
    let A, B, C, D = 0x00000000, 0xFFFF0000, 0xFFDEDEDE, 0xFF2121DE
69
    [|
70
    A; A; A; A; A; B; B; B; B; A; A; A; A; A
71
    A; A; A; B; B; B; B; B; B; B; B; A; A; A
72
    A; A; B; B; B; B; B; B; B; B; B; B; A; A
73
    A; B; B; B; B; B; B; B; B; B; B; B; B; A
74
    A; B; B; C; C; B; B; B; B; C; C; B; B; A
75
    A; B; C; C; C; C; B; B; C; C; C; C; B; A
76
    B; B; C; C; C; C; B; B; C; C; C; C; B; B
77
    B; B; C; D; D; C; B; B; C; D; D; C; B; B
78
    B; B; B; D; D; B; B; B; B; D; D; B; B; B
79
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
80
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
81
    B; B; B; B; B; B; B; B; B; B; B; B; B; B
82
    B; B; A; B; B; B; A; A; B; B; B; A; B; B
83
    B; A; A; A; B; B; A; A; B; B; A; A; A; B
84
    |]
85
86
let pr1 =
87
    13, 13,
88
    let A, B = 0x00000000, 0xFFFFFF00
89
    [|
90
    A; A; A; A; B; B; B; B; B; A; A; A; A
91
    A; A; B; B; B; B; B; B; B; B; B; A; A
92
    A; B; B; B; B; B; B; B; B; B; B; B; A
93
    A; B; B; B; B; B; B; B; B; B; B; A; A
94
    B; B; B; B; B; B; B; B; B; A; A; A; A
95
    B; B; B; B; B; B; B; A; A; A; A; A; A
96
    B; B; B; B; B; B; A; A; A; A; A; A; A
97
    B; B; B; B; B; B; B; A; A; A; A; A; A
98
    B; B; B; B; B; B; B; B; B; A; A; A; A
99
    A; B; B; B; B; B; B; B; B; B; B; A; A
100
    A; B; B; B; B; B; B; B; B; B; B; B; A
101
    A; A; B; B; B; B; B; B; B; B; B; A; A
102
    A; A; A; A; B; B; B; B; B; A; A; A; A
103
    |]
104
let pr2 =
105
    13, 13,
106
    let A, B = 0x0, 0xFFFFFF00
107
    [|
108
    A; A; A; A; B; B; B; B; B; A; A; A; A
109
    A; A; B; B; B; B; B; B; B; B; B; A; A
110
    A; B; B; B; B; B; B; B; B; B; B; B; A
111
    A; B; B; B; B; B; B; B; B; B; B; B; A
112
    B; B; B; B; B; B; B; B; B; B; B; B; B
113
    B; B; B; B; B; B; B; B; B; A; A; A; A
114
    B; B; B; B; B; B; A; A; A; A; A; A; A
115
    B; B; B; B; B; B; B; B; B; A; A; A; A
116
    B; B; B; B; B; B; B; B; B; B; B; B; B
117
    A; B; B; B; B; B; B; B; B; B; B; B; A
118
    A; B; B; B; B; B; B; B; B; B; B; B; A
119
    A; A; B; B; B; B; B; B; B; B; B; A; A
120
    A; A; A; A; B; B; B; B; B; A; A; A; A
121
    |]
122
let pl1 =
123
    13, 13,
124
    let A, B = 0x0, 0xFFFFFF00
125
    [|
126
    A; A; A; A; B; B; B; B; B; A; A; A; A
127
    A; A; B; B; B; B; B; B; B; B; B; A; A
128
    A; B; B; B; B; B; B; B; B; B; B; B; A
129
    A; A; B; B; B; B; B; B; B; B; B; B; A
130
    A; A; A; A; B; B; B; B; B; B; B; B; B
131
    A; A; A; A; A; A; B; B; B; B; B; B; B
132
    A; A; A; A; A; A; A; B; B; B; B; B; B
133
    A; A; A; A; A; A; B; B; B; B; B; B; B
134
    A; A; A; A; B; B; B; B; B; B; B; B; B
135
    A; A; B; B; B; B; B; B; B; B; B; B; A
136
    A; B; B; B; B; B; B; B; B; B; B; B; A
137
    A; A; B; B; B; B; B; B; B; B; B; A; A
138
    A; A; A; A; B; B; B; B; B; A; A; A; A
139
    |]
140
let pl2 =
141
    13, 13,
142
    let A, B = 0x0, 0xFFFFFF00
143
    [|
144
    A; A; A; A; B; B; B; B; B; A; A; A; A
145
    A; A; B; B; B; B; B; B; B; B; B; A; A
146
    A; B; B; B; B; B; B; B; B; B; B; B; A
147
    A; B; B; B; B; B; B; B; B; B; B; B; A
148
    B; B; B; B; B; B; B; B; B; B; B; B; B
149
    A; A; A; A; B; B; B; B; B; B; B; B; B
150
    A; A; A; A; A; A; A; B; B; B; B; B; B
151
    A; A; A; A; B; B; B; B; B; B; B; B; B
152
    B; B; B; B; B; B; B; B; B; B; B; B; B
153
    A; B; B; B; B; B; B; B; B; B; B; B; A
154
    A; B; B; B; B; B; B; B; B; B; B; B; A
155
    A; A; B; B; B; B; B; B; B; B; B; A; A
156
    A; A; A; A; B; B; B; B; B; A; A; A; A
157
    |]
158
let pu1 =
159
    13, 13,
160
    let A, B = 0x0, 0xFFFFFF00
161
    [|
162
    A; A; A; A; A; A; A; A; A; A; A; A; A
163
    A; A; B; A; A; A; A; A; A; A; B; A; A
164
    A; B; B; B; A; A; A; A; A; B; B; B; A
165
    A; B; B; B; A; A; A; A; A; B; B; B; A
166
    B; B; B; B; B; A; A; A; B; B; B; B; B
167
    B; B; B; B; B; A; A; A; B; B; B; B; B
168
    B; B; B; B; B; B; A; B; B; B; B; B; B
169
    B; B; B; B; B; B; B; B; B; B; B; B; B
170
    B; B; B; B; B; B; B; B; B; B; B; B; B
171
    A; B; B; B; B; B; B; B; B; B; B; B; A
172
    A; B; B; B; B; B; B; B; B; B; B; B; A
173
    A; A; B; B; B; B; B; B; B; B; B; A; A
174
    A; A; A; A; B; B; B; B; B; A; A; A; A
175
    |]
176
let pu2 =
177
    13, 13,
178
    let A, B = 0x0, 0xFFFFFF00
179
    [|
180
    A; A; A; A; B; A; A; A; B; A; A; A; A
181
    A; A; B; B; B; A; A; A; B; B; B; A; A
182
    A; B; B; B; B; A; A; A; B; B; B; B; A
183
    A; B; B; B; B; A; A; A; B; B; B; B; A
184
    B; B; B; B; B; B; A; B; B; B; B; B; B
185
    B; B; B; B; B; B; A; B; B; B; B; B; B
186
    B; B; B; B; B; B; A; B; B; B; B; B; B
187
    B; B; B; B; B; B; B; B; B; B; B; B; B
188
    B; B; B; B; B; B; B; B; B; B; B; B; B
189
    A; B; B; B; B; B; B; B; B; B; B; B; A
190
    A; B; B; B; B; B; B; B; B; B; B; B; A
191
    A; A; B; B; B; B; B; B; B; B; B; A; A
192
    A; A; A; A; B; B; B; B; B; A; A; A; A
193
    |]
194
let pd1 =
195
    13, 13,
196
    let A, B = 0x0, 0xFFFFFF00
197
    [|
198
    A; A; A; A; B; B; B; B; B; A; A; A; A
199
    A; A; B; B; B; B; B; B; B; B; B; A; A
200
    A; B; B; B; B; B; B; B; B; B; B; B; A
201
    A; B; B; B; B; B; B; B; B; B; B; B; A
202
    B; B; B; B; B; B; B; B; B; B; B; B; B
203
    B; B; B; B; B; B; B; B; B; B; B; B; B
204
    B; B; B; B; B; B; A; B; B; B; B; B; B
205
    B; B; B; B; B; A; A; A; B; B; B; B; B
206
    B; B; B; B; B; A; A; A; B; B; B; B; B
207
    A; B; B; B; A; A; A; A; A; B; B; B; A
208
    A; B; B; B; A; A; A; A; A; B; B; B; A
209
    A; A; B; A; A; A; A; A; A; A; B; A; A
210
    A; A; A; A; A; A; A; A; A; A; A; A; A
211
    |]
212
let pd2 =
213
    13, 13,
214
    let A, B = 0x0, 0xFFFFFF00
215
    [|
216
    A; A; A; A; B; B; B; B; B; A; A; A; A
217
    A; A; B; B; B; B; B; B; B; B; B; A; A
218
    A; B; B; B; B; B; B; B; B; B; B; B; A
219
    A; B; B; B; B; B; B; B; B; B; B; B; A
220
    B; B; B; B; B; B; B; B; B; B; B; B; B
221
    B; B; B; B; B; B; B; B; B; B; B; B; B
222
    B; B; B; B; B; B; A; B; B; B; B; B; B
223
    B; B; B; B; B; B; A; B; B; B; B; B; B
224
    B; B; B; B; B; B; A; B; B; B; B; B; B
225
    A; B; B; B; B; A; A; A; B; B; B; B; A
226
    A; B; B; B; B; A; A; A; B; B; B; B; A
227
    A; A; B; B; B; A; A; A; B; B; B; A; A
228
    A; A; A; A; B; A; A; A; B; A; A; A; A
229
    |]
230
231
232
233
let maze = "\
234
##/------------7/------------7##,\
235
##|............|!............|##,\
236
##|./__7./___7.|!./___7./__7.|##,\
237
##|o|  !.|   !.|!.|   !.|  !o|##,\
238
##|.L--J.L---J.LJ.L---J.L--J.|##,\
239
##|..........................|##,\
240
##|./__7./7./______7./7./__7.|##,\
241
##|.L--J.|!.L--7/--J.|!.L--J.|##,\
242
##|......|!....|!....|!......|##,\
243
##L____7.|L__7 |! /__J!./____J##,\
244
#######!.|/--J LJ L--7!.|#######,\
245
#######!.|!          |!.|#######,\
246
#######!.|! /__==__7 |!.|#######,\
247
-------J.LJ |      ! LJ.L-------,\
248
########.   | **** !   .########,\
249
_______7./7 |      ! /7./_______,\
250
#######!.|! L______J |!.|#######,\
251
#######!.|!          |!.|#######,\
252
#######!.|! /______7 |!.|#######,\
253
##/----J.LJ L--7/--J LJ.L----7##,\
254
##|............|!............|##,\
255
##|./__7./___7.|!./___7./__7.|##,\
256
##|.L-7!.L---J.LJ.L---J.|/-J.|##,\
257
##|o..|!.......<>.......|!..o|##,\
258
##L_7.|!./7./______7./7.|!./_J##,\
259
##/-J.LJ.|!.L--7/--J.|!.LJ.L-7##,\
260
##|......|!....|!....|!......|##,\
261
##|./____JL__7.|!./__JL____7.|##,\
262
##|.L--------J.LJ.L--------J.|##,\
263
##|..........................|##,\
264
##L--------------------------J##".Split(',')
265
266
let tl = [|
267
    0b00000000
268
    0b00000000
269
    0b00000000
270
    0b00000000
271
    0b00000011
272
    0b00000100
273
    0b00001000
274
    0b00001000|]
275
let top = [|
276
    0b00000000
277
    0b00000000
278
    0b00000000
279
    0b00000000
280
    0b11111111
281
    0b00000000
282
    0b00000000
283
    0b00000000|]
284
let tr = [|
285
    0b00000000
286
    0b00000000
287
    0b00000000
288
    0b00000000
289
    0b11000000
290
    0b00100000
291
    0b00010000
292
    0b00010000|]
293
let left = [|
294
    0b00001000
295
    0b00001000
296
    0b00001000
297
    0b00001000
298
    0b00001000
299
    0b00001000
300
    0b00001000
301
    0b00001000|]
302
let blank = [|
303
    0b00000000
304
    0b00000000
305
    0b00000000
306
    0b00000000
307
    0b00000000
308
    0b00000000
309
    0b00000000
310
    0b00000000|]
311
let right = [|
312
    0b00010000
313
    0b00010000
314
    0b00010000
315
    0b00010000
316
    0b00010000
317
    0b00010000
318
    0b00010000
319
    0b00010000|]
320
let bl = [|
321
    0b00001000
322
    0b00001000
323
    0b00000100
324
    0b00000011
325
    0b00000000
326
    0b00000000
327
    0b00000000
328
    0b00000000|]
329
let bottom = [|
330
    0b00000000
331
    0b00000000
332
    0b00000000
333
    0b11111111
334
    0b00000000
335
    0b00000000
336
    0b00000000
337
    0b00000000|]
338
let br = [|
339
    0b00010000
340
    0b00010000
341
    0b00100000
342
    0b11000000
343
    0b00000000
344
    0b00000000
345
    0b00000000
346
    0b00000000|]
347
let door = [|
348
    0b00000000
349
    0b00000000
350
    0b00000000
351
    0b00000000
352
    0b11111111
353
    0b00000000
354
    0b00000000
355
    0b00000000|]
356
let pill = [|
357
    0b00000000
358
    0b00000000
359
    0b00000000
360
    0b00011000
361
    0b00011000
362
    0b00000000
363
    0b00000000
364
    0b00000000|]
365
let power = [|
366
    0b00000000
367
    0b00011000
368
    0b00111100
369
    0b01111110
370
    0b01111110
371
    0b00111100
372
    0b00011000
373
    0b00000000|]
374
375
type Brush = Blue | Yellow
376
377
let toTile c =
378
    match c with   
379
    | '=' -> door, Blue
380
    | '_' -> top, Blue
381
    | '|' -> left, Blue
382
    | '!' -> right, Blue
383
    | '/' -> tl, Blue
384
    | '7' -> tr, Blue
385
    | 'L' -> bl, Blue
386
    | 'J' -> br, Blue
387
    | '-' -> bottom, Blue
388
    | '.' -> pill, Yellow
389
    | 'o' -> power, Yellow
390
    | _ -> blank, Blue
391
392
let isWall x=
393
    match x with
394
    | '_' | '|' | '!' | '/' | '7' | 'L' | 'J' | '-' | '*' -> true
395
    | _ -> false
396
397
let tileAt (x,y) =
398
    if x < 0 then ' '
399
    elif x > 30 then ' '
400
    else maze.[y].[x]
401
        
402
let isWallAt (x,y) = tileAt(x,y) |> isWall
403
404
[<JSEmit("return {0} << {1};")>]
405
let ShiftLeft(x:int,n:int) : int = failwith "never"
406
407
[<JSEmit("return {0} >> {1};")>]
408
let ShiftRight(x:int,n:int) : int = failwith "never"
409
410
[<JSEmit("return {0} & {1};")>]
411
let And(a:int,b:int) : int = failwith "never"
412
413
let draw f (lines:int[]) =
414
    let width = 8
415
    lines |> Array.iteri (fun y line ->
416
        let line = line
417
        for x = 0 to width-1 do
418
            let bit = ShiftLeft(1, width - 1 - x) 
419
            let pattern = And(line,bit)
420
            if pattern <> 0 then f (x,y)
421
    )
422
423
let part x n =
424
    let bits = ShiftRight(x,n)       
425
    let byte = And(bits, 255)
426
    float byte
427
428
let createImage (width, height, pixels) =
429
    let layer = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))   
430
    layer.width <- float width
431
    layer.height <- float height
432
    let context = layer.getContext("2d")    
433
    let id = context.createImageData(float width,float height)
434
    let d = id.data
435
    pixels |> Array.iteri (fun i pixel ->
436
            let x = i * 4
437
            d.[x+0] <- part pixel 16
438
            d.[x+1] <- part pixel 8
439
            d.[x+2] <- part pixel 0
440
            d.[x+3] <- part pixel 24
441
        )
442
    context.putImageData(id,0.,0.)
443
    let image = unbox<ts.HTMLImageElement>(ts.document.createElement("image"))   
444
    image.src <- layer.toDataURL()
445
    unbox<ts.HTMLElement>(image)
446
447
type Plotter(context:ts.CanvasRenderingContext2D) =
448
    member __.createBrush(r,g,b,a) =
449
        let id = context.createImageData(float 1,float 1)
450
        let d = id.data
451
        d.[0] <- float r; d.[1] <- float g; d.[2] <- float b; d.[3] <- float a
452
        id
453
    member __.plot(brush,x,y) =
454
        context.putImageData(brush, float x, float y)          
455
456-
    let pacman = createImage pr1    
456+
457
    let background = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))   
458
    background.width <- 256.
459
    background.height <- 256.    
460
    let context = background.getContext("2d")
461
    context.fillStyle <- "rgb(0,0,0)"
462
    context.fillRect (0., 0. , 256., 256.);
463
    let plotter = Plotter(context)
464
    let blue = plotter.createBrush (63,63,255,255)
465-
        if keys.LeftPressed && canGoLeft(!x,!y) then x:= !x - 1
465+
466-
        if keys.RightPressed && canGoRight(!x,!y) then x := !x + 1
466+
467-
        if keys.UpPressed && canGoUp(!x,!y) then y:= !y - 1 
467+
468-
        if keys.DownPressed && canGoDown(!x,!y) then y := !y + 1
468+
469
        for x = 0 to line.Length-1 do
470
            let c = line.[x]
471
            let tile, color = toTile c                
472-
        context.drawImage(pacman, float !x, float !y)
472+
473
            let f (x',y') = plotter.plot(brush, x*8 + x', y*8 + y')
474
            draw f tile
475
    unbox<ts.HTMLElement>(background)
476
477
let noWall (x,y) (ex,ey) =
478
    let bx, by = ShiftRight(x+6+ex,3), ShiftRight(y+6+ey,3)
479
    isWallAt (bx,by) |> not
480
481
let verticallyAligned (x,y) =  (x % 8) = 5
482
let horizontallyAligned (x,y) = (y % 8) = 5
483
let isAligned n = (n % 8) = 5
484
485
let canGoUp (x,y) = isAligned x && noWall (x,y) (0,-4)
486
let canGoDown (x,y) = isAligned x && noWall (x,y) (0,5)
487
let canGoLeft (x,y) = isAligned y && noWall (x,y) (-4,0)
488
let canGoRight (x,y) = isAligned y && noWall (x,y) (5,0)
489
490
let wrap (x,y) (dx,dy) =
491
    let x = 
492
        if dx = -1 && x = 0 then 30 * 8
493
        elif dx = 1  && x = 30 *8 then 0
494
        else x
495
    x + dx, y + dy
496
497
type Ghost(image:ts.HTMLElement,x,y,v) =
498
    let mutable x' = x
499
    let mutable y' = y
500
    let mutable v' = v
501
    member val Image = image
502
    member __.X = x'
503
    member __.Y = y' 
504
    member __.V = v'
505
    member ghost.Move(v) =
506
        v' <- v        
507
        let dx,dy = v
508
        let x,y = wrap (x',y') (dx,dy)
509
        x' <- x
510
        y' <- y
511
512
let chooseDirection (ghost:Ghost) =
513
    let x,y = ghost.X, ghost.Y
514
    let dx,dy = ghost.V
515
    let isBackwards (a,b) =
516
        (a <> 0 && a = -dx) || (b <> 0 && b = -dy)
517
    let directions = 
518
        [|canGoLeft(x,y),(-1,0)
519
          canGoDown(x,y),(0,1)
520
          canGoRight(x,y),(1,0)
521
          canGoUp(x,y),(0,-1)|]
522
        |> Array.filter fst
523
        |> Array.map snd
524
        |> Array.filter (not << isBackwards)        
525
    let i = int (ts.Math.floor(ts.Math.random() * float directions.Length))
526
    let dx,dy = directions.[i]
527
    dx,dy
528
529
let createGhosts context = 
530
    [|
531
         redd, (16, 11), (1,0)
532
         cyand, (14, 15), (1,0)
533
         pinkd, (16, 13), (0,-1)
534
         oranged, (18, 15), (-1,0)
535
    |]
536
    |> Array.map (fun (data,(x,y),v) -> 
537
        let image = createImage data
538
        Ghost(image, (x*8)-7, (y*8)-3, v)
539
    )
540
541
type Keys() =
542
    let leftCode, upCode, rightCode, downCode = 90(*z*), 81(*q*), 88(*x*), 65(*a*)
543
    let mutable isLeft = false
544
    let mutable isUp = false
545
    let mutable isDown = false
546
    let mutable isRight = false
547
    member keys.Update (e:ts.KeyboardEventExtensions,pressed) =
548
        let keyCode = int e.keyCode        
549
        if keyCode = leftCode then isLeft <- pressed
550
        if keyCode = rightCode then isRight <- pressed
551
        if keyCode = upCode then isUp <- pressed
552
        if keyCode = downCode then isDown <- pressed           
553
    member keys.LeftPressed = isLeft
554
    member keys.RightPressed = isRight
555
    member keys.UpPressed = isUp
556
    member keys.DownPressed = isDown
557
558
let bindKeys (keys:Keys) =
559
    ts.addEventListener("keydown", unbox<ts.EventListener>(fun e -> 
560
        let e = (unbox<ts.KeyboardEventExtensions>(e))
561
        keys.Update(e, true)
562
        )
563
    )
564
    ts.addEventListener("keyup", unbox<ts.EventListener>(fun e ->
565
            let e = (unbox<ts.KeyboardEventExtensions>(e))
566
            keys.Update(e,false)
567
        )
568
    )   
569
570
let main() =   
571
    let keys = Keys()
572
    bindKeys keys
573
    
574
    let canvas = unbox<ts.HTMLCanvasElement>(ts.document.getElementById("canvas"))
575
    canvas.width <- 256.
576
    canvas.height <- 256.    
577
    let context = canvas.getContext("2d")
578
    context.fillStyle <- "rgb(0,0,0)"
579
    context.fillRect (0., 0. , 256., 256.);
580
581
    let background = createBackground()
582
    let ghosts = createGhosts(context)
583
    let pu1, pu2 = createImage pu1, createImage pu2
584
    let pd1, pd2 = createImage pd1, createImage pd2
585
    let pl1, pl2 = createImage pl1, createImage pl2
586
    let pr1, pr2 = createImage pr1, createImage pr2
587
588
    let score = ref 0
589
    let x, y = ref (16 * 8 - 7), ref (23 * 8 - 3)
590
    let v = ref (0,0)
591
    let lastp = ref pr1 
592
593
    let moveGhosts () =
594
        ghosts |> Array.iter (fun ghost ->
595
            let v = chooseDirection ghost
596
            ghost.Move(v)
597
        )
598
599
    let movePacman () =
600
        v := 
601
            if keys.LeftPressed && canGoLeft(!x,!y) then (-1,0)
602
            elif keys.RightPressed && canGoRight(!x,!y) then (1,0)
603
            elif keys.UpPressed && canGoUp(!x,!y) then (0,-1)
604
            elif keys.DownPressed && canGoDown(!x,!y) then (0,1)
605
            else (0,0)
606
        let x',y' = wrap (!x,!y) !v
607
        x := x'
608
        y := y'
609
610
    let logic () =
611
        moveGhosts()
612
        movePacman()
613
614
    let getPacmanImage () =
615
        let p1, p2 =
616
            match !v with
617
            | -1,  0 -> pl1, pl2
618
            |  1,  0 -> pr1, pr2
619
            |  0, -1 -> pu1, pu2
620
            |  0,  1 -> pd1, pd2
621
            |  _,  _ -> !lastp, !lastp
622
        let x' = int (ts.Math.floor(float (!x/6)))
623
        let y' = int (ts.Math.floor(float (!y/6)))
624
        if (x' + y') % 2 = 0 then p1 else p2
625
626
    let renderPacman () =
627
        let p = getPacmanImage()
628
        lastp := p
629
        context.drawImage(p, float !x, float !y)
630
631
    let renderGhosts () =
632
        ghosts |> Array.iter (fun ghost ->
633
            context.drawImage(ghost.Image, float ghost.X, float ghost.Y) 
634
        )
635
636
    let renderScore () =
637
        context.fillStyle <- "white"
638
        context.font <- "bold 8px";
639
        context.fillText("Score " + (!score).ToString(), 0., 255.)
640
641
    let render () =
642
        context.drawImage(background, 0., 0.)
643
        renderScore ()
644
        renderPacman()
645
        renderGhosts ()
646
647
    let rec update () =
648
        render ()
649
        logic ()
650
        ts.setTimeout(update, 1000. / 60.) |> ignore
651
652
    update()
653
654
do Runtime.Run(directory="Web", components=Interop.Components.all)