add code so that bat also moves vertically (in addition to previous horizontal movement) when updating enemy state
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -502,50 +502,58 @@ 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
|
||||
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
|
||||
MOVE_RIGHT =>
|
||||
EnemyPatch.withPatches
|
||||
( enemy
|
||||
, [ EnemyPatch.W_X_AXIS MOVE_LEFT
|
||||
, EnemyPatch.W_X (x - (Constants.moveEnemyBy * 9))
|
||||
]
|
||||
)
|
||||
| MOVE_LEFT =>
|
||||
EnemyPatch.withPatches
|
||||
( enemy
|
||||
, [ EnemyPatch.W_X_AXIS MOVE_RIGHT
|
||||
, EnemyPatch.W_X (x + (Constants.moveEnemyBy * 9))
|
||||
]
|
||||
)
|
||||
| _ => enemy
|
||||
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
|
||||
(* keep resting until we hit rest limit *)
|
||||
EnemyPatch.withPatch (enemy, EnemyPatch.W_BAT_REST (batRest + 1))
|
||||
in
|
||||
(enemy :: enemyList, fallingList)
|
||||
end
|
||||
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
|
||||
val enemy = EnemyPatch.withPatches (enemy, patches)
|
||||
in
|
||||
(enemy :: enemyList, fallingList)
|
||||
end
|
||||
[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 *)
|
||||
if batRest >= Constants.batRestLimit then
|
||||
(* make enemy move in opposite direction *)
|
||||
case xAxis of
|
||||
MOVE_RIGHT =>
|
||||
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)
|
||||
:: patches
|
||||
| _ => patches
|
||||
else
|
||||
(* keep resting until we hit rest limit *)
|
||||
EnemyPatch.W_BAT_REST (batRest + 1) :: patches
|
||||
else
|
||||
(* no collision, so continue moving in direction *)
|
||||
let
|
||||
val 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
|
||||
|
||||
fun updateEnemyState
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -10,9 +10,15 @@ 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}
|
||||
-> Fn.state
|
||||
val foldRegion:
|
||||
int
|
||||
* int
|
||||
* int
|
||||
* int
|
||||
* Fn.env
|
||||
* Fn.state
|
||||
* {tree: QuadTreeType.t, width: int, height: int}
|
||||
-> Fn.state
|
||||
end
|
||||
|
||||
functor MakeQuadTreeFold(Fn: QUAD_FOLDER): MAKE_QUAD_TREE_FOLD =
|
||||
@@ -50,38 +56,79 @@ struct
|
||||
|
||||
val state =
|
||||
if vtl then
|
||||
helpFoldRegion
|
||||
(rx, ry, rw, rh, env, state, qx, qy, hw, hh, Vector.sub (nodes, tlIdx))
|
||||
helpFoldRegion
|
||||
( rx
|
||||
, ry
|
||||
, rw
|
||||
, rh
|
||||
, env
|
||||
, state
|
||||
, qx
|
||||
, qy
|
||||
, hw
|
||||
, hh
|
||||
, Vector.sub (nodes, tlIdx)
|
||||
)
|
||||
else
|
||||
state
|
||||
|
||||
val state =
|
||||
val state =
|
||||
if vtr then
|
||||
helpFoldRegion
|
||||
(rx, ry, rw, rh, env, state, qx + hw, qy, hw, hh, Vector.sub (nodes, trIdx))
|
||||
else
|
||||
helpFoldRegion
|
||||
( rx
|
||||
, ry
|
||||
, rw
|
||||
, rh
|
||||
, env
|
||||
, state
|
||||
, qx + hw
|
||||
, qy
|
||||
, hw
|
||||
, hh
|
||||
, Vector.sub (nodes, trIdx)
|
||||
)
|
||||
else
|
||||
state
|
||||
|
||||
val 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))
|
||||
helpFoldRegion
|
||||
( 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -26,7 +26,7 @@ struct
|
||||
val vec = Vector.fromList []
|
||||
val tree = LEAF vec
|
||||
in
|
||||
{ tree = tree, width = width, height = height }
|
||||
{tree = tree, width = width, height = height}
|
||||
end
|
||||
|
||||
fun mkItem (id, startX, startY, width, height) : item =
|
||||
@@ -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
|
||||
@@ -65,7 +63,7 @@ struct
|
||||
val tr = mkLeaf tr
|
||||
val bl = mkLeaf bl
|
||||
val br = mkLeaf br
|
||||
val nodes = Vector.fromList [tl, tr, bl, br]
|
||||
val nodes = Vector.fromList [tl, tr, bl, br]
|
||||
in
|
||||
NODE nodes
|
||||
end
|
||||
@@ -101,20 +99,18 @@ 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 =
|
||||
if vtr then
|
||||
helpInsert (ix, iy, iw, ih, itemID, qx + hw, qy, hw, hh, tr)
|
||||
else
|
||||
else
|
||||
tr
|
||||
|
||||
val bl = Vector.sub (nodes, blIdx)
|
||||
val bl =
|
||||
val bl =
|
||||
if vbl then
|
||||
helpInsert (ix, iy, iw, ih, itemID, qx, qy + hh, hw, hh, bl)
|
||||
else
|
||||
@@ -124,7 +120,7 @@ struct
|
||||
val br =
|
||||
if vbr then
|
||||
helpInsert (ix, iy, iw, ih, itemID, qx + hw, qy + hh, hw, hh, br)
|
||||
else
|
||||
else
|
||||
br
|
||||
|
||||
val nodes = Vector.fromList [tl, tr, bl, br]
|
||||
@@ -160,35 +156,40 @@ 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
|
||||
type env = unit
|
||||
type state = int list
|
||||
fun fold (itemID, (), lst) = itemID :: lst
|
||||
end)
|
||||
structure GetCollisions =
|
||||
MakeQuadTreeFold
|
||||
(struct
|
||||
type env = unit
|
||||
type state = int list
|
||||
fun fold (itemID, (), lst) = itemID :: lst
|
||||
end)
|
||||
|
||||
fun getCollisions (itemX, itemY, itemWidth, itemHeight, _, tree) =
|
||||
GetCollisions.foldRegion (itemX, itemY, itemWidth, itemHeight, (), [], tree)
|
||||
|
||||
structure HasCollisionAt = MakeQuadTreeFold (struct
|
||||
type env = unit
|
||||
type state = bool
|
||||
fun fold _ = true
|
||||
end)
|
||||
structure HasCollisionAt =
|
||||
MakeQuadTreeFold
|
||||
(struct
|
||||
type env = unit
|
||||
type state = bool
|
||||
fun fold _ = true
|
||||
end)
|
||||
|
||||
fun hasCollisionAt (ix, iy, iw, ih, _, tree) =
|
||||
HasCollisionAt.foldRegion (ix, iy, iw, ih, (), false, tree)
|
||||
|
||||
structure GetItemID = MakeQuadTreeFold (struct
|
||||
type env = unit
|
||||
type state = int
|
||||
fun fold (itemID, (), curID) = Int.max (itemID, curID)
|
||||
end)
|
||||
structure GetItemID =
|
||||
MakeQuadTreeFold
|
||||
(struct
|
||||
type env = unit
|
||||
type state = int
|
||||
fun fold (itemID, (), curID) = Int.max (itemID, curID)
|
||||
end)
|
||||
|
||||
fun getItemID (ix, iy, iw, ih, tree) =
|
||||
GetItemID.foldRegion (ix, iy, iw, ih, (), ~1, tree)
|
||||
|
||||
Reference in New Issue
Block a user