aboutsummaryrefslogtreecommitdiff
path: root/src/Game/Entities/Slime.hs
blob: 1f50927bf9fc19e9fc26c1dd9942d0e6e633b94e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
module Game.Entities.Slime (mkSlime) where

import Data.Bits (Bits (..))
import Game.Entities.Common
import Game.Entities.Const
import Game.Entities.Types
import qualified Game.Sprites as S

mkSlime :: S.SpriteSheet -> Int -> Int -> Collision -> IsBlocked -> IO Entity
mkSlime sprites x y playerCollision isBlocked = do
  s <- S.get sprites "slime"
  pure
    Entity
      { typ = TypeEnemy,
        x = x,
        y = y,
        delay = frameDelay,
        frame = 0,
        jumping = False,
        gravity = gravityOff,
        dir = DirRight,
        sprite = s,
        update = updateSlime playerCollision isBlocked,
        destroy = False,
        actions = []
      }

updateSlime :: Collision -> IsBlocked -> Entity -> IO Entity
updateSlime touchedPlayer isBlocked e = do
  touched <- touchedPlayer e
  let updated = updateSlimeFrame
  pure $ if touched then updated {actions = [ActionHitPlayer]} else updateMovement updated
  where
    updateMovement :: Entity -> Entity
    updateMovement ent
      | testBit ent.delay 1 = ent
      | ent.dir == DirLeft
          && (isBlocked (ent.x - 1) (ent.y + 15) || isBlocked (ent.x - 1) (ent.y + 10) || not (isBlocked (ent.x - 1) (ent.y + 16))) =
          ent {dir = DirRight}
      | ent.dir == DirLeft = ent {x = ent.x - 1}
      | ent.dir == DirRight
          && (isBlocked (ent.x + 16) (ent.y + 15) || isBlocked (ent.x + 16) (ent.y + 10) || not (isBlocked (ent.x + 16) (ent.y + 16))) =
          ent {dir = DirLeft}
      | ent.dir == DirRight = ent {x = ent.x + 1}
      | otherwise = ent
    updateSlimeFrame :: Entity
    updateSlimeFrame
      | e.delay > 0 = e {delay = e.delay - 1}
      | e.frame + 1 < frameLimit e = e {delay = frameDelay + 2, frame = e.frame + 1}
      | otherwise = e {delay = frameDelay + 2, frame = 0}