aboutsummaryrefslogtreecommitdiff
path: root/src/Game/Entities/Shooter.hs
diff options
context:
space:
mode:
authorJuan J. Martinez <jjm@usebox.net>2023-04-17 23:41:35 +0100
committerJuan J. Martinez <jjm@usebox.net>2023-04-17 23:41:35 +0100
commit7a8af18d0e1003c26eb595b5faa71e51da6286a6 (patch)
treed94ea6897570e12d9c044c40e82e9c05921ba64d /src/Game/Entities/Shooter.hs
parentd333eca8c0761e39781af0711a54044cd5ea3c10 (diff)
downloadspace-plat-hs-7a8af18d0e1003c26eb595b5faa71e51da6286a6.tar.gz
space-plat-hs-7a8af18d0e1003c26eb595b5faa71e51da6286a6.zip
Added new shooter enemy
Diffstat (limited to 'src/Game/Entities/Shooter.hs')
-rw-r--r--src/Game/Entities/Shooter.hs67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/Game/Entities/Shooter.hs b/src/Game/Entities/Shooter.hs
new file mode 100644
index 0000000..6e9675f
--- /dev/null
+++ b/src/Game/Entities/Shooter.hs
@@ -0,0 +1,67 @@
+module Game.Entities.Shooter (mkShooter) where
+
+import Data.Bits (Bits (..))
+import Game.Entities.Common
+import Game.Entities.Const
+import Game.Entities.Types
+import qualified Game.Sprites as S
+
+blasterCoolDown :: Int
+blasterCoolDown = 128
+
+mkShooter :: S.SpriteSheet -> Int -> Int -> Dir -> Collision -> Collision -> IsBlocked -> Collision -> IO Entity
+mkShooter sprites x y d playerCollision playerInLine isBlocked playerVsBlast = do
+ s <- S.get sprites "shooter"
+ pure
+ Entity
+ { typ = TypeEnemy,
+ x = x,
+ y = y,
+ delay = frameDelay,
+ frame = 0,
+ set = toSpriteSet d,
+ jumping = False,
+ gravity = gravityOff,
+ dir = d,
+ sprite = s,
+ update = updateShooter playerCollision playerInLine isBlocked playerVsBlast,
+ destroy = False,
+ actions = [],
+ dat = ShooterData 0
+ }
+
+updateShooter :: Collision -> Collision -> IsBlocked -> Collision -> Entity -> IO Entity
+updateShooter touchedPlayer playerInLine isBlocked playerVsBlast e = do
+ touched <- touchedPlayer e
+ line <- playerInLine e
+ pure $ update touched line (updateFrame True (updateCoolDown e))
+ where
+ update :: Bool -> Bool -> Entity -> Entity
+ update wasTouched wasInLine ent
+ | wasInLine && ent.dat.coolDown == 0 =
+ ent
+ { dat = ShooterData blasterCoolDown,
+ actions = [ActionAddBlast blastX (ent.y + 8) ent.dir playerVsBlast isBlocked],
+ frame = 1,
+ delay = frameDelay * 2
+ }
+ | wasTouched = ent {actions = [ActionHitPlayer]}
+ | testBit ent.delay 1 = ent
+ | ent.dir == DirLeft
+ && (isBlocked (ent.x - 1) (ent.y + 17) || isBlocked (ent.x - 1) (ent.y + 17) || not (isBlocked (ent.x - 1) (ent.y + 24))) =
+ ent {dir = DirRight, set = toSpriteSet DirRight}
+ | ent.dir == DirLeft = ent {x = ent.x - 1}
+ | ent.dir == DirRight
+ && (isBlocked (ent.x + 16) (ent.y + 17) || isBlocked (ent.x + 16) (ent.y + 17) || not (isBlocked (ent.x + 16) (ent.y + 24))) =
+ ent {dir = DirLeft, set = toSpriteSet DirLeft}
+ | ent.dir == DirRight = ent {x = ent.x + 1}
+ | otherwise = ent
+
+ updateCoolDown :: Entity -> Entity
+ updateCoolDown ent
+ | ent.dat.coolDown > 0 = ent {dat = ShooterData (ent.dat.coolDown - 1)}
+ | otherwise = ent
+
+ blastX = case e.dir of
+ DirLeft -> e.x - 16
+ DirRight -> e.x + 16