tentatively refactor quad tree to make it more succinct + eliminate a class of potential bugs (passing wrong quad values through recursion)
This commit is contained in:
@@ -4,18 +4,15 @@ struct
|
||||
|
||||
fun canWalkAhead (x, y, wallTree, platformTree) =
|
||||
let
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val y = y + Constants.enemySize - 5
|
||||
val searchHeight = 10
|
||||
val searchWidth = Constants.moveEnemyBy
|
||||
in
|
||||
QuadTree.hasCollisionAt
|
||||
(x, y, searchWidth, searchHeight, 0, 0, ww, wh, ~1, wallTree)
|
||||
QuadHelp.hasCollisionAt
|
||||
(x, y, searchWidth, searchHeight, wallTree)
|
||||
orelse
|
||||
QuadTree.hasCollisionAt
|
||||
(x, y, searchWidth, searchHeight, 0, 0, ww, wh, ~1, platformTree)
|
||||
QuadHelp.hasCollisionAt
|
||||
(x, y, searchWidth, searchHeight, platformTree)
|
||||
end
|
||||
|
||||
(* same function takes either wallTree or platformTree and returns true
|
||||
@@ -31,11 +28,8 @@ struct
|
||||
|
||||
val width = Constants.enemySize
|
||||
val height = Platform.platHeight
|
||||
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
in
|
||||
QuadTree.hasCollisionAt (ex, ey, width, height, 0, 0, ww, wh, ~1, tree)
|
||||
QuadHelp.hasCollisionAt (ex, ey, width, height, tree)
|
||||
end
|
||||
|
||||
fun getPatrollPatches (enemy: enemy, wallTree, platformTree, acc) =
|
||||
@@ -68,19 +62,11 @@ struct
|
||||
val searchWidth = Constants.moveEnemyBy
|
||||
val searchHeight = Constants.enemySize - 5
|
||||
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val hasWallAhead = QuadTree.hasCollisionAt
|
||||
val hasWallAhead = QuadHelp.hasCollisionAt
|
||||
( searchStartX
|
||||
, y
|
||||
, searchWidth
|
||||
, searchHeight
|
||||
, 0
|
||||
, 0
|
||||
, ww
|
||||
, wh
|
||||
, ~1
|
||||
, wallTree
|
||||
)
|
||||
in
|
||||
@@ -102,19 +88,11 @@ struct
|
||||
val searchWidth = Constants.moveEnemyBy
|
||||
val searchHeight = Constants.enemySize - 5
|
||||
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val hasWallAhead = QuadTree.hasCollisionAt
|
||||
val hasWallAhead = QuadHelp.hasCollisionAt
|
||||
( searchStartX
|
||||
, y
|
||||
, searchWidth
|
||||
, searchHeight
|
||||
, 0
|
||||
, 0
|
||||
, ww
|
||||
, wh
|
||||
, ~1
|
||||
, wallTree
|
||||
)
|
||||
in
|
||||
@@ -155,12 +133,11 @@ struct
|
||||
val searchWidth = Constants.playerSize
|
||||
val searchHeight = Constants.worldHeight - y
|
||||
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val collisions = QuadTree.getCollisions
|
||||
(x, y, searchWidth, searchHeight, 0, 0, ww, wh, ~1, platformTree)
|
||||
val collisions = QuadHelp.getCollisions
|
||||
(x, y, searchWidth, searchHeight, platformTree)
|
||||
val checkY = y + Constants.playerSize
|
||||
|
||||
val wh = Constants.worldHeight
|
||||
in
|
||||
getHighestPlatform (collisions, platforms, wh, ~1, checkY)
|
||||
end
|
||||
@@ -174,11 +151,9 @@ struct
|
||||
|
||||
val y = y + Constants.enemySize
|
||||
|
||||
val ww = Constants.worldWidth
|
||||
val collisions = QuadHelp.getCollisions
|
||||
(x, y, searchWidth, searchHeight, platformTree)
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val collisions = QuadTree.getCollisions
|
||||
(x, y, searchWidth, searchHeight, 0, 0, ww, wh, ~1, platformTree)
|
||||
in
|
||||
getHighestPlatform (collisions, platforms, wh, ~1, y)
|
||||
end
|
||||
|
||||
@@ -34,11 +34,9 @@ struct
|
||||
val {x, y, health, ...} = enemy
|
||||
|
||||
val size = Constants.enemySize
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val hasCollision = QuadTree.hasCollisionAt
|
||||
(x, y, size, size, 0, 0, ww, wh, ~1, projectileTree)
|
||||
val hasCollision = QuadHelp.hasCollisionAt
|
||||
(x, y, size, size, projectileTree)
|
||||
in
|
||||
if hasCollision then
|
||||
if health = 1 then
|
||||
@@ -182,10 +180,8 @@ struct
|
||||
val {id, x, y, ...} = Vector.sub (enemyVec, pos)
|
||||
|
||||
val size = Constants.enemySize
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val acc = QuadTree.insert (x, y, size, size, 0, 0, ww, wh, id, acc)
|
||||
val acc = QuadHelp.insert (x, y, size, size, id, acc)
|
||||
in
|
||||
helpGenerateTree (pos + 1, enemyVec, acc)
|
||||
end
|
||||
|
||||
@@ -178,8 +178,20 @@ struct
|
||||
val plat8 = {id = 8, x = 970, y = 815, width = 303}
|
||||
val plat9 = {id = 9, x = 959, y = 705, width = 303}
|
||||
val plat10 = {id = 10, x = 970, y = 759, width = 303}
|
||||
val plat11 = {id = 11, x = 970, y = 595, width = 303}
|
||||
val plat12 = {id = 12, x = 959, y = 535, width = 303}
|
||||
val plat13 = {id = 13, x = 970, y = 495, width = 303}
|
||||
val plat14 = {id = 14, x = 1000, y = 415, width = 303}
|
||||
val plat15 = {id = 15, x = 1000, y = 335, width = 303}
|
||||
val plat16 = {id = 16, x = 1000, y = 295, width = 303}
|
||||
val plat17 = {id = 17, x = 155, y = 599, width = 199}
|
||||
val plat18 = {id = 18, x = 155, y = 499, width = 199}
|
||||
val plat19 = {id = 19, x = 155, y = 399, width = 199}
|
||||
val platforms = Vector.fromList
|
||||
[plat1, plat2, plat3, plat4, plat5, plat6, plat7, plat8, plat9, plat10]
|
||||
[plat1, plat2, plat3, plat4, plat5, plat6, plat7, plat8, plat9, plat10,
|
||||
plat11, plat12, plat13
|
||||
, plat14, plat15, plat16, plat17, plat18,
|
||||
plat19]
|
||||
val platformTree = Platform.generateTree platforms
|
||||
|
||||
val enemy1 =
|
||||
@@ -189,7 +201,7 @@ struct
|
||||
, health = 1
|
||||
, xAxis = STAY_STILL
|
||||
, yAxis = FALLING
|
||||
, variant = EnemyVariants.FOLLOW_SLIME
|
||||
, variant = EnemyVariants.PATROL_SLIME
|
||||
, platID = ~1
|
||||
, nextPlatID = ~1
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ struct
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
in
|
||||
QuadTree.hasCollisionAt (x, y, width, height, 0, 0, ww, wh, ~1, tree)
|
||||
QuadHelp.hasCollisionAt (x, y, width, height, tree)
|
||||
end
|
||||
|
||||
fun standingOnAreaID (x, y, tree) =
|
||||
@@ -92,12 +92,27 @@ struct
|
||||
val y = y + Fn.entitySize - 1
|
||||
|
||||
val width = Fn.entitySize
|
||||
val height = Platform.platHeight
|
||||
val height = Platform.platHeight + 2
|
||||
|
||||
val plat1 = {id = 1, x = 155, y = 911, width = 199}
|
||||
val plat2 = {id = 2, x = 355, y = 759, width = 555}
|
||||
val plat3 = {id = 3, x = 355, y = 659, width = 111}
|
||||
val plat4 = {id = 4, x = 155, y = 855, width = 99}
|
||||
val plat5 = {id = 5, x = 155, y = 811, width = 199}
|
||||
val plat6 = {id = 6, x = 155, y = 710, width = 199}
|
||||
val plat7 = {id = 7, x = 301, y = 855, width = 99}
|
||||
val plat8 = {id = 8, x = 970, y = 815, width = 303}
|
||||
val plat9 = {id = 9, x = 959, y = 705, width = 303}
|
||||
val plat10 = {id = 10, x = 970, y = 759, width = 303}
|
||||
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
in
|
||||
QuadTree.getItemID (x, y, width, height, 0, 0, ww, wh, tree)
|
||||
|
||||
val _ = print "START getItemID\n"
|
||||
val r =
|
||||
QuadHelp.getItemID (x, y, width, height, tree)
|
||||
val _ = print "FINISH getItemID\n"
|
||||
in r
|
||||
end
|
||||
|
||||
fun getWallPatches (x, y, walls, wallTree, acc) =
|
||||
@@ -110,8 +125,8 @@ struct
|
||||
(* check collision with wall to the left *)
|
||||
val acc =
|
||||
let
|
||||
val leftWallID = QuadTree.getItemID
|
||||
(x - 1, y, 1, 1, 0, 0, ww, wh, wallTree)
|
||||
val leftWallID = QuadHelp.getItemID
|
||||
(x - 1, y, 1, 1, wallTree)
|
||||
in
|
||||
if leftWallID <> ~1 then
|
||||
let
|
||||
@@ -129,8 +144,8 @@ struct
|
||||
(* check collision with wall to the right *)
|
||||
val acc =
|
||||
let
|
||||
val rightWallID = QuadTree.getItemID
|
||||
(x + size - 1, y, 1, 1, 0, 0, ww, wh, wallTree)
|
||||
val rightWallID = QuadHelp.getItemID
|
||||
(x + size - 1, y, 1, 1, wallTree)
|
||||
in
|
||||
if rightWallID <> ~1 then
|
||||
let
|
||||
@@ -145,8 +160,8 @@ struct
|
||||
end
|
||||
|
||||
(* check collision with wall below *)
|
||||
val downWallID = QuadTree.getItemID
|
||||
(x + moveBy + 1, y + size, 1, 1, 0, 0, ww, wh, wallTree)
|
||||
val downWallID = QuadHelp.getItemID
|
||||
(x + moveBy + 1, y + size, 1, 1, wallTree)
|
||||
in
|
||||
if downWallID <> ~1 then
|
||||
let
|
||||
@@ -172,23 +187,14 @@ struct
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
|
||||
val platCollisions = QuadTree.getCollisionsBelow
|
||||
(x, y, size, size, 0, 0, ww, wh, 0, platformTree)
|
||||
|
||||
val platID = standingOnAreaID (x, y, platformTree)
|
||||
|
||||
val acc = []
|
||||
|
||||
val acc =
|
||||
if platID <> ~1 then
|
||||
(case yAxis of
|
||||
DROP_BELOW_PLATFORM =>
|
||||
(* pass through, allowing player to drop below the platform *)
|
||||
acc
|
||||
| JUMPING _ =>
|
||||
(* pass through, allowing player to jump above the platform *)
|
||||
acc
|
||||
| FLOATING _ =>
|
||||
(print ("platID: " ^ Int.toString platID ^ "\n"); case yAxis of
|
||||
JUMPING _ =>
|
||||
(* pass through, allowing player to jump above the platform *)
|
||||
acc
|
||||
| _ =>
|
||||
@@ -216,8 +222,8 @@ struct
|
||||
* so we do not drop below any platforms again
|
||||
* *)
|
||||
if
|
||||
QuadTree.hasCollisionAt
|
||||
(x, y, size, size, 0, 0, ww, wh, ~1, platformTree)
|
||||
QuadHelp.hasCollisionAt
|
||||
(x, y, size, size, platformTree)
|
||||
then acc
|
||||
else Fn.W_Y_AXIS FALLING :: acc
|
||||
| _ => acc
|
||||
|
||||
@@ -11,8 +11,8 @@ struct
|
||||
else
|
||||
let
|
||||
val {id, x, y, width} = Vector.sub (platVec, pos)
|
||||
val acc = QuadTree.insert
|
||||
(x, y, width, platHeight, 0, 0, 1920, 1080, id, acc)
|
||||
val acc = QuadHelp.insert
|
||||
(x, y, width, platHeight, id, acc)
|
||||
in
|
||||
helpGenerateTree (pos + 1, platVec, acc)
|
||||
end
|
||||
|
||||
@@ -47,8 +47,8 @@ struct
|
||||
(case attacked of
|
||||
NOT_ATTACKED =>
|
||||
let
|
||||
val enemyCollisions = QuadTree.getCollisions
|
||||
(x, y, size, size, 0, 0, 1920, 1080, 0, enemyTree)
|
||||
val enemyCollisions = QuadHelp.getCollisions
|
||||
(x, y, size, size, enemyTree)
|
||||
|
||||
val player =
|
||||
Player.enemyCollisionReaction
|
||||
@@ -72,8 +72,8 @@ struct
|
||||
if amt = Constants.attackedLimit then
|
||||
(* if reached limit, detect enemies again *)
|
||||
let
|
||||
val enemyCollisions = QuadTree.getCollisions
|
||||
(x, y, size, size, 0, 0, 1920, 1080, 0, enemyTree)
|
||||
val enemyCollisions = QuadHelp.getCollisions
|
||||
(x, y, size, size, enemyTree)
|
||||
|
||||
val player =
|
||||
Player.exitAttackedAndCheckEnemies
|
||||
|
||||
@@ -320,6 +320,9 @@ struct
|
||||
let
|
||||
val player = #player game
|
||||
|
||||
val _ = print ("(playerX, playerY) = (" ^Int.toString (#x player) ^ ", " ^
|
||||
Int.toString (#y player) ^ ")\n")
|
||||
|
||||
val patches = getProjectilePatches player
|
||||
val player = PlayerPatch.withPatches (player, patches)
|
||||
|
||||
@@ -427,8 +430,8 @@ struct
|
||||
|
||||
val ww = Constants.worldWidth
|
||||
val wh = Constants.worldHeight
|
||||
val enemyCollisions = QuadTree.getCollisions
|
||||
(x, y, size, size, 0, 0, ww, wh, 0, enemyTree)
|
||||
val enemyCollisions = QuadHelp.getCollisions
|
||||
(x, y, size, size, enemyTree)
|
||||
in
|
||||
Vector.fromList enemyCollisions
|
||||
end
|
||||
|
||||
@@ -11,7 +11,7 @@ struct
|
||||
val size = projectileSizeInt
|
||||
|
||||
val {x, y, facing = _} = Vector.sub (projectiles, pos)
|
||||
val acc = QuadTree.insert (x, y, size, size, 0, 0, 1920, 1080, pos, acc)
|
||||
val acc = QuadHelp.insert (x, y, size, size, pos, acc)
|
||||
in
|
||||
helpGenerateTree (pos + 1, projectiles, acc)
|
||||
end
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
signature QUAD_FOLDER =
|
||||
sig
|
||||
type env
|
||||
type state
|
||||
val fState: state * env * int -> state
|
||||
end
|
||||
|
||||
functor MakeQuadFolder(Fn: QUAD_FOLDER) =
|
||||
struct
|
||||
open QuadTreeType
|
||||
|
||||
fun visitTopLeft (iX, iY, iW, iH, qX, qY, qW, qH) =
|
||||
let
|
||||
val midX = qW div 2 + qX
|
||||
val midY = qH div 2 + qY
|
||||
in
|
||||
iX <= midX andalso iY <= midY
|
||||
end
|
||||
|
||||
fun visitTopRight (iX, iY, iW, iH, qX, qY, qW, qH) =
|
||||
let
|
||||
val midX = qW div 2 + qX
|
||||
val midY = qH div 2 + qY
|
||||
in
|
||||
iX >= midX andalso iY <= midY
|
||||
end
|
||||
|
||||
fun visitBottomLeft (iX, iY, iW, iH, qX, qY, qW, qH) =
|
||||
let
|
||||
val midX = qW div 2 + qX
|
||||
val midY = qH div 2 + qY
|
||||
|
||||
val iFinishY = iY + iH
|
||||
in
|
||||
iX <= midX andalso iFinishY >= midY
|
||||
end
|
||||
|
||||
fun visitBottomRight (iX, iY, iW, iH, qX, qY, qW, qH) =
|
||||
let
|
||||
val midX = qW div 2 + qX
|
||||
val midY = qH div 2 + qY
|
||||
|
||||
val iFinishX = iX + iH
|
||||
val iFinishY = iY + iH
|
||||
in
|
||||
iFinishX >= midX andalso iFinishY >= midY
|
||||
end
|
||||
|
||||
fun foldVec (iX, iY, iW, iH, pos, elements, state, env) =
|
||||
if pos = Vector.length elements then
|
||||
state
|
||||
else
|
||||
let
|
||||
val {itemID, ...} = Vector.sub (elements, pos)
|
||||
val state = Fn.fState (state, env, itemID)
|
||||
in
|
||||
foldVec (iX, iY, iW, iH, pos + 1, elements, state, env)
|
||||
end
|
||||
|
||||
fun foldRegion
|
||||
( itemX
|
||||
, itemY
|
||||
, itemW
|
||||
, itemH
|
||||
, quadX
|
||||
, quadY
|
||||
, quadW
|
||||
, quadH
|
||||
, env: Fn.env
|
||||
, state: Fn.state
|
||||
, tree: QuadTreeType.t
|
||||
) =
|
||||
case tree of
|
||||
NODE {topLeft, topRight, bottomLeft, bottomRight} =>
|
||||
let
|
||||
(* fold over intersecting elements in this vector first *)
|
||||
val halfW = quadW div 2
|
||||
val halfH = quadH div 2
|
||||
|
||||
val midX = halfW + quadX
|
||||
val midY = halfH + quadY
|
||||
|
||||
val iX = itemX
|
||||
val iY = itemY
|
||||
val iW = itemW
|
||||
val iH = itemH
|
||||
|
||||
val qX = quadX
|
||||
val qY = quadY
|
||||
val qW = quadW
|
||||
val qH = quadH
|
||||
|
||||
val vtl = visitTopLeft (iX, iY, iW, iH, qX, qY, qW, qH)
|
||||
val vtr = visitTopRight (iX, iY, iW, iH, qX, qY, qW, qH)
|
||||
val vbl = visitBottomLeft (iX, iY, iW, iH, qX, qY, qW, qH)
|
||||
val vbr = visitBottomRight (iX, iY, iW, iH, qX, qY, qW, qH)
|
||||
|
||||
val state =
|
||||
if vtl then
|
||||
foldRegion
|
||||
(iX, iY, iW, iH, qX, qY, halfW, halfH, env, state, topLeft)
|
||||
else
|
||||
state
|
||||
|
||||
val state =
|
||||
if vtr then
|
||||
foldRegion
|
||||
( itemX
|
||||
, itemY
|
||||
, itemW
|
||||
, itemH
|
||||
, midX
|
||||
, quadY
|
||||
, halfW
|
||||
, halfH
|
||||
, env
|
||||
, state
|
||||
, topRight
|
||||
)
|
||||
else
|
||||
state
|
||||
|
||||
val state =
|
||||
if vbl then
|
||||
foldRegion
|
||||
( itemX
|
||||
, itemY
|
||||
, itemW
|
||||
, itemH
|
||||
, quadX
|
||||
, midY
|
||||
, halfW
|
||||
, halfH
|
||||
, env
|
||||
, state
|
||||
, bottomLeft
|
||||
)
|
||||
else
|
||||
state
|
||||
in
|
||||
if vbr then
|
||||
foldRegion
|
||||
( itemX
|
||||
, itemY
|
||||
, itemW
|
||||
, itemH
|
||||
, midX
|
||||
, midY
|
||||
, halfW
|
||||
, halfH
|
||||
, env
|
||||
, state
|
||||
, bottomRight
|
||||
)
|
||||
else
|
||||
state
|
||||
end
|
||||
| LEAF elements =>
|
||||
foldVec (itemX, itemY, itemW, itemH, 0, elements, state, env)
|
||||
end
|
||||
@@ -3,8 +3,17 @@ sig
|
||||
type item = {itemID: int, startX: int, startY: int, width: int, height: int}
|
||||
|
||||
datatype t =
|
||||
NODE of {topLeft: t, topRight: t, bottomLeft: t, bottomRight: t}
|
||||
| LEAF of item vector
|
||||
NODE of
|
||||
{ topLeft: t
|
||||
, topRight: t
|
||||
, bottomLeft: t
|
||||
, bottomRight: t
|
||||
, x: int
|
||||
, y: int
|
||||
, w: int
|
||||
, h: int
|
||||
}
|
||||
| LEAF of {items: item vector, x: int, y: int, w: int, h: int}
|
||||
|
||||
datatype quadrant =
|
||||
TOP_LEFT
|
||||
@@ -19,8 +28,17 @@ struct
|
||||
type item = {itemID: int, startX: int, startY: int, width: int, height: int}
|
||||
|
||||
datatype t =
|
||||
NODE of {topLeft: t, topRight: t, bottomLeft: t, bottomRight: t}
|
||||
| LEAF of item vector
|
||||
NODE of
|
||||
{ topLeft: t
|
||||
, topRight: t
|
||||
, bottomLeft: t
|
||||
, bottomRight: t
|
||||
, x: int
|
||||
, y: int
|
||||
, w: int
|
||||
, h: int
|
||||
}
|
||||
| LEAF of {items: item vector, x: int, y: int, w: int, h: int}
|
||||
|
||||
datatype quadrant =
|
||||
TOP_LEFT
|
||||
|
||||
1101
fcore/quad-tree.sml
1101
fcore/quad-tree.sml
File diff suppressed because it is too large
Load Diff
@@ -6,8 +6,8 @@ struct
|
||||
else
|
||||
let
|
||||
val {id, x, y, width, height} = Vector.sub (wallVec, pos)
|
||||
val acc = QuadTree.insert
|
||||
(x, y, width, height, 0, 0, 1920, 1080, id, acc)
|
||||
val acc = QuadHelp.insert
|
||||
(x, y, width, height, id, acc)
|
||||
in
|
||||
helpGenerateTree (pos + 1, wallVec, acc)
|
||||
end
|
||||
|
||||
@@ -157,8 +157,6 @@ typedef Pointer Objptr;
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MLLIB_PUBLIC(void mltonKeyCallback (Int32 x0, Int32 x1, Int32 x2, Int32 x3);)
|
||||
MLLIB_PUBLIC(void mltonFramebufferSizeCallback (Real32 x0, Real32 x1);)
|
||||
|
||||
#undef MLLIB_PRIVATE
|
||||
#undef MLLIB_PUBLIC
|
||||
|
||||
Reference in New Issue
Block a user