-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgl.hs
68 lines (51 loc) · 2.37 KB
/
gl.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
import Graphics.Rendering.OpenGL
import Graphics.UI.GLUT
import System.Random
import Data.IORef
import GHC.IO
type Healh = Float
newtype XYPosition = XYPosition { getXYPosition :: (GLfloat, GLfloat) } deriving (Show)
data Soldier = Soldier { status :: (Healh, XYPosition) }
newtype Everything = Everything { soldiers :: [Soldier] }
main = do
(progname, _) <- getArgsAndInitialize
createWindow "Moving soldiers"
initEverythingIORef <- initEverything
displayCallback $= (display initEverythingIORef)
addTimerCallback 100 (updateCallback initEverythingIORef)
mainLoop
initEverything :: IO (IORef Everything)
initEverything = newIORef $ Everything [Soldier (1, XYPosition (0.1, 0.1)), Soldier (1, XYPosition (0.4, 0.4)) ]
updateSoldier :: Soldier -> Soldier
updateSoldier (Soldier (health, position)) = Soldier (health, newXYPosition)
where newXYPosition = let (x, y) = getXYPosition position in XYPosition (newPos x, newPos y)
newPos a = (unsafePerformIO (randomRIO(0.1::GLfloat,0.9::GLfloat)))
updateSoldiers :: [Soldier] -> [Soldier]
updateSoldiers x = foldl (\a soldier -> (updateSoldier soldier) : a) [] x
changeEverything :: IORef Everything -> IO ()
changeEverything everythingIoref = do
e <- readIORef everythingIoref
let newEverything = e { soldiers = (updateSoldiers $ soldiers e)}
writeIORef everythingIoref newEverything
return ()
getSoldierPositions :: Everything -> [(GLfloat, GLfloat)]
getSoldierPositions e = foldl (\a soldier -> (getXYPosition . snd . status $ soldier) : a) [] $ soldiers e
updateCallback :: IORef Everything -> IO ()
updateCallback everything = do
postRedisplay Nothing
changeEverything everything
addTimerCallback 100 (updateCallback everything)
display :: IORef Everything -> IO ()
display everything = do
newEverything <- readIORef everything
clear [ColorBuffer]
pointSize $= 10
renderPrimitive Points $ do
renderPrimitive Points $ mapM_ (\(x, y)->vertex $ Vertex2 x y) $ getSoldierPositions newEverything
color $ soldierColor
flush
swapBuffers
where soldierColor = let a = 0.3 :: GLfloat
b = 0.7 :: GLfloat
in
Color4 a b a b