diff --git a/fcore/enemy-behaviour.sml b/fcore/enemy-behaviour.sml index 759bb51..bf75e25 100644 --- a/fcore/enemy-behaviour.sml +++ b/fcore/enemy-behaviour.sml @@ -19,6 +19,25 @@ struct (x, y, searchWidth, searchHeight, 0, 0, ww, wh, ~1, platformTree) end + fun isOnGround (enemy, wallTree, platformTree) = + let + val {x = ex, y = ey, ...} = enemy + + val ey = ey + Constants.enemySize - 1 + + val width = Constants.enemySize + val height = 2 + + val ww = Constants.worldWidth + val wh = Constants.worldHeight + in + QuadTree.hasCollisionAt + (ex, ey, width, height, 0, 0, ww, wh, ~1, wallTree) + orelse + QuadTree.hasCollisionAt + (ex, ey, width, height, 0, 0, ww, wh, ~1, platformTree) + end + fun getPatrollPatches (enemy: enemy, wallTree, platformTree, acc) = let (* This function is meant to check @@ -111,6 +130,26 @@ struct | STAY_STILL => acc end + (* pathfinding *) + fun getFollowPatches (player: player, enemy, wallTree, platformTree, acc) = + let + val {x = px, y = py, ...} = player + val {x = ex, y = ey, yAxis = eyAxis, ...} = enemy + + val xAxis = if px < ex then MOVE_LEFT else MOVE_RIGHT + + val isOnGround = isOnGround (enemy, wallTree, platformTree) + val yAxis = + if ey > py andalso isOnGround then + case eyAxis of + ON_GROUND => JUMPING 0 + | FALLING => JUMPING 0 + | _ => eyAxis + else + eyAxis + in + EnemyPatch.W_Y_AXIS yAxis :: EnemyPatch.W_X_AXIS xAxis :: acc + end fun getVariantPatches (enemy, walls, wallTree, platforms, platformTree, player, acc) = @@ -119,5 +158,7 @@ struct in case #variant enemy of PATROL_SLIME => getPatrollPatches (enemy, wallTree, platformTree, acc) + | FOLLOW_SIME => + getFollowPatches (player, enemy, wallTree, platformTree, acc) end end diff --git a/fcore/enemy-variants.sml b/fcore/enemy-variants.sml index 7c60368..2f21201 100644 --- a/fcore/enemy-variants.sml +++ b/fcore/enemy-variants.sml @@ -1,6 +1,7 @@ signature ENEMY_VARIANTS = sig - datatype t = PATROL_SLIME + datatype t = PATROL_SLIME | FOLLOW_SLIME end -structure EnemyVariants: ENEMY_VARIANTS = struct datatype t = PATROL_SLIME end +structure EnemyVariants: ENEMY_VARIANTS = +struct datatype t = PATROL_SLIME | FOLLOW_SLIME end diff --git a/fcore/enemy.sml b/fcore/enemy.sml index 42091b8..64490ca 100644 --- a/fcore/enemy.sml +++ b/fcore/enemy.sml @@ -2,6 +2,12 @@ structure Enemy = struct open GameType + fun withDefaultYAxis (enemy: enemy) = + case #yAxis enemy of + ON_GROUND => + EnemyPatch.withPatch (enemy, EnemyPatch.W_Y_AXIS FALLING) + | _ => enemy + fun helpExists (pos, id, collisions) = if pos = Vector.length collisions then false @@ -40,8 +46,12 @@ struct acc else let - val enemy = - EnemyPatch.withPatch (enemy, EnemyPatch.W_Y_AXIS FALLING) + val enemy = withDefaultYAxis enemy + + (* get patches specific to this type of enemy *) + val patches = EnemyBehaviour.getVariantPatches + (enemy, walls, wallTree, platforms, platformTree, player, []) + val enemy = EnemyPatch.withPatches (enemy, patches) val patches = EnemyPhysics.getPhysicsPatches enemy val patches = EnemyPatch.W_HEALTH (health - 1) :: patches @@ -49,18 +59,18 @@ struct val patches = EnemyPhysics.getEnvironmentPatches (enemy, walls, wallTree, platforms, platformTree) - - (* get patches specific to this type of enemy *) - val patches = EnemyBehaviour.getVariantPatches - (enemy, walls, wallTree, platforms, platformTree, player, patches) - val enemy = EnemyPatch.withPatches (enemy, patches) in enemy :: acc end else let - val enemy = EnemyPatch.withPatch (enemy, EnemyPatch.W_Y_AXIS FALLING) + val enemy = withDefaultYAxis enemy + + (* get patches specific to this type of enemy *) + val patches = EnemyBehaviour.getVariantPatches + (enemy, walls, wallTree, platforms, platformTree, player, []) + val enemy = EnemyPatch.withPatches (enemy, patches) val patches = EnemyPhysics.getPhysicsPatches enemy val enemy = EnemyPatch.withPatches (enemy, patches) @@ -68,10 +78,6 @@ struct val patches = EnemyPhysics.getEnvironmentPatches (enemy, walls, wallTree, platforms, platformTree) - (* get patches specific to this type of enemy *) - val patches = EnemyBehaviour.getVariantPatches - (enemy, walls, wallTree, platforms, platformTree, player, patches) - val enemy = EnemyPatch.withPatches (enemy, patches) in enemy :: acc diff --git a/fcore/game-type.sml b/fcore/game-type.sml index 4e1ccff..d1f6402 100644 --- a/fcore/game-type.sml +++ b/fcore/game-type.sml @@ -172,7 +172,7 @@ struct , health = 1 , xAxis = MOVE_LEFT , yAxis = FALLING - , variant = EnemyVariants.PATROL_SLIME + , variant = EnemyVariants.FOLLOW_SLIME } val enemy2 = { id = 2 @@ -192,7 +192,7 @@ struct , yAxis = FALLING , variant = EnemyVariants.PATROL_SLIME } - val enemies = Vector.fromList [enemy1, enemy2, enemy3] + val enemies = Vector.fromList [enemy1] in { player = player , walls = walls