module Game.Entities.Blast (mkBlast) where import Data.Bits (Bits (..)) import Game.Entities.Const import Game.Entities.Types import qualified Game.Sprites as S mkBlast :: S.SpriteSheet -> Int -> Int -> Dir -> Collision -> IsBlocked -> IO Entity mkBlast sprites x y dir playerCollision isBlocked = do s <- S.get sprites "blast" pure Entity { typ = TypeEnemy, x = x, y = y, delay = frameDelay, frame = 0, set = 0, jumping = False, gravity = gravityOff, dir = dir, sprite = s, update = updateBlast playerCollision isBlocked, destroy = False, actions = [], dat = NoData } updateBlast :: Collision -> IsBlocked -> Entity -> IO Entity updateBlast touchedPlayer isBlocked e = do touched <- touchedPlayer e pure $ if touched then e {destroy = True, actions = [ActionHitPlayer, ActionAddEffect (e.x + 4) e.y "impact"]} else update where update | e.dir == DirLeft && isBlocked (e.x - 1) (e.y + 4) = e {destroy = True, actions = [ActionAddEffect e.x e.y "impact"]} | e.dir == DirLeft = updatedFrame {x = e.x - 1} | e.dir == DirRight && isBlocked (e.x + 16) (e.y + 4) = e {destroy = True, actions = [ActionAddEffect (e.x + 8) e.y "impact"]} | e.dir == DirRight = updatedFrame {x = e.x + 1} | otherwise = updatedFrame updatedFrame = if e.delay > 0 then e {delay = e.delay - 1} else e {delay = frameDelay, frame = e.frame `xor` 1}