aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-05-23 21:54:53 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-05-23 21:54:53 +0100
commita8091dc3c82a4d646e84b356c46319ba54847ce0 (patch)
tree4501765f1b2ae2628d7ecd4dab14670b1f464dd8 /src
parent11b7cbc1eed2ecfaa1f6f678b8d0a1282a5fac83 (diff)
downloadspace-plat-hs-a8091dc3c82a4d646e84b356c46319ba54847ce0.tar.gz
space-plat-hs-a8091dc3c82a4d646e84b356c46319ba54847ce0.zip
Add deadly tiles in the blocked layer
Currently supported by enemies.
Diffstat (limited to 'src')
-rw-r--r--src/Game/Entities.hs4
-rw-r--r--src/Game/Entities/Runner.hs30
-rw-r--r--src/Game/Entities/Tracker.hs6
-rw-r--r--src/Game/Map.hs14
4 files changed, 40 insertions, 14 deletions
diff --git a/src/Game/Entities.hs b/src/Game/Entities.hs
index 578bf51..bea6e33 100644
--- a/src/Game/Entities.hs
+++ b/src/Game/Entities.hs
@@ -51,8 +51,8 @@ mkEntities sprites m controls = do
toEntity playerRef (M.SlimeEntity x y d) = mkSlime sprites x y d (collision playerRef 16) (M.isBlocked m)
toEntity playerRef (M.RobotEntity x y d) = mkRobot sprites x y d (collision playerRef 24) (M.isBlocked m)
toEntity playerRef (M.ShooterEntity x y d) = mkShooter sprites x y d (collision playerRef 24) (inLine playerRef 24) (M.isBlocked m) (collision playerRef 8)
- toEntity playerRef (M.RunnerEntity x y d) = mkRunner sprites x y d (collision playerRef 24) (M.isBlocked m)
- toEntity playerRef (M.TrackerEntity x y d) = mkTracker sprites x y d (collision playerRef 24) (facingLower playerRef) (M.isBlocked m)
+ toEntity playerRef (M.RunnerEntity x y d) = mkRunner sprites x y d (collision playerRef 24) (M.isBlocked m) (M.isBlockedDeadly m)
+ toEntity playerRef (M.TrackerEntity x y d) = mkTracker sprites x y d (collision playerRef 24) (facingLower playerRef) (M.isBlocked m) (M.isBlockedDeadly m)
toEntity playerRef (M.BatteryEntity x y) = mkBattery sprites x y (collision playerRef 16)
toEntity _ (M.PlayerEntity _ _) = error "Player already processed"
diff --git a/src/Game/Entities/Runner.hs b/src/Game/Entities/Runner.hs
index 7d969a5..288f2b4 100644
--- a/src/Game/Entities/Runner.hs
+++ b/src/Game/Entities/Runner.hs
@@ -7,8 +7,8 @@ import Game.Entities.Types
import qualified Game.Sprites as S
import System.Random (randomRIO)
-mkRunner :: S.SpriteSheet -> Int -> Int -> Dir -> Collision -> IsBlocked -> IO Entity
-mkRunner sprites x y d playerCollision isBlocked = do
+mkRunner :: S.SpriteSheet -> Int -> Int -> Dir -> Collision -> IsBlocked -> IsBlocked -> IO Entity
+mkRunner sprites x y d playerCollision isBlocked isBlockedDeadly = do
s <- S.get sprites "runner"
pure
Entity
@@ -22,14 +22,14 @@ mkRunner sprites x y d playerCollision isBlocked = do
gravity = gravityOff,
dir = d,
sprite = s,
- update = updateRunner playerCollision isBlocked,
+ update = updateRunner playerCollision isBlocked isBlockedDeadly,
destroy = False,
actions = [],
dat = RunnerData 0
}
-updateRunner :: Collision -> IsBlocked -> Entity -> IO Entity
-updateRunner touchedPlayer isBlocked e = do
+updateRunner :: Collision -> IsBlocked -> IsBlocked -> Entity -> IO Entity
+updateRunner touchedPlayer isBlocked isBlockedDeadly e = do
touched <- touchedPlayer e
if touched
then pure e {actions = [ActionHitPlayer]}
@@ -41,21 +41,35 @@ updateRunner touchedPlayer isBlocked e = do
updateMovement ent
| testBit ent.delay 1 = pure ent
| ent.dir == DirLeft
- && (isBlocked (ent.x - 1) (ent.y + 17) || isBlocked (ent.x - 1) (ent.y + 17)) =
+ && ( isBlocked (ent.x - 1) (ent.y + 17)
+ || isBlocked (ent.x - 1) (ent.y + 17)
+ || checkDeadlyFloor (ent.x - 1) (ent.y + 24)
+ ) =
tryJumpingOrTurn ent
| ent.dir == DirLeft = pure ent {x = ent.x - 1}
| ent.dir == DirRight
- && (isBlocked (ent.x + 16) (ent.y + 17) || isBlocked (ent.x + 16) (ent.y + 17)) =
+ && ( isBlocked (ent.x + 16) (ent.y + 17)
+ || isBlocked (ent.x + 16) (ent.y + 17)
+ || checkDeadlyFloor (ent.x + 16) (ent.y + 24)
+ ) =
tryJumpingOrTurn ent
| ent.dir == DirRight = pure ent {x = ent.x + 1}
| otherwise = pure ent
+ checkDeadlyFloor :: Int -> Int -> Bool
+ checkDeadlyFloor x y
+ | isBlockedDeadly x y = True
+ | isBlocked x y = False
+ | otherwise = checkDeadlyFloor x (y + 8)
+
randomWallCount :: [Int]
randomWallCount = [0, 0, 0, 2, 2, 3]
tryJumpingOrTurn :: Entity -> IO Entity
tryJumpingOrTurn ent
- | ent.dat.wallCount > 2 && not (isBlocked (ent.x + 8) (ent.y + 24 + 8)) = do
+ | ent.dat.wallCount > 2
+ && not (isBlocked (ent.x + 8) (ent.y + 24 + 8))
+ && not (checkDeadlyFloor (ent.x + 8) (ent.y + 24 + 8)) = do
r <- randomRIO (0, length randomWallCount - 1) :: IO Int
pure
ent
diff --git a/src/Game/Entities/Tracker.hs b/src/Game/Entities/Tracker.hs
index ef7325f..80b8574 100644
--- a/src/Game/Entities/Tracker.hs
+++ b/src/Game/Entities/Tracker.hs
@@ -5,10 +5,10 @@ import Game.Entities.Runner
import Game.Entities.Types
import qualified Game.Sprites as S
-mkTracker :: S.SpriteSheet -> Int -> Int -> Dir -> Collision -> Collision -> IsBlocked -> IO Entity
-mkTracker sprites x y d playerCollision facingPlayerLower isBlocked = do
+mkTracker :: S.SpriteSheet -> Int -> Int -> Dir -> Collision -> Collision -> IsBlocked -> IsBlocked -> IO Entity
+mkTracker sprites x y d playerCollision facingPlayerLower isBlocked isBlockedDeadly = do
s <- S.get sprites "tracker"
- runner <- mkRunner sprites x y d playerCollision isBlocked
+ runner <- mkRunner sprites x y d playerCollision isBlocked isBlockedDeadly
pure runner {sprite = s, update = updateTracker runner.update facingPlayerLower isBlocked}
updateTracker :: (Entity -> IO Entity) -> Collision -> IsBlocked -> Entity -> IO Entity
diff --git a/src/Game/Map.hs b/src/Game/Map.hs
index 29597dd..d585ff6 100644
--- a/src/Game/Map.hs
+++ b/src/Game/Map.hs
@@ -10,6 +10,7 @@ module Game.Map
render,
update,
isBlocked,
+ isBlockedDeadly,
isPlayer,
Viewport (..),
viewport,
@@ -31,6 +32,9 @@ import Text.JSON.Types
frameDelay :: Int
frameDelay = 6
+deadlyTileId :: Int
+deadlyTileId = 29
+
data Tileset = Tileset
{ cols :: Int,
width :: Int,
@@ -235,13 +239,21 @@ load filename tex = do
_ -> Nothing
-- | Check for collision detection vs "Blocked" TileLayer.
--- x and y in pixels.
+-- x and y in pixels.
isBlocked :: Map -> Int -> Int -> Bool
isBlocked (Map (MapData mapWidth _ tilesets _ blocked _) _ _) x y =
blocked Vector.! ((x `div` ts.width) + (y `div` ts.height) * mapWidth) >= ts.firstGid
where
ts = Vector.head tilesets
+-- | Check for collision detection vs deadly tiles in "Blocked" TileLayer.
+-- x and y in pixels.
+isBlockedDeadly :: Map -> Int -> Int -> Bool
+isBlockedDeadly (Map (MapData mapWidth _ tilesets _ blocked _) _ _) x y =
+ blocked Vector.! ((x `div` ts.width) + (y `div` ts.height) * mapWidth) == deadlyTileId + ts.firstGid
+ where
+ ts = Vector.head tilesets
+
-- | Return the objects in a map.
objects :: Map -> [Object]
objects (Map md _ _) = Vector.toList md.objects