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 enemySize = 35
val enemySizeReal: Real32.real = 35.0 val enemySizeReal: Real32.real = 35.0
val moveEnemyBy = 3 val moveEnemyBy = 3
val batRestLimit = 55 val batRestLimit = 55
val moveBatX = 1
val moveBatY = 2
val moveProjectileBy = 11 val moveProjectileBy = 11
end end

View File

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

View File

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

View File

@@ -10,8 +10,14 @@ signature MAKE_QUAD_TREE_FOLD =
sig sig
structure Fn: QUAD_FOLDER structure Fn: QUAD_FOLDER
val foldRegion: int * int * int * int * val foldRegion:
Fn.env * Fn.state * {tree: QuadTreeType.t, width: int, height: int} int
* int
* int
* int
* Fn.env
* Fn.state
* {tree: QuadTreeType.t, width: int, height: int}
-> Fn.state -> Fn.state
end end
@@ -51,37 +57,78 @@ struct
val state = val state =
if vtl then if vtl then
helpFoldRegion 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 else
state state
val state = val state =
if vtr then if vtr then
helpFoldRegion 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 else
state state
val state = val state =
if vbl then if vbl then
helpFoldRegion 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 else
state state
in in
if vbr then if vbr then
helpFoldRegion 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 else
state state
end end
| LEAF items => | LEAF items => foldRegionVec (rx, ry, rw, rh, env, state, 0, items)
foldRegionVec (rx, ry, rw, rh, env, state, 0, items)
fun foldRegion (rx, ry, rw, rh, env, state, tree) = fun foldRegion (rx, ry, rw, rh, env, state, tree) =
let let val {width, height, tree} = tree
val {width, height, tree} = tree in helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree)
in
helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree)
end end
end end

View File

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

View File

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