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

View File

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

View File

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

View File

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