Advertisement
ptrelford

Pacman Keys in FunScript

Sep 4th, 2013
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
F# 13.98 KB | None | 0 0
  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.  
  105.  
  106. let maze = "\
  107. ##/------------7/------------7##,\
  108. ##|............|!............|##,\
  109. ##|./__7./___7.|!./___7./__7.|##,\
  110. ##|o|  !.|   !.|!.|   !.|  !o|##,\
  111. ##|.L--J.L---J.LJ.L---J.L--J.|##,\
  112. ##|..........................|##,\
  113. ##|./__7./7./______7./7./__7.|##,\
  114. ##|.L--J.|!.L--7/--J.|!.L--J.|##,\
  115. ##|......|!....|!....|!......|##,\
  116. ##L____7.|L__7 |! /__J!./____J##,\
  117. #######!.|/--J LJ L--7!.|#######,\
  118. #######!.|!          |!.|#######,\
  119. #######!.|! /__==__7 |!.|#######,\
  120. -------J.LJ |      ! LJ.L-------,\
  121. ########.   | **** !   .########,\
  122. _______7./7 |      ! /7./_______,\
  123. #######!.|! L______J |!.|#######,\
  124. #######!.|!          |!.|#######,\
  125. #######!.|! /______7 |!.|#######,\
  126. ##/----J.LJ L--7/--J LJ.L----7##,\
  127. ##|............|!............|##,\
  128. ##|./__7./___7.|!./___7./__7.|##,\
  129. ##|.L-7!.L---J.LJ.L---J.|/-J.|##,\
  130. ##|o..|!.......<>.......|!..o|##,\
  131. ##L_7.|!./7./______7./7.|!./_J##,\
  132. ##/-J.LJ.|!.L--7/--J.|!.LJ.L-7##,\
  133. ##|......|!....|!....|!......|##,\
  134. ##|./____JL__7.|!./__JL____7.|##,\
  135. ##|.L--------J.LJ.L--------J.|##,\
  136. ##|..........................|##,\
  137. ##L--------------------------J##".Split(',')
  138.  
  139. let tl = [|
  140.     0b00000000
  141.     0b00000000
  142.     0b00000000
  143.     0b00000000
  144.     0b00000011
  145.     0b00000100
  146.     0b00001000
  147.     0b00001000|]
  148. let top = [|
  149.     0b00000000
  150.     0b00000000
  151.     0b00000000
  152.     0b00000000
  153.     0b11111111
  154.     0b00000000
  155.     0b00000000
  156.     0b00000000|]
  157. let tr = [|
  158.     0b00000000
  159.     0b00000000
  160.     0b00000000
  161.     0b00000000
  162.     0b11000000
  163.     0b00100000
  164.     0b00010000
  165.     0b00010000|]
  166. let left = [|
  167.     0b00001000
  168.     0b00001000
  169.     0b00001000
  170.     0b00001000
  171.     0b00001000
  172.     0b00001000
  173.     0b00001000
  174.     0b00001000|]
  175. let blank = [|
  176.     0b00000000
  177.     0b00000000
  178.     0b00000000
  179.     0b00000000
  180.     0b00000000
  181.     0b00000000
  182.     0b00000000
  183.     0b00000000|]
  184. let right = [|
  185.     0b00010000
  186.     0b00010000
  187.     0b00010000
  188.     0b00010000
  189.     0b00010000
  190.     0b00010000
  191.     0b00010000
  192.     0b00010000|]
  193. let bl = [|
  194.     0b00001000
  195.     0b00001000
  196.     0b00000100
  197.     0b00000011
  198.     0b00000000
  199.     0b00000000
  200.     0b00000000
  201.     0b00000000|]
  202. let bottom = [|
  203.     0b00000000
  204.     0b00000000
  205.     0b00000000
  206.     0b11111111
  207.     0b00000000
  208.     0b00000000
  209.     0b00000000
  210.     0b00000000|]
  211. let br = [|
  212.     0b00010000
  213.     0b00010000
  214.     0b00100000
  215.     0b11000000
  216.     0b00000000
  217.     0b00000000
  218.     0b00000000
  219.     0b00000000|]
  220. let door = [|
  221.     0b00000000
  222.     0b00000000
  223.     0b00000000
  224.     0b00000000
  225.     0b11111111
  226.     0b00000000
  227.     0b00000000
  228.     0b00000000|]
  229. let pill = [|
  230.     0b00000000
  231.     0b00000000
  232.     0b00000000
  233.     0b00011000
  234.     0b00011000
  235.     0b00000000
  236.     0b00000000
  237.     0b00000000|]
  238. let power = [|
  239.     0b00000000
  240.     0b00011000
  241.     0b00111100
  242.     0b01111110
  243.     0b01111110
  244.     0b00111100
  245.     0b00011000
  246.     0b00000000|]
  247.  
  248. type Brush = Blue | Yellow
  249.  
  250. let toTile c =
  251.     match c with  
  252.     | '=' -> door, Blue
  253.     | '_' -> top, Blue
  254.     | '|' -> left, Blue
  255.     | '!' -> right, Blue
  256.     | '/' -> tl, Blue
  257.     | '7' -> tr, Blue
  258.     | 'L' -> bl, Blue
  259.     | 'J' -> br, Blue
  260.     | '-' -> bottom, Blue
  261.     | '.' -> pill, Yellow
  262.     | 'o' -> power, Yellow
  263.     | _ -> blank, Blue
  264.  
  265. let isWall x=
  266.     match x with
  267.     | '_' | '|' | '!' | '/' | '7' | 'L' | 'J' | '-' | '*' -> true
  268.     | _ -> false
  269.  
  270. let tileAt (x,y) =
  271.     if x < 0 then ' '
  272.     elif x > 30 then ' '
  273.     else maze.[y].[x]
  274.        
  275. let isWallAt (x,y) = tileAt(x,y) |> isWall
  276.  
  277. [<JSEmit("return {0} << {1};")>]
  278. let ShiftLeft(x:int,n:int) : int = failwith "never"
  279.  
  280. [<JSEmit("return {0} >> {1};")>]
  281. let ShiftRight(x:int,n:int) : int = failwith "never"
  282.  
  283. [<JSEmit("return {0} & {1};")>]
  284. let And(a:int,b:int) : int = failwith "never"
  285.  
  286. let draw f (lines:int[]) =
  287.     let width = 8
  288.     lines |> Array.iteri (fun y line ->
  289.         let line = line
  290.         for x = 0 to width-1 do
  291.             let bit = ShiftLeft(1, width - 1 - x)
  292.             let pattern = And(line,bit)
  293.             if pattern <> 0 then f (x,y)
  294.     )
  295.  
  296. let part x n =
  297.     let bits = ShiftRight(x,n)      
  298.     let byte = And(bits, 255)
  299.     float byte
  300.  
  301. let createImage (width, height, pixels) =
  302.     let layer = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))  
  303.     layer.width <- float width
  304.     layer.height <- float height
  305.     let context = layer.getContext("2d")    
  306.     let id = context.createImageData(float width,float height)
  307.     let d = id.data
  308.     pixels |> Array.iteri (fun i pixel ->
  309.             let x = i * 4
  310.             d.[x+0] <- part pixel 16
  311.             d.[x+1] <- part pixel 8
  312.             d.[x+2] <- part pixel 0
  313.             d.[x+3] <- part pixel 24
  314.         )
  315.     context.putImageData(id,0.,0.)
  316.     let image = unbox<ts.HTMLImageElement>(ts.document.createElement("image"))  
  317.     image.src <- layer.toDataURL()
  318.     unbox<ts.HTMLElement>(image)
  319.  
  320. type Plotter(context:ts.CanvasRenderingContext2D) =
  321.     member __.createBrush(r,g,b,a) =
  322.         let id = context.createImageData(float 1,float 1)
  323.         let d = id.data
  324.         d.[0] <- float r; d.[1] <- float g; d.[2] <- float b; d.[3] <- float a
  325.         id
  326.     member __.plot(brush,x,y) =
  327.         context.putImageData(brush, float x, float y)          
  328.  
  329. let createBackground () =
  330.     let background = unbox<ts.HTMLCanvasElement>(ts.document.createElement("canvas"))  
  331.     background.width <- 256.
  332.     background.height <- 256.    
  333.     let context = background.getContext("2d")
  334.     context.fillStyle <- "rgb(0,0,0)"
  335.     context.fillRect (0., 0. , 256., 256.);
  336.     let plotter = Plotter(context)
  337.     let blue = plotter.createBrush (63,63,255,255)
  338.     let yellow = plotter.createBrush (255,255,0,255)
  339.     let lines = maze      
  340.     for y = 0 to lines.Length-1 do
  341.         let line = lines.[y]
  342.         for x = 0 to line.Length-1 do
  343.             let c = line.[x]
  344.             let tile, color = toTile c                
  345.             let brush = match color with Blue -> blue | Yellow -> yellow        
  346.             let f (x',y') = plotter.plot(brush, x*8 + x', y*8 + y')
  347.             draw f tile
  348.     unbox<ts.HTMLElement>(background)
  349.  
  350. let noWall (x,y) (ex,ey) =
  351.     let bx, by = ShiftRight(x+6+ex,3), ShiftRight(y+6+ey,3)
  352.     isWallAt (bx,by) |> not
  353.  
  354. let verticallyAligned (x,y) =  (x % 8) = 5
  355. let horizontallyAligned (x,y) = (y % 8) = 5
  356. let isAligned n = (n % 8) = 5
  357.  
  358. let canGoUp (x,y) = isAligned x && noWall (x,y) (0,-4)
  359. let canGoDown (x,y) = isAligned x && noWall (x,y) (0,5)
  360. let canGoLeft (x,y) = isAligned y && noWall (x,y) (-4,0)
  361. let canGoRight (x,y) = isAligned y && noWall (x,y) (5,0)
  362.  
  363. let wrap (x,y) (dx,dy) =
  364.     let x =
  365.         if dx = -1 && x = 0 then 30 * 8
  366.         elif dx = 1  && x = 30 *8 then 0
  367.         else x
  368.     x + dx, y + dy
  369.  
  370. type Ghost(image:ts.HTMLElement,x,y,v) =
  371.     let mutable x' = x
  372.    let mutable y' = y
  373.     let mutable v' = v
  374.    member val Image = image
  375.    member __.X = x'
  376.     member __.Y = y'
  377.    member __.V = v'
  378.     member ghost.Move(v) =
  379.         v' <- v        
  380.        let dx,dy = v
  381.        let x,y = wrap (x',y') (dx,dy)
  382.        x' <- x
  383.         y' <- y
  384.  
  385. let chooseDirection (ghost:Ghost) =
  386.    let x,y = ghost.X, ghost.Y
  387.    let dx,dy = ghost.V
  388.    let isBackwards (a,b) =
  389.        (a <> 0 && a = -dx) || (b <> 0 && b = -dy)
  390.    let directions =
  391.        [|canGoLeft(x,y),(-1,0)
  392.          canGoDown(x,y),(0,1)
  393.          canGoRight(x,y),(1,0)
  394.          canGoUp(x,y),(0,-1)|]
  395.        |> Array.filter fst
  396.        |> Array.map snd
  397.        |> Array.filter (not << isBackwards)        
  398.    let i = int (ts.Math.floor(ts.Math.random() * float directions.Length))
  399.    let dx,dy = directions.[i]
  400.    dx,dy
  401.  
  402. let createGhosts context =
  403.    [|
  404.         redd, (16, 11), (1,0)
  405.         cyand, (14, 15), (1,0)
  406.         pinkd, (16, 13), (0,-1)
  407.         oranged, (18, 15), (-1,0)
  408.    |]
  409.    |> Array.map (fun (data,(x,y),v) ->
  410.        let image = createImage data
  411.        Ghost(image, (x*8)-7, (y*8)-3, v)
  412.    )
  413.  
  414. type Keys() =
  415.    let leftCode, upCode, rightCode, downCode = 90(*z*), 81(*q*), 88(*x*), 65(*a*)
  416.    let mutable isLeft = false
  417.    let mutable isUp = false
  418.    let mutable isDown = false
  419.    let mutable isRight = false
  420.    member keys.Update (e:ts.KeyboardEventExtensions,pressed) =
  421.        let keyCode = int e.keyCode        
  422.        if keyCode = leftCode then isLeft <- pressed
  423.        if keyCode = rightCode then isRight <- pressed
  424.        if keyCode = upCode then isUp <- pressed
  425.        if keyCode = downCode then isDown <- pressed          
  426.    member keys.LeftPressed = isLeft
  427.    member keys.RightPressed = isRight
  428.    member keys.UpPressed = isUp
  429.    member keys.DownPressed = isDown
  430.  
  431. let bindKeys (keys:Keys) =
  432.    ts.addEventListener("keydown", unbox<ts.EventListener>(fun e ->
  433.        let e = (unbox<ts.KeyboardEventExtensions>(e))
  434.        keys.Update(e, true)
  435.        )
  436.    )
  437.    ts.addEventListener("keyup", unbox<ts.EventListener>(fun e ->
  438.            let e = (unbox<ts.KeyboardEventExtensions>(e))
  439.            keys.Update(e,false)
  440.        )
  441.    )  
  442.  
  443. let main() =  
  444.    let keys = Keys()
  445.    bindKeys keys
  446.    
  447.    let canvas = unbox<ts.HTMLCanvasElement>(ts.document.getElementById("canvas"))
  448.    canvas.width <- 256.
  449.    canvas.height <- 256.    
  450.    let context = canvas.getContext("2d")
  451.    context.fillStyle <- "rgb(0,0,0)"
  452.    context.fillRect (0., 0. , 256., 256.);
  453.  
  454.    let background = createBackground()
  455.    let ghosts = createGhosts(context)
  456.    let pacman = createImage pr1    
  457.  
  458.    let x, y = ref (16 * 8 - 7), ref (23 * 8 - 3)
  459.    
  460.    let logic () =
  461.        ghosts |> Array.iter (fun ghost ->
  462.            let v = chooseDirection ghost
  463.            ghost.Move(v)
  464.        )
  465.        if keys.LeftPressed && canGoLeft(!x,!y) then x:= !x - 1
  466.        if keys.RightPressed && canGoRight(!x,!y) then x := !x + 1
  467.        if keys.UpPressed && canGoUp(!x,!y) then y:= !y - 1
  468.        if keys.DownPressed && canGoDown(!x,!y) then y := !y + 1
  469.  
  470.    let render () =
  471.        context.drawImage(background, 0., 0.)
  472.        context.drawImage(pacman, float !x, float !y)
  473.        ghosts |> Array.iter (fun ghost ->
  474.            context.drawImage(ghost.Image, float ghost.X, float ghost.Y)
  475.        )
  476.  
  477.    let rec update () =
  478.        render ()
  479.        logic ()
  480.        ts.setTimeout(update, 1000. / 60.) |> ignore
  481.  
  482.    update()
  483.  
  484. do Runtime.Run(directory="Web", components=Interop.Components.all)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement