From f886dc2f03a75b12749ad029134b70c346aea194 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Tue, 23 May 2023 22:52:01 +0100 Subject: Deadly blocks kill the player Implemented "auto-checkpoints" based on where the player lands after a jump. --- src/Game/Entities.hs | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src/Game/Entities.hs') diff --git a/src/Game/Entities.hs b/src/Game/Entities.hs index bea6e33..5e1af65 100644 --- a/src/Game/Entities.hs +++ b/src/Game/Entities.hs @@ -38,7 +38,7 @@ import qualified SDL mkEntities :: S.SpriteSheet -> M.Map -> IORef C.Controls -> IO Entities mkEntities sprites m controls = do player <- case find M.isPlayer (M.objects m) of - Just (M.PlayerEntity x y) -> mkPlayer sprites x y controls (M.isBlocked m) + Just (M.PlayerEntity x y) -> mkPlayer sprites x y controls (M.isBlocked m) (M.isBlockedDeadly m) _ -> error "No player entity in map" playerRef <- newIORef player entities <- traverse (toEntity playerRef) $ sort $ filter (not . M.isPlayer) (M.objects m) @@ -97,18 +97,11 @@ updateAll es state = do ActionAddBattery x y -> processActions s {GS.batteries = s.batteries + 1, GS.lastBattery = (x, y)} ents t ActionHitPlayer -> do - let (s', ents') = - if s.lives == 1 - then - ( s {GS.lives = 0, GS.gameOverDelay = gameOverDelay}, - -- the player is not in the action, changing then type disables collision detection - (head ents) {typ = TypeEffect, set = dyingSet, gravity = gravityUp, frame = 0} : tail ents - ) - else - ( s {GS.lives = s.lives - 1, GS.hitDelay = hitDelay}, - ents - ) + let (s', ents') = processPlayerHitAction s ents processActions s' ents' t + ActionHitPlayerDeadly -> do + let (s', ents') = processPlayerHitAction s ents + processActions s' (playerToCheckpoint s'.lives (head ents') : tail ents') t ActionExitStarted -> processActions s {GS.playState = GS.ExitStarted} @@ -122,6 +115,24 @@ updateAll es state = do processActions s (ents ++ [blast]) t processActions s ents [] = pure (s, ents) + playerToCheckpoint :: Int -> Entity -> Entity + playerToCheckpoint lives p + | lives == 0 = p + | otherwise = p {x = p.dat.checkx, y = p.dat.checky} + + processPlayerHitAction :: GS.State -> [Entity] -> (GS.State, [Entity]) + processPlayerHitAction s ents = + if s.lives == 1 + then + ( s {GS.lives = 0, GS.gameOverDelay = gameOverDelay, GS.hitDelay = 0}, + -- the player is not in the action, changing then type disables collision detection + (head ents) {typ = TypeEffect, set = dyingSet, gravity = gravityUp, frame = 0} : tail ents + ) + else + ( s {GS.lives = s.lives - 1, GS.hitDelay = hitDelay}, + ents + ) + -- Update entities skipping enemies if the player was hit updateFilter :: Bool -> Entity -> IO Entity updateFilter False e = e.update e -- cgit v1.2.3