on d178521 help sign in
elk/Examples/elm-js/FrameRate/FrameRate.elm
72 lines 1.8 kB history raw
2module FrameRate where
4import Data.Maybe (mapMaybe)
5import Foreign.JavaScript
6import Signal.Keyboard.Raw
7import Signal.Input
9(drop,dFPS) = dropDown
10 [ ( "30", 30)
11 , ( "4", 4)
12 , ( "10", 10)
13 , ( "60", 60)
14 , ("100", 100) ]
16desiredFPS = lift castIntToJSNumber dFPS
17foreign export jsevent "desiredFPS"
18 desiredFPS :: Signal JSNumber
21foreign import jsevent "trigger" (castIntToJSNumber 0)
22 jsTime :: Signal JSNumber
24time = lift castJSNumberToFloat jsTime
27-- Calculate FPS based on incoming times.
29getFPS ts =
30 let len = length ts in
31 if len > 1 then (len-1) / (head ts - last ts) else 0
32fps = lift (truncate . getFPS) (foldp (\t ts -> take 10 (t:ts)) [0] time)
35-- Use time and keyboard input to determine the
36-- position of the black square.
38addVecs (x1,y1) (x2,y2) = (x1+x2, y1+y2)
39scaleBy s (x,y) = (x*s, y*s)
41addKey k (x,y) =
42 if k < 37 || k > 40 then (x,y) else
43 if k `mod` 2 == 1 then (x + k - 38, y)
44 else (x, y + k - 39)
46velocity = lift (foldl addKey (0,0)) keysDown
48timestep = lift snd $ foldp (\t1 (t0,d) -> (t1, t1-t0)) (0,0) time
50delta = dropIf (\(x,y) -> x == 0 && y == 0) (0,0) . sampleOn timestep $
51 lift (scaleBy 100) (lift2 scaleBy timestep velocity)
53position = foldp addVecs (0,0) delta
56-- Display moving square and FPS on screen.
58screen pos actual =
59 flow down [ collage 400 400 [ outlined black (rect 40 40 pos) ]
60 , plainText "Move the square around with the arrow keys."
61 , text $ toText "Actual frames per second: " ++ show actual
62 , plainText "Desired frames per second: " `beside` drop
63 ]
66game = lift2 screen position fps
68done = lift (\_ -> castBoolToJSBool True) game
69foreign export jsevent "finished"
70 done :: Signal JSBool
72main = game