From 528154a4645fdb82f623655ded4319d72877444b Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Tue, 16 May 2023 22:52:34 +0100 Subject: Change stage using a simple transition --- src/Game.hs | 34 ++++++++++++++++++++++++---------- src/Game/Entities.hs | 2 +- src/Game/State.hs | 2 +- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/Game.hs b/src/Game.hs index 7ed7ade..3338a8c 100644 --- a/src/Game.hs +++ b/src/Game.hs @@ -13,6 +13,7 @@ import qualified Game.Map as M import qualified Game.Sprites as S import qualified Game.State as GS import qualified Game.Toaster as T +import qualified Game.Utils as U import SDL (($=)) import qualified SDL import qualified SDL.Image @@ -153,10 +154,10 @@ gameLoop e = do ) SDL.rendererRenderTarget renderer $= Just canvas - SDL.clear renderer updatedEnv <- case state.playState of GS.GameOver -> gameOverLoop updatedToasterEnv + GS.ExitDone frames -> nextStageLoop updatedToasterEnv frames _ -> playLoop updatedToasterEnv T.render renderer updatedEnv.toaster @@ -182,6 +183,8 @@ playLoop e = do -- to update the map viewport let (px, py) = E.playerPosition updated + SDL.clear renderer + -- 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 @@ -206,20 +209,30 @@ playLoop e = do | state.batteries == state.totalBatteries && not state.exit = do es <- E.addExit env.entities x (y - 8) -- adjusted to player's height pure env {entities = es, state = state {GS.exit = True}} - | state.playState == GS.ExitDone = do - map' <- M.load (env.mapList !! (env.state.currentLevel + 1)) env.tsTexture - entities <- E.mkEntities env.sprites map' env.controlsRef - pure $ - env - { map = map', - state = (GS.levelState env.state map') {GS.currentLevel = env.state.currentLevel + 1}, - entities = entities - } | otherwise = pure env where state = env.state (x, y) = state.lastBattery +nextStageLoop :: Env -> Int -> IO Env +nextStageLoop e frames + -- erase the screen + | frames < fromIntegral gameWidth = do + SDL.fillRect e.renderer $ Just (U.rect 0 H.height (frames + 8) (fromIntegral gameHeight - H.height)) + pure e {state = e.state {GS.playState = GS.ExitDone $ frames + 8}} + -- some delay after the transition is done + | frames < fromIntegral gameWidth + 32 = + pure e {state = e.state {GS.playState = GS.ExitDone $ frames + 1}} + | otherwise = do + map' <- M.load (e.mapList !! (e.state.currentLevel + 1)) e.tsTexture + entities <- E.mkEntities e.sprites map' e.controlsRef + pure $ + e + { map = map', + state = (GS.levelState e.state map') {GS.currentLevel = e.state.currentLevel + 1}, + entities = entities + } + gameOverLoop :: Env -> IO Env gameOverLoop e = do let renderer = e.renderer @@ -239,6 +252,7 @@ gameOverLoop e = do pure e {state = (GS.levelState e.state map') {GS.lives = GS.maxLives}, entities = entities} else do + SDL.clear renderer H.render renderer hud state title <- S.get sprites "game-over" S.render renderer title 112 80 0 0 diff --git a/src/Game/Entities.hs b/src/Game/Entities.hs index 6ddf589..578bf51 100644 --- a/src/Game/Entities.hs +++ b/src/Game/Entities.hs @@ -116,7 +116,7 @@ updateAll es state = do ((head ents) {typ = TypeEffect} : tail ents) t ActionEntryDone -> processActions s {GS.playState = GS.InPlay} ents t - ActionExitDone -> processActions s {GS.playState = GS.ExitDone} ents t + ActionExitDone -> processActions s {GS.playState = GS.ExitDone 0} ents t ActionAddBlast x y d playerCollision isBlocked -> do blast <- mkBlast es.sprites x y d playerCollision isBlocked processActions s (ents ++ [blast]) t diff --git a/src/Game/State.hs b/src/Game/State.hs index df2d4fa..5c9de0b 100644 --- a/src/Game/State.hs +++ b/src/Game/State.hs @@ -6,7 +6,7 @@ import qualified Game.Map as M maxLives :: Int maxLives = 4 -data PlayState = InPlay | IntoStage | ExitStarted | ExitDone | GameOver deriving (Eq) +data PlayState = InPlay | IntoStage | ExitStarted | ExitDone Int | GameOver deriving (Eq) data State = State { batteries :: Int, -- cgit v1.2.3