add function to return which side a collision occurs at
This commit is contained in:
@@ -2,6 +2,12 @@ signature QUAD_TREE =
|
|||||||
sig
|
sig
|
||||||
type t
|
type t
|
||||||
|
|
||||||
|
datatype collision_side =
|
||||||
|
QUERY_ON_LEFT_SIDE
|
||||||
|
| QUERY_ON_TOP_SIDE
|
||||||
|
| QUERY_ON_RIGHT_SIDE
|
||||||
|
| QUERY_ON_BOTTOM_SIDE
|
||||||
|
|
||||||
val insert : int * int * int * int *
|
val insert : int * int * int * int *
|
||||||
int * int * int * int *
|
int * int * int * int *
|
||||||
int * t -> t
|
int * t -> t
|
||||||
@@ -307,6 +313,64 @@ struct
|
|||||||
andalso itemID <> checkID
|
andalso itemID <> checkID
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(* no variant to represent 'no collision' case
|
||||||
|
* because caller should only try getting collision side
|
||||||
|
* after checking that there is any collision. *)
|
||||||
|
datatype collision_side =
|
||||||
|
QUERY_ON_LEFT_SIDE
|
||||||
|
| QUERY_ON_TOP_SIDE
|
||||||
|
| QUERY_ON_RIGHT_SIDE
|
||||||
|
| QUERY_ON_BOTTOM_SIDE
|
||||||
|
|
||||||
|
(* getCollisionSide function ported from this answer:
|
||||||
|
* https://stackoverflow.com/a/56607347
|
||||||
|
* *)
|
||||||
|
fun getCollisionSide (iX, iY, iW, iH, checkWith: item) =
|
||||||
|
let
|
||||||
|
val iFinishX = iX + iW
|
||||||
|
val iFinishY = iY + iH
|
||||||
|
val iHalfW = iW div 2
|
||||||
|
val iHalfH = iH div 2
|
||||||
|
val iCentreX = iX + iHalfW
|
||||||
|
val iCentreY = iY + iHalfH
|
||||||
|
|
||||||
|
val {startX = cX, startY = cY, width = cW, height = cH, ...} = item
|
||||||
|
|
||||||
|
val cFinishX = cX + cW
|
||||||
|
val cFinishY = cY + cH
|
||||||
|
val cHalfW = cW div 2
|
||||||
|
val cHalfH = cH div 2
|
||||||
|
val cCentreX = cX + cHalfW
|
||||||
|
val cCentreY = cY + cHalfH
|
||||||
|
|
||||||
|
val diffX = iCentreX - cCentreX
|
||||||
|
val diffY = iCentreY - cCentreY
|
||||||
|
|
||||||
|
val minXDist = iHalfW + cHalfW
|
||||||
|
val minYDist = iHalfH + cHalfH
|
||||||
|
|
||||||
|
val depthX =
|
||||||
|
if diffX > 0
|
||||||
|
then minXDist - diffX
|
||||||
|
else (~minXDist) - diffX
|
||||||
|
|
||||||
|
val depthY =
|
||||||
|
if diffY > 0
|
||||||
|
then minYDist - diffY
|
||||||
|
else (~minYDist) - diffY
|
||||||
|
in
|
||||||
|
if abs depthX < abs depthY then
|
||||||
|
if depthX > 0 then
|
||||||
|
QUERY_ON_LEFT_SIDE
|
||||||
|
else
|
||||||
|
QUERY_ON_RIGHT_SIDE
|
||||||
|
else
|
||||||
|
if depthY > 0 then
|
||||||
|
QUERY_ON_TOP_SIDE
|
||||||
|
else
|
||||||
|
QUERY_ON_BOTTOM_SIDE
|
||||||
|
end
|
||||||
|
|
||||||
fun getCollisionsVec (iX, iY, iW, iH, itemID, pos, elements, acc) =
|
fun getCollisionsVec (iX, iY, iW, iH, itemID, pos, elements, acc) =
|
||||||
if pos = Vector.length elements then
|
if pos = Vector.length elements then
|
||||||
acc
|
acc
|
||||||
@@ -321,6 +385,27 @@ struct
|
|||||||
getCollisionsVec (iX, iY, iW, iH, itemID, pos + 1, elements, acc)
|
getCollisionsVec (iX, iY, iW, iH, itemID, pos + 1, elements, acc)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
(* like getCollisionsVec, but instead of consing just the itemID,
|
||||||
|
* it also conses the "collision-side" information.
|
||||||
|
* *)
|
||||||
|
fun getCollisionSideVec (iX, iY, iW, iH, itemID, pos, elements, acc) =
|
||||||
|
if pos = Vector.length elements then
|
||||||
|
acc
|
||||||
|
else
|
||||||
|
let
|
||||||
|
val item = Vector.sub (elements, pos)
|
||||||
|
val acc =
|
||||||
|
if isColliding (iX, iY, iW, iH, itemID, item) then
|
||||||
|
let
|
||||||
|
val side = getCollisionSide (iX, iY, iW, iH, item)
|
||||||
|
in
|
||||||
|
(side, #itemID item) :: acc
|
||||||
|
end
|
||||||
|
else acc
|
||||||
|
in
|
||||||
|
getCollisionsVec (iX, iY, iW, iH, itemID, pos + 1, elements, acc)
|
||||||
|
end
|
||||||
|
|
||||||
fun getCollisionsAll
|
fun getCollisionsAll
|
||||||
( iX, iY, iW, iH, qW, qH
|
( iX, iY, iW, iH, qW, qH
|
||||||
, itemID, acc, tree
|
, itemID, acc, tree
|
||||||
|
|||||||
9
fcore/wall.sml
Normal file
9
fcore/wall.sml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
structure Wall =
|
||||||
|
struct
|
||||||
|
(* Wall or platform, where player can land after falling.
|
||||||
|
* Difference between wall and platform is that one can jump to a platform
|
||||||
|
* and go below it, but wall is completely opaque. *)
|
||||||
|
datatype wall_type = WALL | PLATFORM
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user