pang-a-lambda-0.2.0.0: Experiments/circling-boxes/Main.hs
{-# LANGUAGE Arrows #-}
import Graphics.UI.SDL as SDL
import FRP.Yampa as Yampa
import Data.IORef
width = 640
height = 480
main = do
timeRef <- newIORef (0 :: Int)
reactimate initGraphs
(\_ -> do
dtSecs <- yampaSDLTimeSense timeRef
return (dtSecs, Nothing))
(\_ e -> display e >> return False)
inCirclesL
-- | 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 xs = 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 0 0
let side = 10
let paintSquare (x,y) =
fillRect screen (Just (Rect (round x) (round y) side side)) red
mapM_ paintSquare xs
-- Double buffering
SDL.flip screen
inCirclesL :: SF () [(Double, Double)]
inCirclesL = parB [ inCircles (100, 100)
, inCircles (200, 200)
]
inCircles :: (Double, Double) -> SF () (Double, Double)
inCircles (baseX, baseY) = proc () -> do
t <- (/5) ^<< localTime -< ()
let radius = 30
x = baseX + (cos t * radius)
y = baseY + (sin t * radius)
returnA -< (x,y)