/
GameState.hs
89 lines (78 loc) · 2.26 KB
/
GameState.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
84
85
86
87
88
89
module GameState
( GameState(State)
, Entity(Entity)
, Options(Options)
, KeyBindings
, initialState
, entities
, options
, deltaTime
, elapsedTime
, updateGameState
, renderGameState
, initialOptions
, screenRes
, frameLimit
, keybindings
, processInput
, eID
, update
, render
) where
import Control.Monad
import Foreign.C.Types
import SDL
import qualified SDL
import InputModule
-- Hands the current state of the game to various functions
data GameState =
State
{ options :: Options
, deltaTime :: CDouble
, elapsedTime :: CDouble
, entities :: [Entity]
}
data Entity =
Entity
{ eID :: Int
, update :: GameState -> Entity
, render :: SDL.Renderer -> IO ()
}
-- We will need this later so just making a newtype for now
data Options =
Options
{ screenRes :: (CInt, CInt)
, frameLimit :: Int
, keybindings :: KeyBindings GameState
}
initialState :: GameState
initialState = State initialOptions 0 0 []
initialOptions :: Options
initialOptions =
Options
{ screenRes = (1440, 1080)
, frameLimit = 60
, keybindings = blankKeyBindings :: KeyBindings GameState
}
-- Change the gamestate with input
processInput :: GameState -> SDL.EventPayload -> GameState
processInput state@(State (Options _ _ kbs) _ _ _) input = exec $ join func
where func = getBoundInput kbs <$> processEvent input
exec (Just f) = f state
exec _ = state
-- Retrieves the keycode and press-status of key
processEvent :: SDL.EventPayload -> Maybe (SDL.Keycode, Bool)
processEvent (SDL.KeyboardEvent (SDL.KeyboardEventData _ SDL.Pressed False (SDL.Keysym _ code _))) = Just (code, True)
processEvent (SDL.KeyboardEvent (SDL.KeyboardEventData _ SDL.Released _ (SDL.Keysym _ code _))) = Just (code, False)
processEvent _ = Nothing
-- Updates the game state's entities
updateGameState :: GameState -> CDouble -> GameState
updateGameState state delta =
state
{ deltaTime = delta
, elapsedTime = elapsedTime state + delta
, entities = map (\(Entity _ up _) -> up state) (entities state)
}
-- Renders the game state's entities
renderGameState :: GameState -> SDL.Renderer -> IO [()]
renderGameState state renderer = sequence $ map (\(Entity _ _ rend) -> rend renderer) $ entities state