have functiokn to get upwards path semi-working

This commit is contained in:
2025-01-18 00:25:27 +00:00
parent 560ef3f99a
commit f796f2f858
2 changed files with 164 additions and 5 deletions

View File

@@ -131,6 +131,124 @@ struct
| STAY_STILL => acc
end
(* new pathfinding using quad tree *)
fun getUpwardsPath
(playerPlatID, currentPlatID, platforms, platformTree, dist) =
if playerPlatID = currentPlatID then
(dist, [currentPlatID])
else
let
val currentPlat = Platform.find (currentPlatID, platforms)
val {x, y, width, ...} = currentPlat
val searchY = y - Constants.jumpLimit - 1
val searchH = Constants.jumpLimit
(* todo: x/width are placeholder values.
* They should define values that let reachable platforms
* on the top left/top right be included in the collision list
* but they currentl are not. *)
val searchX = x
val searchW = width
val ww = Constants.worldWidth
val wh = Constants.worldHeight
val upList = QuadTree.getCollisions
(searchX, searchY, searchW, searchH, 0, 0, ww, wh, ~1, platformTree)
val (bestDist, bestPath) = helpGetUpwardsPath
( playerPlatID
, platforms
, platformTree
, upList
, dist
, currentPlat
, ~1
, []
)
in
if bestDist = ~1 then
(* invalid; return error value *)
(~1, [])
else
(* is valid, so cons currentPlatID to path *)
(bestDist, currentPlatID :: bestPath)
end
and helpGetUpwardsPath
( playerPlatID
, platforms
, platformTree
, lst
, dist
, prevPlat
, bestDist
, bestPath
) =
case lst of
id :: tl =>
let
val currentPlat = Platform.find (id, platforms)
val {y = cy, ...} = currentPlat
val {y = py, ...} = prevPlat
val diff = py - cy
val platDist = dist + diff
val (newDist, newPath) = getUpwardsPath
(playerPlatID, id, platforms, platformTree, platDist)
in
if newDist = ~1 then
(* newPath is invalid, so reuse old path *)
helpGetUpwardsPath
( playerPlatID
, platforms
, platformTree
, tl
, dist
, prevPlat
, bestDist
, bestPath
)
else if bestDist = ~1 then
(* bestPath is invalid *)
helpGetUpwardsPath
( playerPlatID
, platforms
, platformTree
, tl
, dist
, prevPlat
, newDist
, newPath
)
else if newDist < bestDist then
helpGetUpwardsPath
( playerPlatID
, platforms
, platformTree
, tl
, dist
, prevPlat
, newDist
, newPath
)
else
helpGetUpwardsPath
( playerPlatID
, platforms
, platformTree
, tl
, dist
, prevPlat
, bestDist
, bestPath
)
end
| [] => (bestDist, bestPath)
(* pathfinding *)
fun getHighestPlatform (collisions, platforms, highestY, highestID) =
case collisions of
id :: tl =>
@@ -144,7 +262,7 @@ struct
end
| [] => highestID
fun getPlatformBelowPlayer (player: player, platformTree, platforms) =
fun getPlatformBelowPlayer (player, platformTree, platforms) =
let
val {x, y, ...} = player
@@ -160,6 +278,22 @@ struct
getHighestPlatform (collisions, platforms, wh, ~1)
end
fun getPlatformBelowEnemy (enemy: enemy, platformTree, platforms) =
let
val {x, y, ...} = enemy
val searchWidth = Constants.enemySize
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)
in
getHighestPlatform (collisions, platforms, wh, ~1)
end
fun canJumpOnPID (collisions, pID) =
case collisions of
id :: tl => (id = pID) orelse canJumpOnPID (tl, pID)
@@ -171,6 +305,29 @@ struct
val {x, y, ...} = enemy
val eID = getPlatformBelowEnemy (enemy, platformTree, platforms)
val (bestDist, bestPath) =
if eID > ~1 andalso pID > ~1 then
getUpwardsPath (pID, eID, platforms, platformTree, 0)
else
(~1, [])
val _ =
if bestDist = ~1 then
print "no path\n"
else
let
val _ = print "has path:\n"
val _ =
List.map
(fn platID =>
print ("best path platID: " ^ Int.toString platID ^ "\n"))
bestPath
in
()
end
val distance = Constants.moveEnemyBy * Constants.jumpLimit
val distance = distance div 2
@@ -193,7 +350,7 @@ struct
orelse canJumpOnPID (leftCollisions, pID)
end
(* pathfinding *)
fun getFollowPatches
(player: player, enemy, wallTree, platformTree, platforms, acc) =
let
@@ -206,7 +363,6 @@ struct
val isOnPlatform = standingOnArea (enemy, platformTree)
val hasPlatformAbove =
canJumpOnPlatform (player, platforms, enemy, platformTree)
val () = print ("canJump: " ^ Bool.toString hasPlatformAbove ^ "\n")
val shouldJump = (isOnWall orelse isOnPlatform) andalso hasPlatformAbove
val yAxis =
@@ -218,7 +374,7 @@ struct
else
eyAxis
in
EnemyPatch.W_Y_AXIS yAxis :: EnemyPatch.W_X_AXIS xAxis :: acc
EnemyPatch.W_X_AXIS STAY_STILL :: acc
end
fun getVariantPatches

View File

@@ -164,7 +164,10 @@ struct
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 = 555}
val platforms = Vector.fromList [plat1, plat2, plat3]
val plat4 = {id = 4, x = 155, y = 855, width = 199}
val plat5 = {id = 5, x = 155, y = 759, width = 199}
val plat6 = {id = 6, x = 155, y = 610, width = 199}
val platforms = Vector.fromList [plat1, plat2, plat3, plat4, plat5, plat6]
val platformTree = Platform.generateTree platforms
val enemy1 =