From cbddc03a882f4f71331432e6ddc814e989484da2 Mon Sep 17 00:00:00 2001 From: Humza Shahid Date: Fri, 17 Jan 2025 13:18:02 +0000 Subject: [PATCH] progress towards implementing follow slime (slime only tries jumping when platform is reachable now) --- fcore/enemy-behaviour.sml | 58 +++++++++++++++++++++++++++++++++------ fcore/game-type.sml | 4 ++- fcore/platform.sml | 14 ++++++++++ 3 files changed, 67 insertions(+), 9 deletions(-) diff --git a/fcore/enemy-behaviour.sml b/fcore/enemy-behaviour.sml index a038e8d..f7f9653 100644 --- a/fcore/enemy-behaviour.sml +++ b/fcore/enemy-behaviour.sml @@ -131,8 +131,44 @@ struct | STAY_STILL => acc end - fun canJumpOnPlatform (enemy: enemy, platformTree) = + fun getHighestPlatform (collisions, platforms, highestY, highestID) = + case collisions of + id :: tl => + let + val {y = platY, ...} = Platform.find (id, platforms) + in + (* platY < highestY is correct because lowest number = highest + * in * this case *) + if platY < highestY then getHighestPlatform (tl, platforms, platY, id) + else getHighestPlatform (tl, platforms, highestY, highestID) + end + | [] => highestID + + fun getPlatformBelowPlayer (player: player, platformTree, platforms) = let + val {x, y, ...} = player + + 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) + in + getHighestPlatform (collisions, platforms, wh, ~1) + end + + fun canJumpOnPID (collisions, pID) = + case collisions of + id :: tl => (id = pID) orelse canJumpOnPID (tl, pID) + | [] => false + + fun canJumpOnPlatform (player, platforms, enemy: enemy, platformTree) = + let + val pID = getPlatformBelowPlayer (player, platformTree, platforms) + val {x, y, ...} = enemy val distance = Constants.moveEnemyBy * Constants.jumpLimit @@ -146,16 +182,20 @@ struct val wh = Constants.worldHeight val mx = x - distance - in - QuadTree.hasCollisionAt + + val rightCollisions = QuadTree.getCollisions (x, y, distance, yDistance, 0, 0, ww, wh, ~1, platformTree) - orelse - QuadTree.hasCollisionAt + + val leftCollisions = QuadTree.getCollisions (mx, y, distance, yDistance, 0, 0, ww, wh, ~1, platformTree) + in + canJumpOnPID (rightCollisions, pID) + orelse canJumpOnPID (leftCollisions, pID) end (* pathfinding *) - fun getFollowPatches (player: player, enemy, wallTree, platformTree, acc) = + fun getFollowPatches + (player: player, enemy, wallTree, platformTree, platforms, acc) = let val {x = px, y = py, ...} = player val {x = ex, y = ey, yAxis = eyAxis, ...} = enemy @@ -164,7 +204,8 @@ struct val isOnWall = standingOnArea (enemy, wallTree) val isOnPlatform = standingOnArea (enemy, platformTree) - val hasPlatformAbove = canJumpOnPlatform (enemy, platformTree) + val hasPlatformAbove = + canJumpOnPlatform (player, platforms, enemy, platformTree) val () = print ("canJump: " ^ Bool.toString hasPlatformAbove ^ "\n") val shouldJump = (isOnWall orelse isOnPlatform) andalso hasPlatformAbove @@ -188,6 +229,7 @@ struct case #variant enemy of PATROL_SLIME => getPatrollPatches (enemy, wallTree, platformTree, acc) | FOLLOW_SIME => - getFollowPatches (player, enemy, wallTree, platformTree, acc) + getFollowPatches + (player, enemy, wallTree, platformTree, platforms, acc) end end diff --git a/fcore/game-type.sml b/fcore/game-type.sml index d1f6402..af3a16d 100644 --- a/fcore/game-type.sml +++ b/fcore/game-type.sml @@ -162,7 +162,9 @@ struct val wallTree = Wall.generateTree walls val plat1 = {id = 1, x = 155, y = 911, width = 199} - val platforms = Vector.fromList [plat1] + 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 platformTree = Platform.generateTree platforms val enemy1 = diff --git a/fcore/platform.sml b/fcore/platform.sml index b70717b..7e1c1a7 100644 --- a/fcore/platform.sml +++ b/fcore/platform.sml @@ -19,6 +19,20 @@ struct fun generateTree platVec = helpGenerateTree (0, platVec, QuadTree.empty) + fun helpFind (findNum, vec, low, high) = + let + val mid = low + ((high - low) div 2) + val platform = Vector.sub (vec, mid) + val {id = curNum, x = _, y = _, width = _} = platform + in + if curNum = findNum then platform + else if curNum < findNum then helpFind (findNum, vec, mid + 1, high) + else helpFind (findNum, vec, low, mid - 1) + end + + fun find (findNum, vec) = + helpFind (findNum, vec, 0, Vector.length vec - 1) + fun helpGetDrawVecWider (pos, platVec, acc, winWidth, winHeight, ratio, yOffset) = if pos = Vector.length platVec then