add 'facing' field to enemy, and update that field when enemy starts moving in different direction (with regards to x_axis)

This commit is contained in:
2025-02-15 08:13:36 +00:00
parent 0b9bdeceff
commit e538caa6c6
4 changed files with 74 additions and 28 deletions

View File

@@ -95,13 +95,15 @@ struct
(searchStartX, y, searchWidth, searchHeight, ~1, wallTree)
in
if hasWallAhead then
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
EnemyPatch.W_FACING FACING_RIGHT :: EnemyPatch.W_X_AXIS MOVE_RIGHT
:: acc
else if canWalkAhead (searchStartX, y, wallTree, platformTree) then
(* invert direction if moving further left
* will result in falling down *)
acc
else
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
EnemyPatch.W_FACING FACING_RIGHT :: EnemyPatch.W_X_AXIS MOVE_RIGHT
:: acc
end
| MOVE_RIGHT =>
let
@@ -116,13 +118,15 @@ struct
(searchStartX, y, searchWidth, searchHeight, ~1, wallTree)
in
if hasWallAhead then
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_X_AXIS MOVE_LEFT
:: acc
else if canWalkAhead (searchStartX, y, wallTree, platformTree) then
(* invert direction if moving further right
* will result in falling down *)
acc
else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_X_AXIS MOVE_LEFT
:: acc
end
| STAY_STILL => acc
end
@@ -202,9 +206,11 @@ struct
else (* have to travel either left or right before jumping *) if
ecx < platX
then
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
EnemyPatch.W_FACING FACING_RIGHT :: EnemyPatch.W_X_AXIS MOVE_RIGHT
:: acc
else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_X_AXIS MOVE_LEFT
:: acc
else
acc
end
@@ -247,9 +253,11 @@ struct
else (* have to travel either left or right before jumping *) if
ecx < platX
then
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
EnemyPatch.W_FACING FACING_RIGHT :: EnemyPatch.W_X_AXIS MOVE_RIGHT
:: acc
else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_X_AXIS MOVE_LEFT
:: acc
else
acc
end
@@ -260,27 +268,31 @@ struct
* So, if we check for jump first, we would always jump before dropping
* even if jumping is not necessary. *)
if TraceJump.traceRightDrop (enemy, #id nextPlatform, platformTree) then
EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: EnemyPatch.W_X_AXIS MOVE_RIGHT
:: acc
EnemyPatch.W_FACING FACING_RIGHT
:: EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM
:: EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
else if TraceJump.traceRightJump (enemy, #id nextPlatform, platformTree) then
if standingOnArea (enemy, platformTree) then
EnemyPatch.W_Y_AXIS (JUMPING 0) :: EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
EnemyPatch.W_FACING FACING_RIGHT :: EnemyPatch.W_Y_AXIS (JUMPING 0)
:: EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
else
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
EnemyPatch.W_FACING FACING_RIGHT :: EnemyPatch.W_X_AXIS MOVE_RIGHT
:: acc
else
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
EnemyPatch.W_FACING FACING_RIGHT :: EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
fun getMoveLeftPatches (nextPlatform, enemy, platformTree, acc) =
if TraceJump.traceLeftDrop (enemy, #id nextPlatform, platformTree) then
EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: EnemyPatch.W_X_AXIS MOVE_LEFT
:: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM
:: EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
else if TraceJump.traceLeftJump (enemy, #id nextPlatform, platformTree) then
if standingOnArea (enemy, platformTree) then
EnemyPatch.W_Y_AXIS (JUMPING 0) :: EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_Y_AXIS (JUMPING 0)
:: EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
(* get patches to help enemy move to nextPlatformID *)
fun getPathToNextPlatform
@@ -331,13 +343,9 @@ struct
fun startPatrolPatches (player, enemy, wallTree, platformTree, acc) =
case #xAxis enemy of
STAY_STILL =>
let
val acc =
if #x player <= #x enemy then EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
else EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
in
acc
end
(case #facing enemy of
FACING_RIGHT => EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
| FACING_LEFT => EnemyPatch.W_X_AXIS MOVE_LEFT :: acc)
| _ => getPatrolPatches (enemy, wallTree, platformTree, acc)
fun isInFollowRange (player, enemy) =
@@ -484,10 +492,11 @@ struct
(* make enemy move in opposite direction *)
case xAxis of
MOVE_RIGHT =>
EnemyPatch.W_X_AXIS MOVE_LEFT :: EnemyPatch.W_X (x - 1)
:: patches
EnemyPatch.W_FACING FACING_LEFT :: EnemyPatch.W_X_AXIS MOVE_LEFT
:: EnemyPatch.W_X (x - 1) :: patches
| MOVE_LEFT =>
EnemyPatch.W_X_AXIS MOVE_RIGHT :: EnemyPatch.W_X (x + 1)
EnemyPatch.W_FACING FACING_RIGHT
:: EnemyPatch.W_X_AXIS MOVE_RIGHT :: EnemyPatch.W_X (x + 1)
:: patches
| _ => patches
else

View File

@@ -12,6 +12,7 @@ sig
| W_BAT_MAX_Y of int
| W_BAT_MIN_Y of int
| W_BAT_DIR_Y of EnemyType.bat_dir_y
| W_FACING of EntityType.facing
val withPatch: EnemyType.enemy * enemy_patch -> EnemyType.enemy
@@ -32,6 +33,7 @@ struct
| W_BAT_MAX_Y of int
| W_BAT_MIN_Y of int
| W_BAT_DIR_Y of EnemyType.bat_dir_y
| W_FACING of EntityType.facing
fun mkEnemy
( id
@@ -47,6 +49,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
) =
{ id = id
, health = health
@@ -61,6 +64,7 @@ struct
, batDirY = batDirY
, batMaxY = batMaxY
, batMinY = batMinY
, facing = facing
}
fun withPatch (enemy, patch) =
@@ -79,6 +83,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
} = enemy
in
case patch of
@@ -97,6 +102,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_X x =>
mkEnemy
@@ -113,6 +119,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_X_AXIS xAxis =>
mkEnemy
@@ -129,6 +136,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_Y y =>
mkEnemy
@@ -145,6 +153,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_Y_AXIS yAxis =>
mkEnemy
@@ -161,6 +170,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_PLAT_ID platID =>
mkEnemy
@@ -177,6 +187,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_NEXT_PLAT_ID nextPlatID =>
mkEnemy
@@ -193,6 +204,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_BAT_REST batRest =>
mkEnemy
@@ -209,6 +221,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_BAT_MAX_Y batMaxY =>
mkEnemy
@@ -225,6 +238,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_BAT_MIN_Y batMinY =>
mkEnemy
@@ -241,6 +255,7 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_BAT_DIR_Y batDirY =>
mkEnemy
@@ -257,6 +272,24 @@ struct
, batDirY
, batMaxY
, batMinY
, facing
)
| W_FACING facing =>
mkEnemy
( id
, health
, x
, y
, xAxis
, yAxis
, variant
, platID
, nextPlatID
, batRest
, batDirY
, batMaxY
, batMinY
, facing
)
end

View File

@@ -18,6 +18,7 @@ sig
, batDirY: bat_dir_y
, batMaxY: int
, batMinY: int
, facing: EntityType.facing
}
type falling_enemy = {x: int, y: int, variant: variant}
@@ -43,6 +44,7 @@ struct
, batDirY: bat_dir_y
, batMaxY: int
, batMinY: int
, facing: EntityType.facing
}
type falling_enemy = {x: int, y: int, variant: variant}

View File

@@ -109,6 +109,7 @@ struct
, batRest = 0
, batMaxY = 485
, batMinY = 625
, facing = EntityType.FACING_RIGHT
}
val enemy2 =
{ id = 2
@@ -124,6 +125,7 @@ struct
, batRest = 0
, batMaxY = 485
, batMinY = 625
, facing = EntityType.FACING_RIGHT
}
val enemies = enemyMapFromList ([enemy1, enemy2], EnemyMap.empty)
val graph = Graph.fromPlatforms (platforms, platformTree)