forked from composewell/streamly
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCirclingSquare.hs
83 lines (67 loc) · 2.48 KB
/
CirclingSquare.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
-- Adapted from the Yampa package.
-- Displays a square moving in a circle. To move the position drag it with the
-- mouse.
--
-- Requires the SDL package, assuming streamly has already been built, you can
-- compile it like this:
-- stack ghc --package SDL CirclingSquare.hs
import Data.IORef
import Graphics.UI.SDL as SDL
import Streamly
import Streamly.Prelude as S
------------------------------------------------------------------------------
-- SDL Graphics Init
------------------------------------------------------------------------------
sdlInit :: IO ()
sdlInit = do
SDL.init [InitVideo]
let width = 640
height = 480
_ <- SDL.setVideoMode width height 16 [SWSurface]
SDL.setCaption "Test" ""
------------------------------------------------------------------------------
-- Display a box at a given coordinates
------------------------------------------------------------------------------
display :: (Double, Double) -> IO ()
display (playerX, playerY) = do
screen <- getVideoSurface
-- Paint screen green
let format = surfaceGetPixelFormat screen
bgColor <- mapRGB format 55 60 64
_ <- fillRect screen Nothing bgColor
-- Paint small red square, at an angle 'angle' with respect to the center
foreC <- mapRGB format 212 108 73
let side = 20
x = round playerX
y = round playerY
_ <- fillRect screen (Just (Rect x y side side)) foreC
-- Double buffering
SDL.flip screen
------------------------------------------------------------------------------
-- Wait and update Controller Position if it changes
------------------------------------------------------------------------------
updateController :: IORef (Double, Double) -> IO ()
updateController ref = do
e <- pollEvent
case e of
MouseMotion x y _ _ -> writeIORef ref (fromIntegral x, fromIntegral y)
_ -> return ()
------------------------------------------------------------------------------
-- Periodically refresh the output display
------------------------------------------------------------------------------
updateDisplay :: IORef (Double, Double) -> IO ()
updateDisplay cref = do
time <- SDL.getTicks
(x, y) <- readIORef cref
let t = fromIntegral time * speed / 1000
in display (x + cos t * radius, y + sin t * radius)
where
speed = 6
radius = 60
main :: IO ()
main = do
sdlInit
cref <- newIORef (0,0)
S.drain $ asyncly $ constRate 40
$ S.repeatM (updateController cref)
`parallel` S.repeatM (updateDisplay cref)