pang-a-lambda-0.2.0.0: Experiments/stickyarrowup/Main.hs
{-# LANGUAGE Arrows #-}
import Graphics.UI.SDL as SDL
import Graphics.UI.SDL.Primitives as SDL
import FRP.Yampa as Yampa
import Data.IORef
import Debug.Trace
width = 640
height = 480
main = do
timeRef <- newIORef (0 :: Int)
reactimate initGraphs
(\_ -> do
dtSecs <- yampaSDLTimeSense timeRef
return (dtSecs, Nothing))
(\_ e -> display e >> return False)
(fire (fromIntegral height / 2) (-10))
-- | Updates the time in an IO Ref and returns the time difference
updateTime :: IORef Int -> Int -> IO Int
updateTime timeRef newTime = do
previousTime <- readIORef timeRef
writeIORef timeRef newTime
return (newTime - previousTime)
yampaSDLTimeSense :: IORef Int -> IO Yampa.DTime
yampaSDLTimeSense timeRef = do
-- Get time passed since SDL init
newTime <- fmap fromIntegral SDL.getTicks
-- Obtain time difference
dt <- updateTime timeRef newTime
let dtSecs = fromIntegral dt / 100
return dtSecs
initGraphs :: IO ()
initGraphs = do
-- Initialise SDL
SDL.init [InitVideo]
-- Create window
screen <- setVideoMode width height 16 [SWSurface]
setCaption "Test" ""
display :: (Double, Double) -> IO()
display (boxY0,boxY) = do
-- Obtain surface
screen <- getVideoSurface
-- Paint screen green
let format = surfaceGetPixelFormat screen
green <- mapRGB format 0 0xFF 0
fillRect screen Nothing green
-- Paint small red square, at an angle 'angle' with respect to the center
red <- mapRGB format 0xFF 0xFF 0
let x = fromIntegral $ width `div` 2
y0 = round boxY0
y = round boxY
vLine screen x y0 y red
-- Double buffering
SDL.flip screen
rising :: Double -> Double -> SF () (Double, Double)
rising y0 v0 = proc () -> do
y <- (y0+) ^<< integral -< v0
returnA -< (y0, y)
fire :: Double -> Double -> SF () (Double, Double)
fire y vy = switch (rising y vy >>> (Yampa.identity &&& hitCeiling))
(\(y0, yn) -> switch (constant (y0, yn) &&& after 10 ())
(\_ -> fire y vy))
hitCeiling :: SF (Double, Double) (Yampa.Event (Double, Double))
hitCeiling = arr (\(y0,y) ->
let boxTop = y
in if boxTop < 0
then Yampa.Event (y0, y)
else Yampa.NoEvent)