From 11120a24b6927073d55d2e56b4b911817dedaae2 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Wed, 15 Feb 2023 22:53:22 +0000 Subject: Game state, HUD, ... WIP Exploring ideas. --- src/Game/Entities.hs | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) (limited to 'src/Game/Entities.hs') diff --git a/src/Game/Entities.hs b/src/Game/Entities.hs index d0ef4eb..95d9626 100644 --- a/src/Game/Entities.hs +++ b/src/Game/Entities.hs @@ -5,6 +5,8 @@ import Data.IORef import qualified Game.Controller as C import qualified Game.Map as M import qualified Game.Sprites as S +import qualified Game.State as GS +import SDL (($~)) import qualified SDL data Dir = DirRight | DirLeft deriving (Eq) @@ -79,24 +81,20 @@ collision playerRef other = do && player.y + 12 < other.y + 16 && other.y + 4 < player.y + 24 -mkEntities :: S.SpriteSheet -> M.Map -> IORef C.Controls -> IO Entities -mkEntities sprites m controls = do - player <- case find isPlayer (M.objects m) of +mkEntities :: S.SpriteSheet -> M.Map -> IORef C.Controls -> IORef GS.State -> IO Entities +mkEntities sprites m controls stateRef = do + player <- case find M.isPlayer (M.objects m) of Just (M.PlayerEntity x y) -> mkPlayer sprites x y controls (M.isBlocked m) _ -> error "No player entity in map" playerRef <- newIORef player - entities <- traverse (toEntity playerRef) $ filter (not . isPlayer) (M.objects m) + entities <- traverse (toEntity playerRef) $ filter (not . M.isPlayer) (M.objects m) -- the entities list has always player first pure $ Entities sprites playerRef (player : entities) where toEntity :: IORef Entity -> M.Object -> IO Entity - toEntity playerRef (M.BatteryEntity x y) = mkBattery sprites x y playerRef + toEntity playerRef (M.BatteryEntity x y) = mkBattery sprites x y playerRef stateRef toEntity _ (M.PlayerEntity _ _) = error "Player already processed" - isPlayer :: M.Object -> Bool - isPlayer (M.PlayerEntity _ _) = True - isPlayer _ = False - processSpawn :: S.SpriteSheet -> Spawn -> IO Entity processSpawn sprites (DustEffectSpawn x y) = mkEffect sprites x y "dust" @@ -133,7 +131,7 @@ render renderer es = do mkEffect :: S.SpriteSheet -> Int -> Int -> String -> IO Entity mkEffect sprites x y name = do s <- S.get sprites name - pure $ + pure Entity { typ = TypeEffect, x = x, @@ -155,10 +153,10 @@ updateEffect e | e.frame + 1 < frameLimit e = e {delay = frameDelay, frame = e.frame + 1} | otherwise = e {destroy = True} -mkBattery :: S.SpriteSheet -> Int -> Int -> IORef Entity -> IO Entity -mkBattery sprites x y playerRef = do +mkBattery :: S.SpriteSheet -> Int -> Int -> IORef Entity -> IORef GS.State -> IO Entity +mkBattery sprites x y playerRef stateRef = do s <- S.get sprites "battery" - pure $ + pure Entity { typ = TypePickup, x = x, @@ -169,15 +167,19 @@ mkBattery sprites x y playerRef = do gravity = gravityOff, dir = DirRight, sprite = s, - update = updateBattery (collision playerRef), + update = updateBattery (collision playerRef) collectedBattery, destroy = False, spawns = [] } - -updateBattery :: Collision -> Entity -> IO Entity -updateBattery touchedPlayer e = do - -- XXX: how do we update game state? :thinkingface: - (\t -> if t then e {destroy = True} else updateBatteryFrame) <$> touchedPlayer e + where + collectedBattery :: IO () + collectedBattery = do + stateRef $~ (\s -> s {GS.batteries = s.batteries + 1}) + +updateBattery :: Collision -> IO () -> Entity -> IO Entity +updateBattery touchedPlayer collectedBattery e = do + touched <- touchedPlayer e + if touched then e {destroy = True} <$ collectedBattery else pure updateBatteryFrame where updateBatteryFrame :: Entity updateBatteryFrame @@ -188,7 +190,7 @@ updateBattery touchedPlayer e = do mkPlayer :: S.SpriteSheet -> Int -> Int -> IORef C.Controls -> IsBlocked -> IO Entity mkPlayer sprites x y controls isBlocked = do s <- S.get sprites "player" - pure $ + pure Entity { typ = TypePlayer, x = x, -- cgit v1.2.3