aboutsummaryrefslogtreecommitdiff
path: root/src/Game.hs
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-03-02 12:54:47 +0000
committerJuan J. Martinez <jjm@usebox.net>2023-03-02 12:54:47 +0000
commite5cbf917ad8b12b48932bc4fa13a044bc8159a74 (patch)
tree41511ca9f1447643ac921b2294f5dab8a62731e2 /src/Game.hs
parent5dd9180606e935ee5a7c1637773fdfc3277677ca (diff)
downloadspace-plat-hs-e5cbf917ad8b12b48932bc4fa13a044bc8159a74.tar.gz
space-plat-hs-e5cbf917ad8b12b48932bc4fa13a044bc8159a74.zip
Even less IORef
Also reviewed comments and made the action to add effects more general.
Diffstat (limited to 'src/Game.hs')
-rw-r--r--src/Game.hs71
1 files changed, 37 insertions, 34 deletions
diff --git a/src/Game.hs b/src/Game.hs
index 41c8178..851b7fc 100644
--- a/src/Game.hs
+++ b/src/Game.hs
@@ -47,8 +47,8 @@ data Env = Env
font :: BF.BitmapFont,
entities :: E.Entities,
hud :: H.Hud,
- controls :: IORef C.Controls,
- state :: IORef GS.State
+ state :: GS.State,
+ controls :: IORef C.Controls
}
defaultRenderRect :: SDL.Rectangle CInt
@@ -77,19 +77,18 @@ main = do
map' <- M.load "data/map.json" tsTexture
sprites <- S.load "data/sprites.json" ssTexture
font <- BF.load "data/font.json" bfTexture
- state <-
- newIORef
- GS.State
- { batteries = 0,
- totalBatteries = M.totalBatteries map',
- lives = maxLives,
- totalLives = maxLives,
- hitDelay = 0,
- gameOverDelay = 0
- }
controls <- newIORef =<< C.init
- hud <- H.mkHud sprites state
- entities <- E.mkEntities sprites map' controls state
+ entities <- E.mkEntities sprites map' controls
+ hud <- H.mkHud sprites
+ let initialState =
+ GS.State
+ { batteries = 0,
+ totalBatteries = M.totalBatteries map',
+ lives = maxLives,
+ totalLives = maxLives,
+ hitDelay = 0,
+ gameOverDelay = 0
+ }
gameLoop
Env
{ window = window,
@@ -102,8 +101,8 @@ main = do
font = font,
entities = entities,
hud = hud,
- controls = controls,
- state = state
+ state = initialState,
+ controls = controls
}
SDL.destroyWindow window
SDL.quit
@@ -140,8 +139,7 @@ gameLoop e = do
canvas = env.canvas
renderRect = env.renderRect
controls = env.controls
- stateRef = env.state
- entities = env.entities
+ state = env.state
-- ESC or close the window to quit
let quit = fromMaybe False (U.isPressed SDL.KeycodeEscape events) || SDL.QuitEvent `elem` events
@@ -152,11 +150,7 @@ gameLoop e = do
SDL.rendererRenderTarget renderer $= Just canvas
SDL.clear renderer
- state <- readIORef stateRef
- when (state.gameOverDelay > 1) $ stateRef $= state {GS.gameOverDelay = state.gameOverDelay - 1}
- when (state.gameOverDelay == 1) $ gameOverLoop env
-
- updatedEntities <- if state.gameOverDelay /= 1 then playLoop env else pure entities
+ updatedEnv <- if state.gameOverDelay /= 1 then playLoop (updateState env) else gameOverLoop env
SDL.rendererRenderTarget renderer $= Nothing
SDL.clear renderer
@@ -164,39 +158,48 @@ gameLoop e = do
SDL.present renderer
- gameLoop env {entities = updatedEntities}
-
-playLoop :: Env -> IO E.Entities
+ gameLoop updatedEnv
+ where
+ -- update state counters
+ updateState :: Env -> Env
+ updateState env
+ | state.gameOverDelay > 1 = env {state = state {GS.gameOverDelay = state.gameOverDelay - 1}}
+ | otherwise = env
+ where
+ state = env.state
+
+playLoop :: Env -> IO Env
playLoop e = do
let renderer = e.renderer
map' = e.map
entities = e.entities
hud = e.hud
- updated <- E.updateAll entities
+ (updated, state) <- E.updateAll entities e.state
-- to update the map viewport
let (px, py) = E.playerPosition updated
- -- render map and entities
-
-- set the SDL viewport
viewport <- M.viewport renderer map' px py (fromIntegral gameWidth) (fromIntegral gameHeight - H.height) (Just (0, H.height))
+ -- render map and entities
M.render renderer map' viewport
- E.renderVisible renderer updated viewport
+ E.renderVisible renderer updated viewport state
-- reset viewport to draw the HUD
SDL.rendererViewport renderer $= Nothing
- H.render renderer hud
+ H.render renderer hud state
- pure updated
+ pure e {state = state, entities = updated}
-gameOverLoop :: Env -> IO ()
+gameOverLoop :: Env -> IO Env
gameOverLoop e = do
let renderer = e.renderer
sprites = e.sprites
+ state = e.state
hud = e.hud
- H.render renderer hud
+ H.render renderer hud state
title <- S.get sprites "game-over"
S.render renderer title 112 80 0 0
+ pure e