add player_attacked datatype to player record, and refactor

This commit is contained in:
2024-12-20 07:38:41 +00:00
parent fec4d996d9
commit 58f552b38b
2 changed files with 138 additions and 42 deletions

View File

@@ -15,10 +15,13 @@ sig
datatype player_recoil = NO_RECOIL | RECOIL_LEFT of int | RECOIL_RIGHT of int datatype player_recoil = NO_RECOIL | RECOIL_LEFT of int | RECOIL_RIGHT of int
datatype player_attacked = NOT_ATTACKED | ATTACKED of int
type player = type player =
{ yAxis: player_y_axis { yAxis: player_y_axis
, xAxis: player_x_axis , xAxis: player_x_axis
, recoil: player_recoil , recoil: player_recoil
, attacked: player_attacked
, health: int , health: int
, x: int , x: int
, y: int , y: int
@@ -58,10 +61,13 @@ struct
datatype player_recoil = NO_RECOIL | RECOIL_LEFT of int | RECOIL_RIGHT of int datatype player_recoil = NO_RECOIL | RECOIL_LEFT of int | RECOIL_RIGHT of int
datatype player_attacked = NOT_ATTACKED | ATTACKED of int
type player = type player =
{ yAxis: player_y_axis { yAxis: player_y_axis
, xAxis: player_x_axis , xAxis: player_x_axis
, recoil: player_recoil , recoil: player_recoil
, attacked: player_attacked
, health: int , health: int
, x: int , x: int
, y: int , y: int
@@ -86,6 +92,7 @@ struct
{ yAxis = JUMPING 0 { yAxis = JUMPING 0
, xAxis = STAY_STILL , xAxis = STAY_STILL
, recoil = NO_RECOIL , recoil = NO_RECOIL
, attacked = NOT_ATTACKED
, health = 3 , health = 3
, x = 500 , x = 500
, y = 500 , y = 500

View File

@@ -11,18 +11,20 @@ struct
val jumpLimit = 150 val jumpLimit = 150
val floatLimit = 3 val floatLimit = 3
val recoilLimit = 15 val recoilLimit = 15
val attackLimit = 35
fun mkPlayer (health, xAxis, yAxis, x, y, jumpPressed, recoil) = fun mkPlayer (health, xAxis, yAxis, x, y, jumpPressed, recoil, attacked) =
{ yAxis = yAxis { yAxis = yAxis
, xAxis = xAxis , xAxis = xAxis
, recoil = recoil , recoil = recoil
, attacked = attacked
, health = health , health = health
, x = x , x = x
, y = y , y = y
, jumpPressed = jumpPressed , jumpPressed = jumpPressed
} }
fun checkWalls (yAxis, xAxis, x, y, health, jumpPressed, recoil, lst, game: game_type) = fun checkWalls (yAxis, xAxis, x, y, health, jumpPressed, recoil, attacked, lst, game: game_type) =
let let
open QuadTree open QuadTree
in in
@@ -35,7 +37,10 @@ struct
val newX = wallX + wallWidth val newX = wallX + wallWidth
in in
checkWalls (yAxis, xAxis, newX, y, health, jumpPressed, recoil, tl, game) checkWalls
( yAxis, xAxis, newX, y, health, jumpPressed
, recoil, attacked, tl, game
)
end end
| (QUERY_ON_RIGHT_SIDE, wallID) :: tl => | (QUERY_ON_RIGHT_SIDE, wallID) :: tl =>
let let
@@ -45,7 +50,10 @@ struct
val newX = wallX - size val newX = wallX - size
in in
checkWalls (yAxis, xAxis, newX, y, health, jumpPressed, recoil, tl, game) checkWalls
( yAxis, xAxis, newX, y, health, jumpPressed
, recoil, attacked, tl, game
)
end end
| (QUERY_ON_BOTTOM_SIDE, wallID) :: tl => | (QUERY_ON_BOTTOM_SIDE, wallID) :: tl =>
let let
@@ -55,17 +63,22 @@ struct
val newY = wallY - size val newY = wallY - size
in in
checkWalls checkWalls
(ON_GROUND, xAxis, x, newY, health, jumpPressed, recoil, tl, game) ( ON_GROUND, xAxis, x, newY, health, jumpPressed
, recoil, attacked, tl, game
)
end end
| (QUERY_ON_TOP_SIDE, wallID) :: tl => | (QUERY_ON_TOP_SIDE, wallID) :: tl =>
checkWalls (yAxis, xAxis, x, y, health, jumpPressed, recoil, tl, game) checkWalls
( yAxis, xAxis, x, y, health, jumpPressed
, recoil, attacked, tl, game
)
| [] => | [] =>
mkPlayer (health, xAxis, yAxis, x, y, jumpPressed, recoil) mkPlayer (health, xAxis, yAxis, x, y, jumpPressed, recoil, attacked)
end end
fun helpCheckPlatforms fun helpCheckPlatforms
( yAxis, xAxis, x, y, health ( yAxis, xAxis, x, y, health
, jumpPressed, recoil , jumpPressed, recoil, attacked
, platList, wallList, game , platList, wallList, game
) = ) =
let let
@@ -77,11 +90,17 @@ struct
DROP_BELOW_PLATFORM => DROP_BELOW_PLATFORM =>
(* pass through, allowing player to drop below the platform *) (* pass through, allowing player to drop below the platform *)
helpCheckPlatforms helpCheckPlatforms
(yAxis, xAxis, x, y, health, jumpPressed, recoil, tl, wallList, game) ( yAxis, xAxis, x, y, health
, jumpPressed, recoil, attacked
, tl, wallList, game
)
| JUMPING _ => | JUMPING _ =>
(* pass through, allowing player to jump above the platform *) (* pass through, allowing player to jump above the platform *)
helpCheckPlatforms helpCheckPlatforms
(yAxis, xAxis, x, y, health, jumpPressed, recoil, tl, wallList, game) ( yAxis, xAxis, x, y, health
, jumpPressed, recoil, attacked
, tl, wallList, game
)
| _ => | _ =>
let let
(* default case: (* default case:
@@ -104,14 +123,21 @@ struct
val newY = platY - size val newY = platY - size
in in
helpCheckPlatforms helpCheckPlatforms
(ON_GROUND, xAxis, x, newY, health, jumpPressed, recoil, tl, wallList, game) ( ON_GROUND, xAxis, x, newY, health
, jumpPressed, recoil, attacked
, tl, wallList, game
)
end) end)
| [] => | [] =>
checkWalls (yAxis, xAxis, x, y, health, jumpPressed, recoil, wallList, game) checkWalls
( yAxis, xAxis, x, y, health
, jumpPressed, recoil, attacked
, wallList, game
)
end end
fun checkEnemies fun checkEnemies
( yAxis, xAxis, x, y, health, jumpPressed, recoil ( yAxis, xAxis, x, y, health, jumpPressed, recoil, attacked
, enemyCollisions, platCollisions, wallCollisions, game , enemyCollisions, platCollisions, wallCollisions, game
) = ) =
case enemyCollisions of case enemyCollisions of
@@ -135,19 +161,27 @@ struct
else else
RECOIL_LEFT 0 RECOIL_LEFT 0
end end
val attacked = ATTACKED 0
in in
checkEnemies checkEnemies
( FALLING, STAY_STILL, x, y, health, jumpPressed, newRecoil ( FALLING, STAY_STILL, x, y, health
, jumpPressed, newRecoil, attacked
, tl, platCollisions, wallCollisions, game , tl, platCollisions, wallCollisions, game
) )
end end
| [] => | [] =>
helpCheckPlatforms helpCheckPlatforms
( yAxis, xAxis, x, y, health, jumpPressed, recoil ( yAxis, xAxis, x, y, health
, jumpPressed, recoil, attacked
, platCollisions, wallCollisions, game , platCollisions, wallCollisions, game
) )
fun checkCollisions (yAxis, xAxis, x, y, health, jumpPressed, recoil, game) = fun checkCollisions
( yAxis, xAxis, x, y, health
, jumpPressed, recoil
, attacked, game
) =
let let
val {wallTree, platformTree, enemyTree, ...} = game val {wallTree, platformTree, enemyTree, ...} = game
@@ -163,25 +197,52 @@ struct
val wallCollisions = QuadTree.getCollisionSides val wallCollisions = QuadTree.getCollisionSides
(x, y, size, size, 0, 0, 1920, 1080, 0, wallTree) (x, y, size, size, 0, 0, 1920, 1080, 0, wallTree)
in in
case recoil of (* skip enemy collisions if player is in attacked state
NO_RECOIL => * because games often offer a short cooldown period
* where player can walk through enemies without receiving damage
* in which case enemy collisions don't count
* *)
case attacked of
NOT_ATTACKED =>
let let
val enemyCollisions = QuadTree.getCollisions val enemyCollisions = QuadTree.getCollisions
(x, y, size, size, 0, 0, 1920, 1080, 0, enemyTree) (x, y, size, size, 0, 0, 1920, 1080, 0, enemyTree)
in in
checkEnemies checkEnemies
( yAxis, xAxis, x, y, health, jumpPressed, recoil ( yAxis, xAxis, x, y, health
, jumpPressed, recoil, attacked
, enemyCollisions, platCollisions, wallCollisions, game , enemyCollisions, platCollisions, wallCollisions, game
) )
end end
| _ => | ATTACKED amt =>
helpCheckPlatforms if amt = attackLimit then
( yAxis, xAxis, x, y, health, jumpPressed, recoil (* if we hit limit, exit ATTACKED phase
, platCollisions, wallCollisions, game * and react to enemy collisions again
) * *)
let
val enemyCollisions = QuadTree.getCollisions
(x, y, size, size, 0, 0, 1920, 1080, 0, enemyTree)
in
checkEnemies
( yAxis, xAxis, x, y, health
, jumpPressed, recoil, NOT_ATTACKED
, enemyCollisions, platCollisions, wallCollisions, game
)
end
else
let
val amt = amt + 1
val attacked = ATTACKED amt
in
helpCheckPlatforms
( yAxis, xAxis, x, y, health
, jumpPressed, recoil, attacked
, platCollisions, wallCollisions, game
)
end
end end
fun helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, game) = fun helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, attacked, game) =
let let
(* check against wall quad tree *) (* check against wall quad tree *)
val desiredX = val desiredX =
@@ -193,28 +254,34 @@ struct
case yAxis of case yAxis of
ON_GROUND => ON_GROUND =>
checkCollisions checkCollisions
(yAxis, xAxis, desiredX, y, health, jumpPressed, recoil, game) ( yAxis, xAxis, desiredX, y, health
, jumpPressed, recoil, attacked, game
)
| FLOATING floated => | FLOATING floated =>
let let
val yAxis = val yAxis =
if floated = floatLimit then FALLING else FLOATING (floated + 1) if floated = floatLimit then FALLING else FLOATING (floated + 1)
in in
checkCollisions checkCollisions
(yAxis, xAxis, desiredX, y, health, jumpPressed, recoil, game) (yAxis, xAxis, desiredX, y, health, jumpPressed, recoil, attacked, game)
end end
| FALLING => | FALLING =>
let let
val desiredY = y + moveBy val desiredY = y + moveBy
in in
checkCollisions checkCollisions
(yAxis, xAxis, desiredX, desiredY, health, jumpPressed, recoil, game) ( yAxis, xAxis, desiredX, desiredY, health
, jumpPressed, recoil, attacked, game
)
end end
| DROP_BELOW_PLATFORM => | DROP_BELOW_PLATFORM =>
let let
val desiredY = y + moveBy val desiredY = y + moveBy
in in
checkCollisions checkCollisions
(yAxis, xAxis, desiredX, desiredY, health, jumpPressed, recoil, game) ( yAxis, xAxis, desiredX, desiredY, health
, jumpPressed, recoil, attacked, game
)
end end
| JUMPING jumped => | JUMPING jumped =>
if jumped + moveBy > jumpLimit then if jumped + moveBy > jumpLimit then
@@ -223,7 +290,9 @@ struct
val newYAxis = FLOATING 0 val newYAxis = FLOATING 0
in in
checkCollisions checkCollisions
(newYAxis, xAxis, desiredX, y, health, jumpPressed, recoil, game) ( newYAxis, xAxis, desiredX, y, health
, jumpPressed, recoil, attacked, game
)
end end
else else
(* jump *) (* jump *)
@@ -234,7 +303,7 @@ struct
in in
checkCollisions checkCollisions
( newYAxis, xAxis, desiredX, desiredY ( newYAxis, xAxis, desiredX, desiredY
, health, jumpPressed, recoil, game , health, jumpPressed, recoil, attacked, game
) )
end end
end end
@@ -283,7 +352,7 @@ struct
fun handleInput (game: game_type, input, recoil) = fun handleInput (game: game_type, input, recoil) =
let let
val {x, y, yAxis, health, jumpPressed, ...} = #player game val {x, y, yAxis, health, jumpPressed, attacked, ...} = #player game
val {leftHeld, rightHeld, upHeld, downHeld} = input val {leftHeld, rightHeld, upHeld, downHeld} = input
val xAxis = getXAxis (leftHeld, rightHeld) val xAxis = getXAxis (leftHeld, rightHeld)
@@ -294,25 +363,39 @@ struct
val yAxis = defaultYAxis yAxis val yAxis = defaultYAxis yAxis
val jumpPressed = false val jumpPressed = false
in in
helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, game) helpMove
( x, y, xAxis, yAxis, health
, jumpPressed, recoil, attacked, game
)
end end
| (true, true) => | (true, true) =>
let val yAxis = defaultYAxis yAxis let
in helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, game) val yAxis = defaultYAxis yAxis
in
helpMove
( x, y, xAxis, yAxis, health
, jumpPressed, recoil, attacked, game
)
end end
| (true, false) => | (true, false) =>
let let
val yAxis = onJumpPressed (yAxis, jumpPressed) val yAxis = onJumpPressed (yAxis, jumpPressed)
val jumpPressed = true val jumpPressed = true
in in
helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, game) helpMove
( x, y, xAxis, yAxis, health
, jumpPressed, recoil, attacked, game
)
end end
| (false, true) => | (false, true) =>
let let
val jumpPressed = false val jumpPressed = false
val yAxis = DROP_BELOW_PLATFORM val yAxis = DROP_BELOW_PLATFORM
in in
helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, game) helpMove
(x, y, xAxis, yAxis, health
, jumpPressed, recoil, attacked, game
)
end end
end end
@@ -332,7 +415,7 @@ struct
handleInput (game, input, NO_RECOIL) handleInput (game, input, NO_RECOIL)
else else
let let
val {x, y, health, ...} = player val {x, y, health, attacked, ...} = player
(* difference between RECOIL_LEFT and RECOIL_RIGHT (* difference between RECOIL_LEFT and RECOIL_RIGHT
* is the direction player moves back in *) * is the direction player moves back in *)
val x = x - 5 val x = x - 5
@@ -343,14 +426,17 @@ struct
val recoiled = recoiled + 1 val recoiled = recoiled + 1
val recoil = RECOIL_LEFT recoiled val recoil = RECOIL_LEFT recoiled
in in
helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, game) helpMove
( x, y, xAxis, yAxis, health
, jumpPressed, recoil, attacked, game
)
end end
| RECOIL_RIGHT recoiled => | RECOIL_RIGHT recoiled =>
if recoiled = recoilLimit then if recoiled = recoilLimit then
handleInput (game, input, NO_RECOIL) handleInput (game, input, NO_RECOIL)
else else
let let
val {x, y, health, ...} = player val {x, y, health, attacked, ...} = player
val x = x + 5 val x = x + 5
val xAxis = STAY_STILL val xAxis = STAY_STILL
@@ -359,7 +445,10 @@ struct
val recoiled = recoiled + 1 val recoiled = recoiled + 1
val recoil = RECOIL_RIGHT recoiled val recoil = RECOIL_RIGHT recoiled
in in
helpMove (x, y, xAxis, yAxis, health, jumpPressed, recoil, game) helpMove
( x, y, xAxis, yAxis, health
, jumpPressed, recoil, attacked, game
)
end end
end end