139 lines
4.3 KiB
Standard ML
139 lines
4.3 KiB
Standard ML
structure Player =
|
|
struct
|
|
datatype y_axis = ON_GROUND | FALLING | JUMPING of int
|
|
datatype x_axis = MOVE_LEFT | STAY_STILL | MOVE_RIGHT
|
|
|
|
(* width/height *)
|
|
val size = 35
|
|
val realSize = 35.0
|
|
|
|
val moveBy = 5
|
|
val jumpLimit = 150
|
|
|
|
type t = {yAxis: y_axis, xAxis: x_axis, health: int, x: int, y: int}
|
|
|
|
(* placeholder *)
|
|
val initial: t =
|
|
{yAxis = JUMPING 0, xAxis = STAY_STILL, health = 3, x = 500, y = 500}
|
|
|
|
(* placeholder *)
|
|
fun getVec ({x, y, ...}: t) =
|
|
Block.lerp (x, y, realSize, realSize, 1920.0, 1080.0, 0.5, 0.5, 0.5)
|
|
|
|
fun mkPlayer (health, xAxis, yAxis, x, y) =
|
|
{yAxis = yAxis, xAxis = xAxis, health = health, x = x, y = y}
|
|
|
|
fun checkWalls (yAxis, xAxis, x, y, health, lst) =
|
|
let
|
|
open QuadTree
|
|
in
|
|
case lst of
|
|
(QUERY_ON_LEFT_SIDE, wallID) :: tl =>
|
|
let
|
|
val {x = wallX, width = wallWidth, ...} = Wall.getID wallID
|
|
val newX = wallX + wallWidth
|
|
in
|
|
checkWalls (yAxis, xAxis, newX, y, health, tl)
|
|
end
|
|
| (QUERY_ON_RIGHT_SIDE, wallID) :: tl =>
|
|
let
|
|
val {x = wallX, width = wallWidth, ...} = Wall.getID wallID
|
|
val newX = wallX - size
|
|
in
|
|
checkWalls (yAxis, xAxis, newX, y, health, tl)
|
|
end
|
|
| (QUERY_ON_BOTTOM_SIDE, wallID) :: tl =>
|
|
let
|
|
val {y = wallY, ...} = Wall.getID wallID
|
|
val newY = wallY - size
|
|
in
|
|
checkWalls (ON_GROUND, xAxis, x, newY, health, tl)
|
|
end
|
|
| (QUERY_ON_TOP_SIDE, wallID) :: tl =>
|
|
checkWalls (yAxis, xAxis, x, y, health, tl)
|
|
| [] => mkPlayer (health, xAxis, yAxis, x, y)
|
|
end
|
|
|
|
fun helpMove (x, y, xAxis, yAxis, health) =
|
|
let
|
|
(* check against wall quad tree *)
|
|
val desiredX =
|
|
case xAxis of
|
|
STAY_STILL => x
|
|
| MOVE_LEFT => x - moveBy
|
|
| MOVE_RIGHT => x + moveBy
|
|
in
|
|
case yAxis of
|
|
ON_GROUND =>
|
|
let
|
|
val collisions = QuadTree.getCollisionSides
|
|
(desiredX, y, size, size, 0, 0, 1920, 1080, 0, Wall.tree)
|
|
in
|
|
checkWalls (yAxis, xAxis, desiredX, y, health, collisions)
|
|
end
|
|
| FALLING =>
|
|
let
|
|
val desiredY = y + moveBy
|
|
val collisions = QuadTree.getCollisionSides
|
|
(desiredX, desiredY, size, size, 0, 0, 1920, 1080, 0, Wall.tree)
|
|
in
|
|
checkWalls (yAxis, xAxis, desiredX, desiredY, health, collisions)
|
|
end
|
|
| JUMPING jumped =>
|
|
if jumped + moveBy > jumpLimit then
|
|
(* if we are above the jump limit, trigger a fall *)
|
|
let
|
|
val collisions = QuadTree.getCollisionSides
|
|
(desiredX, y, size, size, 0, 0, 1920, 1080, 0, Wall.tree)
|
|
in
|
|
checkWalls (FALLING, xAxis, desiredX, y, health, collisions)
|
|
end
|
|
else
|
|
(* jump *)
|
|
let
|
|
val newJumped = jumped + moveBy
|
|
val yAxis = JUMPING newJumped
|
|
val desiredY = y - moveBy
|
|
|
|
val collisions = QuadTree.getCollisionSides
|
|
(desiredX, desiredY, size, size, 0, 0, 1920, 1080, 0, Wall.tree)
|
|
in
|
|
checkWalls (yAxis, xAxis, desiredX, desiredY, health, collisions)
|
|
end
|
|
end
|
|
|
|
fun getXAxis (lh, rh) =
|
|
case (lh, rh) of
|
|
(false, false) => STAY_STILL
|
|
| (false, true) => MOVE_RIGHT
|
|
| (true, false) => MOVE_LEFT
|
|
| (true, true) => STAY_STILL
|
|
|
|
fun getYAxis (uh, dh, yAxis) =
|
|
case (uh, dh) of
|
|
(false, false) =>
|
|
(* default yAxis of FALLING does two things:
|
|
* 1. When player walks off platform, gravity is applied.
|
|
* 2. When player presses up for a short period of time,
|
|
* the player makes a shorter jump rather than jumping longer.
|
|
* *)
|
|
FALLING
|
|
| (true, true) => FALLING
|
|
| (true, false) =>
|
|
(case yAxis of
|
|
ON_GROUND => JUMPING 0
|
|
| _ => yAxis)
|
|
| (false, true) =>
|
|
(* todo: should move down if on platform *)
|
|
yAxis
|
|
|
|
fun move
|
|
({x, y, yAxis, health, ...}: t, {leftHeld, rightHeld, upHeld, downHeld}) =
|
|
let
|
|
val xAxis = getXAxis (leftHeld, rightHeld)
|
|
val yAxis = getYAxis (upHeld, downHeld, yAxis)
|
|
in
|
|
helpMove (x, y, xAxis, yAxis, health)
|
|
end
|
|
end
|