fix compile errors after previous commit (which involved reimplementing the quad tree to eliminate the possibility of a class of bugs I was experiencing; the problem was that the quad bounds were being passed recursively in different functions, but the long argument list in these functions made it difficult to see where the mismatch was)

This commit is contained in:
2025-01-27 23:41:59 +00:00
parent 6369be21fa
commit 9b7d7a1396
12 changed files with 264 additions and 333 deletions

View File

@@ -8,11 +8,10 @@ struct
val searchHeight = 10 val searchHeight = 10
val searchWidth = Constants.moveEnemyBy val searchWidth = Constants.moveEnemyBy
in in
QuadHelp.hasCollisionAt QuadTree.hasCollisionAt (x, y, searchWidth, searchHeight, ~1, wallTree)
(x, y, searchWidth, searchHeight, wallTree)
orelse orelse
QuadHelp.hasCollisionAt QuadTree.hasCollisionAt
(x, y, searchWidth, searchHeight, platformTree) (x, y, searchWidth, searchHeight, ~1, platformTree)
end end
(* same function takes either wallTree or platformTree and returns true (* same function takes either wallTree or platformTree and returns true
@@ -29,7 +28,7 @@ struct
val width = Constants.enemySize val width = Constants.enemySize
val height = Platform.platHeight val height = Platform.platHeight
in in
QuadHelp.hasCollisionAt (ex, ey, width, height, tree) QuadTree.hasCollisionAt (ex, ey, width, height, ~1, tree)
end end
fun getPatrollPatches (enemy: enemy, wallTree, platformTree, acc) = fun getPatrollPatches (enemy: enemy, wallTree, platformTree, acc) =
@@ -62,22 +61,17 @@ struct
val searchWidth = Constants.moveEnemyBy val searchWidth = Constants.moveEnemyBy
val searchHeight = Constants.enemySize - 5 val searchHeight = Constants.enemySize - 5
val hasWallAhead = QuadHelp.hasCollisionAt val hasWallAhead = QuadTree.hasCollisionAt
( searchStartX (searchStartX, y, searchWidth, searchHeight, ~1, wallTree)
, y
, searchWidth
, searchHeight
, wallTree
)
in in
if if hasWallAhead then
hasWallAhead EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
then 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 EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc else
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
end end
| MOVE_RIGHT => | MOVE_RIGHT =>
let let
@@ -88,22 +82,17 @@ struct
val searchWidth = Constants.moveEnemyBy val searchWidth = Constants.moveEnemyBy
val searchHeight = Constants.enemySize - 5 val searchHeight = Constants.enemySize - 5
val hasWallAhead = QuadHelp.hasCollisionAt val hasWallAhead = QuadTree.hasCollisionAt
( searchStartX (searchStartX, y, searchWidth, searchHeight, ~1, wallTree)
, y
, searchWidth
, searchHeight
, wallTree
)
in in
if if hasWallAhead then
hasWallAhead EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
then 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 EnemyPatch.W_X_AXIS MOVE_LEFT :: acc else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
end end
| STAY_STILL => acc | STAY_STILL => acc
end end
@@ -133,8 +122,8 @@ struct
val searchWidth = Constants.playerSize val searchWidth = Constants.playerSize
val searchHeight = Constants.worldHeight - y val searchHeight = Constants.worldHeight - y
val collisions = QuadHelp.getCollisions val collisions = QuadTree.getCollisions
(x, y, searchWidth, searchHeight, platformTree) (x, y, searchWidth, searchHeight, ~1, platformTree)
val checkY = y + Constants.playerSize val checkY = y + Constants.playerSize
val wh = Constants.worldHeight val wh = Constants.worldHeight
@@ -151,8 +140,8 @@ struct
val y = y + Constants.enemySize val y = y + Constants.enemySize
val collisions = QuadHelp.getCollisions val collisions = QuadTree.getCollisions
(x, y, searchWidth, searchHeight, platformTree) (x, y, searchWidth, searchHeight, ~1, platformTree)
val wh = Constants.worldHeight val wh = Constants.worldHeight
in in
getHighestPlatform (collisions, platforms, wh, ~1, y) getHighestPlatform (collisions, platforms, wh, ~1, y)
@@ -191,9 +180,9 @@ struct
ON_GROUND => EnemyPatch.W_Y_AXIS (JUMPING 0) :: acc ON_GROUND => EnemyPatch.W_Y_AXIS (JUMPING 0) :: acc
| FALLING => EnemyPatch.W_Y_AXIS (JUMPING 0) :: acc | FALLING => EnemyPatch.W_Y_AXIS (JUMPING 0) :: acc
| _ => acc | _ => acc
else else (* have to travel either left or right before jumping *) if
(* have to travel either left or right before jumping *) ecx < platX
if ecx < platX then then
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
else else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
@@ -234,9 +223,9 @@ struct
ON_GROUND => EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: acc ON_GROUND => EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: acc
| FALLING => EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: acc | FALLING => EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: acc
| _ => acc | _ => acc
else else (* have to travel either left or right before jumping *) if
(* have to travel either left or right before jumping *) ecx < platX
if ecx < platX then then
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
else else
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
@@ -296,8 +285,8 @@ struct
in in
if yDiff >= xDiff then if yDiff >= xDiff then
(* can reach next platform by simply dropping and moving right *) (* can reach next platform by simply dropping and moving right *)
EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: EnemyPatch.W_X_AXIS EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM
MOVE_RIGHT :: acc :: EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
else else
let let
val jumpAmt = val jumpAmt =
@@ -370,8 +359,8 @@ struct
in in
if yDiff >= xDiff then if yDiff >= xDiff then
(* can reach next platform by simply dropping and moving right *) (* can reach next platform by simply dropping and moving right *)
EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM :: EnemyPatch.W_X_AXIS EnemyPatch.W_Y_AXIS DROP_BELOW_PLATFORM
MOVE_LEFT :: acc :: EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
else else
let let
val jumpAmt = val jumpAmt =
@@ -445,10 +434,8 @@ struct
val startDiff = abs (px - ex) val startDiff = abs (px - ex)
val endDiff = abs (pfx - efx) val endDiff = abs (pfx - efx)
in in
if startDiff > endDiff then if startDiff > endDiff then EnemyPatch.W_X_AXIS MOVE_LEFT :: acc
EnemyPatch.W_X_AXIS MOVE_LEFT :: acc else EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
else
EnemyPatch.W_X_AXIS MOVE_RIGHT :: acc
end end
end end
@@ -471,35 +458,25 @@ struct
in in
if ey < py - 65 then if ey < py - 65 then
(* set to falling *) (* set to falling *)
EnemyPatch.W_NEXT_PLAT_ID ~1 :: EnemyPatch.W_NEXT_PLAT_ID ~1 :: EnemyPatch.W_Y_AXIS FALLING :: acc
EnemyPatch.W_Y_AXIS FALLING ::
acc
else else
acc acc
end end
fun getLandingPatches (newPlatformID, platforms, enemy, acc) = fun getLandingPatches (newPlatformID, platforms, enemy, acc) =
case #yAxis enemy of case #yAxis enemy of
JUMPING _ => JUMPING _ => getJumpLandingPatches (enemy, newPlatformID, platforms, acc)
getJumpLandingPatches (enemy, newPlatformID, platforms, acc) | _ => getFallingPatches (enemy, newPlatformID, platforms, acc)
| _ =>
getFallingPatches (enemy, newPlatformID, platforms, acc)
fun getFollowPatches fun getFollowPatches
(player: player, enemy, wallTree, platformTree, platforms, acc) = (player: player, enemy, wallTree, platformTree, platforms, acc) =
let let
(* todo: possibly get pID and eID of player/enemy in a different way *) (* todo: possibly get pID and eID of player/enemy in a different way *)
val pID = getPlatformBelowPlayer (player, platformTree, platforms) val pID = getPlatformBelowPlayer (player, platformTree, platforms)
val pID = val pID = if pID = ~1 then #platID player else pID
if pID = ~1 then
#platID player
else pID
val eID = getPlatformBelowEnemy (enemy, platformTree, platforms) val eID = getPlatformBelowEnemy (enemy, platformTree, platforms)
val eID = val eID = if eID = ~1 then #platID enemy else eID
if eID = ~1 then
#platID enemy
else eID
in in
if eID = ~1 orelse pID = ~1 then if eID = ~1 orelse pID = ~1 then
(* without checking that neither of these are ~1 (* without checking that neither of these are ~1
@@ -521,7 +498,14 @@ struct
val acc = EnemyPatch.W_NEXT_PLAT_ID nextPlatformID :: acc val acc = EnemyPatch.W_NEXT_PLAT_ID nextPlatformID :: acc
in in
getPathToNextPlatform getPathToNextPlatform
(nextPlatformID, platforms, platformTree, enemy, eID, pID, acc) ( nextPlatformID
, platforms
, platformTree
, enemy
, eID
, pID
, acc
)
end end
| [] => getPatrollPatches (enemy, wallTree, platformTree, acc) | [] => getPatrollPatches (enemy, wallTree, platformTree, acc)
end end

View File

@@ -44,10 +44,12 @@ struct
case patch of case patch of
W_HEALTH health => W_HEALTH health =>
mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID) mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID)
| W_X x => mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID) | W_X x =>
mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID)
| W_X_AXIS xAxis => | W_X_AXIS xAxis =>
mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID) mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID)
| W_Y y => mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID) | W_Y y =>
mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID)
| W_Y_AXIS yAxis => | W_Y_AXIS yAxis =>
mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID) mkEnemy (id, health, x, y, xAxis, yAxis, variant, platID, nextPlatID)
| W_PLAT_ID platID => | W_PLAT_ID platID =>

View File

@@ -4,8 +4,7 @@ struct
fun withDefaultYAxis (enemy: enemy) = fun withDefaultYAxis (enemy: enemy) =
case #yAxis enemy of case #yAxis enemy of
ON_GROUND => ON_GROUND => EnemyPatch.withPatch (enemy, EnemyPatch.W_Y_AXIS FALLING)
EnemyPatch.withPatch (enemy, EnemyPatch.W_Y_AXIS FALLING)
| _ => enemy | _ => enemy
fun helpExists (pos, id, collisions) = fun helpExists (pos, id, collisions) =
@@ -35,8 +34,8 @@ struct
val size = Constants.enemySize val size = Constants.enemySize
val hasCollision = QuadHelp.hasCollisionAt val hasCollision = QuadTree.hasCollisionAt
(x, y, size, size, projectileTree) (x, y, size, size, ~1, projectileTree)
in in
if hasCollision then if hasCollision then
if health = 1 then if health = 1 then
@@ -181,12 +180,17 @@ struct
val size = Constants.enemySize val size = Constants.enemySize
val acc = QuadHelp.insert (x, y, size, size, id, acc) val acc = QuadTree.insert (x, y, size, size, id, acc)
in in
helpGenerateTree (pos + 1, enemyVec, acc) helpGenerateTree (pos + 1, enemyVec, acc)
end end
fun generateTree enemyVec = helpGenerateTree (0, enemyVec, QuadTree.empty) fun generateTree enemyVec =
helpGenerateTree
( 0
, enemyVec
, QuadTree.create (Constants.worldWidth, Constants.worldHeight)
)
fun helpFind (findNum, vec: enemy vector, low, high) = fun helpFind (findNum, vec: enemy vector, low, high) =
(* should only be called when we know enemy already exists in vec *) (* should only be called when we know enemy already exists in vec *)

View File

@@ -188,10 +188,26 @@ struct
val plat18 = {id = 18, x = 155, y = 499, width = 199} val plat18 = {id = 18, x = 155, y = 499, width = 199}
val plat19 = {id = 19, x = 155, y = 399, width = 199} val plat19 = {id = 19, x = 155, y = 399, width = 199}
val platforms = Vector.fromList val platforms = Vector.fromList
[plat1, plat2, plat3, plat4, plat5, plat6, plat7, plat8, plat9, plat10, [ plat1
plat11, plat12, plat13 , plat2
, plat14, plat15, plat16, plat17, plat18, , plat3
plat19] , plat4
, plat5
, plat6
, plat7
, plat8
, plat9
, plat10
, plat11
, plat12
, plat13
, plat14
, plat15
, plat16
, plat17
, plat18
, plat19
]
val platformTree = Platform.generateTree platforms val platformTree = Platform.generateTree platforms
val enemy1 = val enemy1 =

View File

@@ -84,7 +84,7 @@ struct
val ww = Constants.worldWidth val ww = Constants.worldWidth
val wh = Constants.worldHeight val wh = Constants.worldHeight
in in
QuadHelp.hasCollisionAt (x, y, width, height, tree) QuadTree.hasCollisionAt (x, y, width, height, ~1, tree)
end end
fun standingOnAreaID (x, y, tree) = fun standingOnAreaID (x, y, tree) =
@@ -109,10 +109,10 @@ struct
val wh = Constants.worldHeight val wh = Constants.worldHeight
val _ = print "START getItemID\n" val _ = print "START getItemID\n"
val r = val r = QuadTree.getItemID (x, y, width, height, tree)
QuadHelp.getItemID (x, y, width, height, tree)
val _ = print "FINISH getItemID\n" val _ = print "FINISH getItemID\n"
in r in
r
end end
fun getWallPatches (x, y, walls, wallTree, acc) = fun getWallPatches (x, y, walls, wallTree, acc) =
@@ -125,8 +125,7 @@ struct
(* check collision with wall to the left *) (* check collision with wall to the left *)
val acc = val acc =
let let
val leftWallID = QuadHelp.getItemID val leftWallID = QuadTree.getItemID (x - 1, y, 1, 1, wallTree)
(x - 1, y, 1, 1, wallTree)
in in
if leftWallID <> ~1 then if leftWallID <> ~1 then
let let
@@ -144,8 +143,7 @@ struct
(* check collision with wall to the right *) (* check collision with wall to the right *)
val acc = val acc =
let let
val rightWallID = QuadHelp.getItemID val rightWallID = QuadTree.getItemID (x + size - 1, y, 1, 1, wallTree)
(x + size - 1, y, 1, 1, wallTree)
in in
if rightWallID <> ~1 then if rightWallID <> ~1 then
let let
@@ -160,7 +158,7 @@ struct
end end
(* check collision with wall below *) (* check collision with wall below *)
val downWallID = QuadHelp.getItemID val downWallID = QuadTree.getItemID
(x + moveBy + 1, y + size, 1, 1, wallTree) (x + moveBy + 1, y + size, 1, 1, wallTree)
in in
if downWallID <> ~1 then if downWallID <> ~1 then
@@ -193,7 +191,8 @@ struct
val acc = val acc =
if platID <> ~1 then if platID <> ~1 then
(print ("platID: " ^ Int.toString platID ^ "\n"); case yAxis of ( print ("platID: " ^ Int.toString platID ^ "\n")
; case yAxis of
JUMPING _ => JUMPING _ =>
(* pass through, allowing player to jump above the platform *) (* pass through, allowing player to jump above the platform *)
acc acc
@@ -208,7 +207,8 @@ struct
val acc = Fn.W_Y_AXIS ON_GROUND :: Fn.W_Y newY :: acc val acc = Fn.W_Y_AXIS ON_GROUND :: Fn.W_Y newY :: acc
in in
acc acc
end) end
)
else else
acc acc
@@ -221,11 +221,10 @@ struct
* then set new yAxis to FALLING * then set new yAxis to FALLING
* so we do not drop below any platforms again * so we do not drop below any platforms again
* *) * *)
if if QuadTree.hasCollisionAt (x, y, size, size, ~1, platformTree) then
QuadHelp.hasCollisionAt acc
(x, y, size, size, platformTree) else
then acc Fn.W_Y_AXIS FALLING :: acc
else Fn.W_Y_AXIS FALLING :: acc
| _ => acc | _ => acc
val acc = getWallPatches (x, y, walls, wallTree, acc) val acc = getWallPatches (x, y, walls, wallTree, acc)

View File

@@ -11,13 +11,17 @@ struct
else else
let let
val {id, x, y, width} = Vector.sub (platVec, pos) val {id, x, y, width} = Vector.sub (platVec, pos)
val acc = QuadHelp.insert val acc = QuadTree.insert (x, y, width, platHeight, id, acc)
(x, y, width, platHeight, id, acc)
in in
helpGenerateTree (pos + 1, platVec, acc) helpGenerateTree (pos + 1, platVec, acc)
end end
fun generateTree platVec = helpGenerateTree (0, platVec, QuadTree.empty) fun generateTree platVec =
helpGenerateTree
( 0
, platVec
, QuadTree.create (Constants.worldWidth, Constants.worldHeight)
)
fun helpFind (findNum, vec, low, high) = fun helpFind (findNum, vec, low, high) =
let let

View File

@@ -47,8 +47,8 @@ struct
(case attacked of (case attacked of
NOT_ATTACKED => NOT_ATTACKED =>
let let
val enemyCollisions = QuadHelp.getCollisions val enemyCollisions = QuadTree.getCollisions
(x, y, size, size, enemyTree) (x, y, size, size, ~1, enemyTree)
val player = val player =
Player.enemyCollisionReaction Player.enemyCollisionReaction
@@ -72,8 +72,8 @@ struct
if amt = Constants.attackedLimit then if amt = Constants.attackedLimit then
(* if reached limit, detect enemies again *) (* if reached limit, detect enemies again *)
let let
val enemyCollisions = QuadHelp.getCollisions val enemyCollisions = QuadTree.getCollisions
(x, y, size, size, enemyTree) (x, y, size, size, ~1, enemyTree)
val player = val player =
Player.exitAttackedAndCheckEnemies Player.exitAttackedAndCheckEnemies

View File

@@ -320,8 +320,9 @@ struct
let let
val player = #player game val player = #player game
val _ = print ("(playerX, playerY) = (" ^Int.toString (#x player) ^ ", " ^ val _ = print
Int.toString (#y player) ^ ")\n") ("(playerX, playerY) = (" ^ Int.toString (#x player) ^ ", "
^ Int.toString (#y player) ^ ")\n")
val patches = getProjectilePatches player val patches = getProjectilePatches player
val player = PlayerPatch.withPatches (player, patches) val player = PlayerPatch.withPatches (player, patches)
@@ -430,8 +431,8 @@ struct
val ww = Constants.worldWidth val ww = Constants.worldWidth
val wh = Constants.worldHeight val wh = Constants.worldHeight
val enemyCollisions = QuadHelp.getCollisions val enemyCollisions = QuadTree.getCollisions
(x, y, size, size, enemyTree) (x, y, size, size, ~1, enemyTree)
in in
Vector.fromList enemyCollisions Vector.fromList enemyCollisions
end end

View File

@@ -11,13 +11,17 @@ struct
val size = projectileSizeInt val size = projectileSizeInt
val {x, y, facing = _} = Vector.sub (projectiles, pos) val {x, y, facing = _} = Vector.sub (projectiles, pos)
val acc = QuadHelp.insert (x, y, size, size, pos, acc) val acc = QuadTree.insert (x, y, size, size, pos, acc)
in in
helpGenerateTree (pos + 1, projectiles, acc) helpGenerateTree (pos + 1, projectiles, acc)
end end
fun generateTree projectiles = fun generateTree projectiles =
helpGenerateTree (0, projectiles, QuadTree.empty) helpGenerateTree
( 0
, projectiles
, QuadTree.create (Constants.worldWidth, Constants.worldHeight)
)
fun helpGetProjectileVec fun helpGetProjectileVec
(pos, projectiles, width, height, ratio, xOffset, yOffset, acc) = (pos, projectiles, width, height, ratio, xOffset, yOffset, acc) =

View File

@@ -8,21 +8,15 @@ sig
| QUERY_ON_RIGHT_SIDE | QUERY_ON_RIGHT_SIDE
| QUERY_ON_BOTTOM_SIDE | QUERY_ON_BOTTOM_SIDE
val insert: int * int * int * int * val insert: int * int * int * int * int * t -> t
int * t -> t
val getCollisions: int * int * int * int * val getCollisions: int * int * int * int * int * t -> int list
int * t -> int list
val helpGetCollisions: int * int * int * int * val helpGetCollisions: int * int * int * int * int * int list * t -> int list
int * int list * t
-> int list
val hasCollisionAt: int * int * int * int * val hasCollisionAt: int * int * int * int * int * t -> bool
int * t -> bool
val getItemID: int * int * int * int * val getItemID: int * int * int * int * t -> int
t -> int
val create: int * int -> t val create: int * int -> t
end end
@@ -34,19 +28,10 @@ struct
type item = QuadTreeType.item type item = QuadTreeType.item
fun create (width, height) = fun create (width, height) =
LEAF { LEAF {items = Vector.fromList [], x = 0, y = 0, w = width, h = height}
items = Vector.fromList [],
x = 0,
y = 0,
w = width,
h = height
}
fun isColliding (ix, iy, ifx, ify, cx, cy, cfx, cfy) = fun isColliding (ix, iy, ifx, ify, cx, cy, cfx, cfy) =
ix < cfx andalso ix < cfx andalso ifx > cx andalso iy < cfy andalso ify > cy
ifx > cx andalso
iy < cfy andalso
ify > cy
fun isCollidingPlus (ix, iy, iw, ih, cx, cy, cw, ch) = fun isCollidingPlus (ix, iy, iw, ih, cx, cy, cw, ch) =
let let
@@ -145,13 +130,7 @@ struct
val hw = w div 2 val hw = w div 2
val hh = h div 2 val hh = h div 2
in in
LEAF { LEAF {items = items, x = x, y = y, w = hw, h = hh}
items = items,
x = x,
y = y,
w = hw,
h = hh
}
end end
fun mkTopRight (x, y, w, h, items) = fun mkTopRight (x, y, w, h, items) =
@@ -161,13 +140,7 @@ struct
val hh = h div 2 val hh = h div 2
val x = x + hw val x = x + hw
in in
LEAF { LEAF {items = items, x = x, y = y, w = hw, h = hh}
items = items,
x = x,
y = y,
w = hw,
h = hh
}
end end
fun mkBottomLeft (x, y, w, h, items) = fun mkBottomLeft (x, y, w, h, items) =
@@ -177,13 +150,7 @@ struct
val hh = h div 2 val hh = h div 2
val y = y + hh val y = y + hh
in in
LEAF { LEAF {items = items, x = x, y = y, w = hw, h = hh}
items = items,
x = x,
y = y,
w = hw,
h = hh
}
end end
fun mkBottomRight (x, y, w, h, items) = fun mkBottomRight (x, y, w, h, items) =
@@ -194,17 +161,21 @@ struct
val x = x + hw val x = x + hw
val y = y + hh val y = y + hh
in in
LEAF { LEAF {items = items, x = x, y = y, w = hw, h = hh}
items = items,
x = x,
y = y,
w = hw,
h = hh
}
end end
fun splitLeaf (x, y, w, h, tl: item list, tr: item list, bl: item list, br: fun splitLeaf
item list, elements, pos) = ( x
, y
, w
, h
, tl: item list
, tr: item list
, bl: item list
, br: item list
, elements
, pos
) =
if pos < 0 then if pos < 0 then
let let
val tl = mkTopLeft (x, y, w, h, tl) val tl = mkTopLeft (x, y, w, h, tl)
@@ -257,8 +228,15 @@ struct
val bl = insert (iX, iY, iW, iH, itemID, bottomLeft) val bl = insert (iX, iY, iW, iH, itemID, bottomLeft)
val br = insert (iX, iY, iW, iH, itemID, bottomRight) val br = insert (iX, iY, iW, iH, itemID, bottomRight)
in in
NODE {topLeft = tl, topRight = tr, bottomLeft = bl, bottomRight = br NODE
, x = x, y = y, w = w, h = h { topLeft = tl
, topRight = tr
, bottomLeft = bl
, bottomRight = br
, x = x
, y = y
, w = w
, h = h
} }
end end
else else
@@ -284,18 +262,7 @@ struct
val br = if vbr then [item] else [] val br = if vbr then [item] else []
in in
splitLeaf splitLeaf (x, y, w, h, tl, tr, bl, br, items, pos)
( x
, y
, w
, h
, tl
, tr
, bl
, br
, items
, pos
)
end end
else else
(* can insert itemID in items vector *) (* can insert itemID in items vector *)
@@ -311,13 +278,17 @@ struct
fun isColliding (iX, iY, iW, iH, itemID, checkWith: item) = fun isColliding (iX, iY, iW, iH, itemID, checkWith: item) =
let let
val {itemID = checkID, startX = cX, startY = cY, width = cW, height = cH, ...} = checkWith val
{ itemID = checkID
, startX = cX
, startY = cY
, width = cW
, height = cH
, ...
} = checkWith
in in
iX < cX + cW andalso iX < cX + cW andalso iX + iW > cX andalso iY < cY + cH
iX + iW > cX andalso andalso iY + iH > cY andalso itemID <> checkID
iY < cY + cH andalso
iY + iH > cY andalso
itemID <> checkID
end end
fun getCollisionsVec (iX, iY, iW, iH, itemID, pos, elements, acc) = fun getCollisionsVec (iX, iY, iW, iH, itemID, pos, elements, acc) =
@@ -338,93 +309,46 @@ struct
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} => NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
let let
val acc = getCollisionsAll val acc = getCollisionsAll (iX, iY, iW, iH, itemID, acc, topLeft)
(iX, iY, iW, iH, itemID, acc, topLeft)
val acc = getCollisionsAll val acc = getCollisionsAll (iX, iY, iW, iH, itemID, acc, topRight)
(iX, iY, iW, iH, itemID, acc, topRight)
val acc = getCollisionsAll val acc = getCollisionsAll (iX, iY, iW, iH, itemID, acc, bottomLeft)
(iX, iY, iW, iH, itemID, acc, bottomLeft)
in in
getCollisionsAll getCollisionsAll (iX, iY, iW, iH, itemID, acc, bottomRight)
(iX, iY, iW, iH, itemID, acc, bottomRight)
end end
else else
acc acc
| LEAF {items, x, y, w, h} => | LEAF {items, x, y, w, h} =>
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
getCollisionsVec (iX, iY, iW, iH, itemID, 0, items, acc) getCollisionsVec (iX, iY, iW, iH, itemID, 0, items, acc)
else acc else
acc
fun helpGetCollisions fun helpGetCollisions (iX, iY, iW, iH, itemID, acc, tree: t) =
( iX
, iY
, iW
, iH
, itemID
, acc
, tree: t
) =
case tree of case tree of
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} => NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
let let
val acc = val acc = helpGetCollisions (iX, iY, iW, iH, itemID, acc, topLeft)
helpGetCollisions
(iX, iY, iW, iH, itemID, acc, topLeft)
val acc = val acc = helpGetCollisions (iX, iY, iW, iH, itemID, acc, topRight)
helpGetCollisions
(iX, iY, iW, iH, itemID, acc, topRight)
val acc = val acc = helpGetCollisions
helpGetCollisions (iX, iY, iW, iH, itemID, acc, bottomLeft)
( iX
, iY
, iW
, iH
, itemID
, acc
, bottomLeft
)
in in
helpGetCollisions helpGetCollisions (iX, iY, iW, iH, itemID, acc, bottomRight)
( iX
, iY
, iW
, iH
, itemID
, acc
, bottomRight
)
end end
else else
acc acc
| LEAF {items, x, y, w, h} => | LEAF {items, x, y, w, h} =>
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
getCollisionsVec getCollisionsVec (iX, iY, iW, iH, itemID, 0, items, acc)
(iX, iY, iW, iH, itemID, 0, items, acc)
else else
acc acc
fun getCollisions fun getCollisions (itemX, itemY, itemWidth, itemHeight, itemID, tree) =
( itemX helpGetCollisions (itemX, itemY, itemWidth, itemHeight, itemID, [], tree)
, itemY
, itemWidth
, itemHeight
, itemID
, tree
) =
helpGetCollisions
( itemX
, itemY
, itemWidth
, itemHeight
, itemID
, []
, tree
)
(* no variant to represent 'no collision' case (* no variant to represent 'no collision' case
* because caller should only try getting collision side * because caller should only try getting collision side
@@ -481,38 +405,25 @@ struct
let let
val item = Vector.sub (elements, pos) val item = Vector.sub (elements, pos)
in in
isColliding (iX, iY, iW, iH, itemID, item) orelse isColliding (iX, iY, iW, iH, itemID, item)
hasCollisionAtVec (iX, iY, iW, iH, itemID, pos + 1, elements) orelse hasCollisionAtVec (iX, iY, iW, iH, itemID, pos + 1, elements)
end end
fun hasCollisionAt fun hasCollisionAt (iX, iY, iW, iH, itemID, tree) =
( iX
, iY
, iW
, iH
, itemID
, tree
) =
case tree of case tree of
NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} => NODE {topLeft, topRight, bottomLeft, bottomRight, x, y, w, h} =>
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
hasCollisionAt hasCollisionAt (iX, iY, iW, iH, itemID, topLeft)
(iX, iY, iW, iH, itemID, topLeft) orelse hasCollisionAt (iX, iY, iW, iH, itemID, topRight)
orelse orelse hasCollisionAt (iX, iY, iW, iH, itemID, bottomLeft)
hasCollisionAt orelse hasCollisionAt (iX, iY, iW, iH, itemID, bottomRight)
(iX, iY, iW, iH, itemID, topRight)
orelse
hasCollisionAt
(iX, iY, iW, iH, itemID, bottomLeft)
orelse
hasCollisionAt
(iX, iY, iW, iH, itemID, bottomRight)
else else
false false
| LEAF {items, x, y, w, h} => | LEAF {items, x, y, w, h} =>
if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then if isCollidingPlus (iX, iY, iW, iH, x, y, w, h) then
hasCollisionAtVec (iX, iY, iW, iH, itemID, 0, items) hasCollisionAtVec (iX, iY, iW, iH, itemID, 0, items)
else false else
false
fun getItemIDVec (iX, iY, iW, iH, pos, elements) = fun getItemIDVec (iX, iY, iW, iH, pos, elements) =
if pos = Vector.length elements then if pos = Vector.length elements then

View File

@@ -6,13 +6,17 @@ struct
else else
let let
val {id, x, y, width, height} = Vector.sub (wallVec, pos) val {id, x, y, width, height} = Vector.sub (wallVec, pos)
val acc = QuadHelp.insert val acc = QuadTree.insert (x, y, width, height, id, acc)
(x, y, width, height, id, acc)
in in
helpGenerateTree (pos + 1, wallVec, acc) helpGenerateTree (pos + 1, wallVec, acc)
end end
fun generateTree wallVec = helpGenerateTree (0, wallVec, QuadTree.empty) fun generateTree wallVec =
helpGenerateTree
( 0
, wallVec
, QuadTree.create (Constants.worldWidth, Constants.worldHeight)
)
fun helpGetDrawVecWider fun helpGetDrawVecWider
(pos, wallVec, acc, winWidth, winHeight, ratio, yOffset) = (pos, wallVec, acc, winWidth, winHeight, ratio, yOffset) =

View File

@@ -157,6 +157,8 @@ typedef Pointer Objptr;
extern "C" { extern "C" {
#endif #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_PRIVATE
#undef MLLIB_PUBLIC #undef MLLIB_PUBLIC