From 7a8af18d0e1003c26eb595b5faa71e51da6286a6 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Mon, 17 Apr 2023 23:41:35 +0100 Subject: Added new shooter enemy --- src/Game/Entities/Shooter.hs | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/Game/Entities/Shooter.hs (limited to 'src/Game/Entities/Shooter.hs') 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 -- cgit v1.2.3