add code so that bat also moves vertically (in addition to previous horizontal movement) when updating enemy state

This commit is contained in:
2025-02-12 00:25:55 +00:00
parent 1dc3116b77
commit 4c8b404c09
6 changed files with 161 additions and 120 deletions

View File

@@ -30,7 +30,10 @@ struct
val enemySize = 35
val enemySizeReal: Real32.real = 35.0
val moveEnemyBy = 3
val batRestLimit = 55
val moveBatX = 1
val moveBatY = 2
val moveProjectileBy = 11
end

View File

@@ -502,51 +502,59 @@ struct
fun updateStraightBat
(player, enemy, walls, wallTree, projectileTree, enemyList, fallingList) =
let
val {x, y, batRest, ...} = enemy
val {x, y, batRest, batDirY, batMinY, batMaxY, xAxis, ...} = enemy
val size = Constants.enemySize
in
val moveByY = Constants.moveBatY
val moveByX = Constants.moveBatX
val patches =
(* get apatches for up/down movement *)
case batDirY of
UP =>
if y - moveByY <= batMaxY then
[EnemyPatch.W_BAT_DIR_Y DOWN, EnemyPatch.W_Y (y + moveByY)]
else
[EnemyPatch.W_Y (y - moveByY)]
| DOWN =>
if y + moveByY >= batMinY then
[EnemyPatch.W_BAT_DIR_Y UP, EnemyPatch.W_Y (y - moveByY)]
else
[EnemyPatch.W_Y (y + moveByY)]
val patches =
(* get patches for horizontal movement *)
if QuadTree.hasCollisionAt (x, y, size, size, ~1, wallTree) then
(* has collision with wall *)
let
val enemy =
if batRest >= Constants.batRestLimit then
(* make enemy move in opposite direction *)
case #xAxis enemy of
case xAxis of
MOVE_RIGHT =>
EnemyPatch.withPatches
( enemy
, [ EnemyPatch.W_X_AXIS MOVE_LEFT
, EnemyPatch.W_X (x - (Constants.moveEnemyBy * 9))
]
)
EnemyPatch.W_X_AXIS MOVE_LEFT :: EnemyPatch.W_X (x - 1)
:: patches
| MOVE_LEFT =>
EnemyPatch.withPatches
( enemy
, [ EnemyPatch.W_X_AXIS MOVE_RIGHT
, EnemyPatch.W_X (x + (Constants.moveEnemyBy * 9))
]
)
| _ => enemy
EnemyPatch.W_X_AXIS MOVE_RIGHT :: EnemyPatch.W_X (x + 1)
:: patches
| _ => patches
else
(* keep resting until we hit rest limit *)
EnemyPatch.withPatch (enemy, EnemyPatch.W_BAT_REST (batRest + 1))
in
(enemy :: enemyList, fallingList)
end
EnemyPatch.W_BAT_REST (batRest + 1) :: patches
else
(* no collision, so continue moving in direction *)
let
val patches =
case #xAxis enemy of
MOVE_RIGHT => [EnemyPatch.W_X (x + Constants.moveEnemyBy)]
| MOVE_LEFT => [EnemyPatch.W_X (x - Constants.moveEnemyBy)]
| STAY_STILL => []
val patches = EnemyPatch.W_BAT_REST 0 :: patches
case xAxis of
MOVE_RIGHT => EnemyPatch.W_X (x + moveByX) :: patches
| MOVE_LEFT => EnemyPatch.W_X (x - moveByX) :: patches
| STAY_STILL => patches
in
EnemyPatch.W_BAT_REST 0 :: patches
end
val enemy = EnemyPatch.withPatches (enemy, patches)
in
(enemy :: enemyList, fallingList)
end
end
fun updateEnemyState
( enemy

View File

@@ -234,8 +234,8 @@ struct
, nextPlatID = ~1
, batRest = 0
, batDirY = UP
, batMaxY = 635
, batMinY = 475
, batMaxY = 485
, batMinY = 625
}
val enemies = Vector.fromList [enemy1]
val graph = Graph.fromPlatforms (platforms, platformTree)

View File

@@ -10,8 +10,14 @@ signature MAKE_QUAD_TREE_FOLD =
sig
structure Fn: QUAD_FOLDER
val foldRegion: int * int * int * int *
Fn.env * Fn.state * {tree: QuadTreeType.t, width: int, height: int}
val foldRegion:
int
* int
* int
* int
* Fn.env
* Fn.state
* {tree: QuadTreeType.t, width: int, height: int}
-> Fn.state
end
@@ -51,37 +57,78 @@ struct
val state =
if vtl then
helpFoldRegion
(rx, ry, rw, rh, env, state, qx, qy, hw, hh, Vector.sub (nodes, tlIdx))
( rx
, ry
, rw
, rh
, env
, state
, qx
, qy
, hw
, hh
, Vector.sub (nodes, tlIdx)
)
else
state
val state =
if vtr then
helpFoldRegion
(rx, ry, rw, rh, env, state, qx + hw, qy, hw, hh, Vector.sub (nodes, trIdx))
( rx
, ry
, rw
, rh
, env
, state
, qx + hw
, qy
, hw
, hh
, Vector.sub (nodes, trIdx)
)
else
state
val state =
if vbl then
helpFoldRegion
(rx, ry, rw, rh, env, state, qx, qy + hh, hw, hh, Vector.sub (nodes, blIdx))
( rx
, ry
, rw
, rh
, env
, state
, qx
, qy + hh
, hw
, hh
, Vector.sub (nodes, blIdx)
)
else
state
in
if vbr then
helpFoldRegion
(rx, ry, rw, rh, env, state, qw + hw, qy + hh, hw, hh, Vector.sub (nodes, brIdx))
( rx
, ry
, rw
, rh
, env
, state
, qw + hw
, qy + hh
, hw
, hh
, Vector.sub (nodes, brIdx)
)
else
state
end
| LEAF items =>
foldRegionVec (rx, ry, rw, rh, env, state, 0, items)
| LEAF items => foldRegionVec (rx, ry, rw, rh, env, state, 0, items)
fun foldRegion (rx, ry, rw, rh, env, state, tree) =
let
val {width, height, tree} = tree
in
helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree)
let val {width, height, tree} = tree
in helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree)
end
end

View File

@@ -2,51 +2,33 @@ signature QUAD_TREE_TYPE =
sig
type item = {itemID: int, startX: int, startY: int, width: int, height: int}
datatype t =
NODE of t vector
| LEAF of item vector
datatype t = NODE of t vector | LEAF of item vector
val tlIdx: int
val trIdx: int
val blIdx: int
val brIdx: int
val isColliding: int * int * int * int *
int * int * int * int
-> bool
val isColliding: int * int * int * int * int * int * int * int -> bool
val isCollidingPlus: int * int * int * int *
int * int * int * int
-> bool
val isCollidingPlus: int * int * int * int * int * int * int * int -> bool
val isCollidingItem: int * int * int * int *
int * item
-> bool
val isCollidingItem: int * int * int * int * int * item -> bool
val visitTopLeft: int * int * int * int *
int * int * int * int
-> bool
val visitTopLeft: int * int * int * int * int * int * int * int -> bool
val visitTopRight: int * int * int * int *
int * int * int * int
-> bool
val visitTopRight: int * int * int * int * int * int * int * int -> bool
val visitBottomLeft: int * int * int * int *
int * int * int * int
-> bool
val visitBottomLeft: int * int * int * int * int * int * int * int -> bool
val visitBottomRight: int * int * int * int *
int * int * int * int
-> bool
val visitBottomRight: int * int * int * int * int * int * int * int -> bool
end
structure QuadTreeType :> QUAD_TREE_TYPE =
struct
type item = {itemID: int, startX: int, startY: int, width: int, height: int}
datatype t =
NODE of t vector
| LEAF of item vector
datatype t = NODE of t vector | LEAF of item vector
val tlIdx = 0
val trIdx = 1

View File

@@ -41,10 +41,8 @@ struct
val maxSize = 16
fun mkLeaf items =
let
val items = Vector.fromList items
in
LEAF items
let val items = Vector.fromList items
in LEAF items
end
fun splitLeaf
@@ -101,10 +99,8 @@ struct
val tl = Vector.sub (nodes, tlIdx)
val tl =
if vtl then
helpInsert (ix, iy, iw, ih, itemID, qw, qy, hw, hh, tl)
else
tl
if vtl then helpInsert (ix, iy, iw, ih, itemID, qw, qy, hw, hh, tl)
else tl
val tr = Vector.sub (nodes, trIdx)
val tr =
@@ -160,13 +156,14 @@ struct
fun insert (iX, iY, iW, iH, itemID, tree: t) =
let
val {width, height, tree} = tree
val tree =
helpInsert (iX, iY, iW, iH, itemID, 0, 0, width, height, tree)
val tree = helpInsert (iX, iY, iW, iH, itemID, 0, 0, width, height, tree)
in
{width = width, height = height, tree = tree}
end
structure GetCollisions = MakeQuadTreeFold (struct
structure GetCollisions =
MakeQuadTreeFold
(struct
type env = unit
type state = int list
fun fold (itemID, (), lst) = itemID :: lst
@@ -175,7 +172,9 @@ struct
fun getCollisions (itemX, itemY, itemWidth, itemHeight, _, tree) =
GetCollisions.foldRegion (itemX, itemY, itemWidth, itemHeight, (), [], tree)
structure HasCollisionAt = MakeQuadTreeFold (struct
structure HasCollisionAt =
MakeQuadTreeFold
(struct
type env = unit
type state = bool
fun fold _ = true
@@ -184,7 +183,9 @@ struct
fun hasCollisionAt (ix, iy, iw, ih, _, tree) =
HasCollisionAt.foldRegion (ix, iy, iw, ih, (), false, tree)
structure GetItemID = MakeQuadTreeFold (struct
structure GetItemID =
MakeQuadTreeFold
(struct
type env = unit
type state = int
fun fold (itemID, (), curID) = Int.max (itemID, curID)