aboutsummaryrefslogtreecommitdiff
path: root/src/Game
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-02-07 12:10:02 +0000
committerJuan J. Martinez <jjm@usebox.net>2023-02-07 12:10:02 +0000
commit54d3f5a32758eb92606338d28a13652bcf51375c (patch)
tree6ac4d319fc60539717fd80de8dae6d42e2a6d60d /src/Game
parenta7799c2098ef1cd549c852eb2063f5c3a6c9d039 (diff)
downloadspace-plat-hs-54d3f5a32758eb92606338d28a13652bcf51375c.tar.gz
space-plat-hs-54d3f5a32758eb92606338d28a13652bcf51375c.zip
Implemented "Coyote time" to make jumping easier
Diffstat (limited to 'src/Game')
-rw-r--r--src/Game/Entities.hs55
1 files changed, 47 insertions, 8 deletions
diff --git a/src/Game/Entities.hs b/src/Game/Entities.hs
index 66d2da6..b42f232 100644
--- a/src/Game/Entities.hs
+++ b/src/Game/Entities.hs
@@ -1,5 +1,3 @@
-{-# OPTIONS_GHC -Wno-unused-top-binds #-}
-
module Game.Entities (Entities, mkEntities, mkPlayer, mkEffect, append, update, render) where
import Data.Foldable (traverse_)
@@ -29,7 +27,10 @@ gravityUp :: Int
gravityUp = 0
gravityDown :: Int
-gravityDown = 16
+gravityDown = 14
+
+jumpLimit :: Int
+jumpLimit = gravityDown + 7
gravityTable :: [Int]
gravityTable = [0, 6, 4, 4, 2, 2, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 4]
@@ -45,6 +46,7 @@ data Entity = Entity
eDelay :: Int,
eFrame :: Int,
eFrameLimit :: Int,
+ eJumping :: Bool,
eGravity :: Int,
eDir :: Dir,
eSprite :: S.Sprite,
@@ -86,7 +88,23 @@ render renderer (Entities _ entities) = do
mkEffect :: S.SpriteSheet -> Int -> Int -> String -> IO Entity
mkEffect sprites x y name = do
s <- S.get sprites name
- pure $ Entity TypeEffect x y frameDelay 0 3 gravityOff DirRight s (pure . updateEffect) (\_ _ -> False) False []
+ pure $
+ Entity
+ { eType = TypeEffect,
+ eX = x,
+ eY = y,
+ eDelay = frameDelay,
+ eFrame = 0,
+ eFrameLimit = 3,
+ eJumping = False,
+ eGravity = gravityOff,
+ eDir = DirRight,
+ eSprite = s,
+ eUpdate = pure . updateEffect,
+ eBlocked = \_ _ -> False,
+ eDestroy = False,
+ eSpawns = []
+ }
updateEffect :: Entity -> Entity
updateEffect e
@@ -101,7 +119,23 @@ updateEffect e
mkPlayer :: S.SpriteSheet -> Int -> Int -> IORef C.Controls -> (Int -> Int -> Bool) -> IO Entity
mkPlayer sprites x y controls isBlocked = do
s <- S.get sprites "player"
- pure $ Entity TypePlayer x y 0 0 3 gravityOff DirRight s (updatePlayer controls) isBlocked False []
+ pure $
+ Entity
+ { eType = TypePlayer,
+ eX = x,
+ eY = y,
+ eDelay = 0,
+ eFrame = 0,
+ eFrameLimit = 3,
+ eJumping = False,
+ eGravity = gravityOff,
+ eDir = DirRight,
+ eSprite = s,
+ eUpdate = updatePlayer controls,
+ eBlocked = isBlocked,
+ eDestroy = False,
+ eSpawns = []
+ }
updateFrame :: Bool -> Entity -> Entity
updateFrame updated e
@@ -136,8 +170,12 @@ updateHorizontal left right e
updateVertical :: Bool -> Bool -> Entity -> Entity
updateVertical jump down e
- | not jump || gravity /= gravityOff = e
- | not down = e {eGravity = gravityUp, eFrame = jumpFrame, eSpawns = events ++ [DustEffectSpawn x (y + 8)]}
+ | not jump
+ || jumping
+ -- make jumping easier with "Coyote time"
+ || (gravity /= gravityOff && (gravity < gravityDown || gravity > jumpLimit)) =
+ e
+ | not down = e {eJumping = True, eGravity = gravityUp, eFrame = jumpFrame, eSpawns = events ++ [DustEffectSpawn x (y + 8)]}
-- go down a 8 pixel tall platform; not ideal to have these values hardcoded here
-- but to be fair, the player height/width is hardcoded as well
| down
@@ -148,6 +186,7 @@ updateVertical jump down e
where
x = eX e
y = eY e
+ jumping = eJumping e
gravity = eGravity e
isBlocked = eBlocked e
events = eSpawns e
@@ -160,7 +199,7 @@ applyGravity v e
&& (isBlocked (x + 2) (y + 24) || isBlocked (x + 12) (y + 24))
&& not (isBlocked (x + 2) (y + 23))
&& not (isBlocked (x + 12) (y + 23)) =
- e {eGravity = gravityOff, eDelay = 0}
+ e {eJumping = False, eGravity = gravityOff, eDelay = 0}
| otherwise = applyGravity (v - 1) e {eY = y + change}
where
gravity = eGravity e