2024-12-09 04:37:40 +00:00
|
|
|
structure Player =
|
|
|
|
|
struct
|
2024-12-15 09:10:19 +00:00
|
|
|
open GameType
|
2024-12-09 04:37:40 +00:00
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
fun mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
2024-12-20 17:41:21 +00:00
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-20 17:41:21 +00:00
|
|
|
) =
|
2024-12-14 21:05:51 +00:00
|
|
|
{ yAxis = yAxis
|
|
|
|
|
, xAxis = xAxis
|
2024-12-19 04:09:03 +00:00
|
|
|
, recoil = recoil
|
2024-12-20 07:38:41 +00:00
|
|
|
, attacked = attacked
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttack = mainAttack
|
|
|
|
|
, mainAttackPressed = mainAttackPressed
|
2024-12-20 17:41:21 +00:00
|
|
|
, facing = facing
|
2024-12-14 21:05:51 +00:00
|
|
|
, health = health
|
|
|
|
|
, x = x
|
|
|
|
|
, y = y
|
|
|
|
|
, jumpPressed = jumpPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies = enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge = charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles = projectiles
|
2024-12-14 21:05:51 +00:00
|
|
|
}
|
2024-12-09 04:37:40 +00:00
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
fun withPatch (player: player, patch) =
|
|
|
|
|
let
|
|
|
|
|
val
|
|
|
|
|
{ yAxis
|
|
|
|
|
, xAxis
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-22 05:40:33 +00:00
|
|
|
, facing
|
|
|
|
|
, health
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
} = player
|
|
|
|
|
in
|
|
|
|
|
case patch of
|
|
|
|
|
W_X_AXIS xAxis =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_Y_AXIS yAxis =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_RECOIL recoil =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_ATTACKED attacked =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_MAIN_ATTACK mainAttack =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_FACING facing =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_HEALTH health =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_X x =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_Y y =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
|
|
|
|
| W_JUMP_PRESSED jumpPressed =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
2024-12-22 20:21:16 +00:00
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-22 05:40:33 +00:00
|
|
|
)
|
2024-12-31 10:04:40 +00:00
|
|
|
| W_ENEMIES enemies =>
|
2024-12-23 00:28:53 +00:00
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
|
|
|
|
, mainAttackPressed
|
2024-12-26 12:26:13 +00:00
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-26 12:26:13 +00:00
|
|
|
)
|
2024-12-31 10:04:40 +00:00
|
|
|
| W_CHARGE charge =>
|
2024-12-26 12:26:13 +00:00
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
|
|
|
|
, mainAttackPressed
|
|
|
|
|
, enemies
|
2024-12-28 08:41:10 +00:00
|
|
|
, charge
|
2025-01-07 12:57:15 +00:00
|
|
|
, projectiles
|
2024-12-23 00:28:53 +00:00
|
|
|
)
|
2025-01-08 12:49:29 +00:00
|
|
|
| W_PROJECTILES projectiles =>
|
|
|
|
|
mkPlayer
|
|
|
|
|
( health
|
|
|
|
|
, xAxis
|
|
|
|
|
, yAxis
|
|
|
|
|
, x
|
|
|
|
|
, y
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, recoil
|
|
|
|
|
, attacked
|
|
|
|
|
, mainAttack
|
|
|
|
|
, facing
|
|
|
|
|
, mainAttackPressed
|
|
|
|
|
, enemies
|
|
|
|
|
, charge
|
|
|
|
|
, projectiles
|
|
|
|
|
)
|
2024-12-22 05:40:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun withPatches (player: player, lst) =
|
|
|
|
|
case lst of
|
|
|
|
|
hd :: tl =>
|
|
|
|
|
let val player = withPatch (player, hd)
|
|
|
|
|
in withPatches (player, tl)
|
|
|
|
|
end
|
|
|
|
|
| [] => player
|
|
|
|
|
|
|
|
|
|
(* width/height *)
|
|
|
|
|
val size = 35
|
|
|
|
|
val realSize = 35.0
|
|
|
|
|
|
2024-12-28 04:06:27 +00:00
|
|
|
val halfSize = 35 div 2
|
|
|
|
|
val halfRealSize = 35.0 / 2.0
|
|
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
val moveBy = 5
|
|
|
|
|
|
2025-01-01 14:17:42 +00:00
|
|
|
(* defeated enemy constants *)
|
|
|
|
|
val defeatedPi = Real32.Math.pi / 180.0
|
2025-01-07 13:03:17 +00:00
|
|
|
val defeatedSize = 9.0
|
2025-01-06 11:26:20 +00:00
|
|
|
val defeatedDistance = 13.0
|
2025-01-01 14:17:42 +00:00
|
|
|
|
2024-12-23 03:59:27 +00:00
|
|
|
(* timing variables; always start at 0,
|
|
|
|
|
* and revert to default state when limit is hit *)
|
2024-12-22 05:40:33 +00:00
|
|
|
val jumpLimit = 150
|
|
|
|
|
val floatLimit = 3
|
|
|
|
|
val recoilLimit = 15
|
2024-12-22 20:21:16 +00:00
|
|
|
val attackedLimit = 55
|
2024-12-28 08:41:10 +00:00
|
|
|
val maxCharge = 60
|
2024-12-22 05:40:33 +00:00
|
|
|
|
|
|
|
|
(* helper functions checking input *)
|
|
|
|
|
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 getFacing (facing, xAxis) =
|
|
|
|
|
case xAxis of
|
|
|
|
|
STAY_STILL => facing
|
|
|
|
|
| MOVE_LEFT => FACING_LEFT
|
|
|
|
|
| MOVE_RIGHT => FACING_RIGHT
|
|
|
|
|
|
|
|
|
|
(* function returns default yAxis when neither up/down are pressed
|
|
|
|
|
* or both are pressed.
|
|
|
|
|
*
|
|
|
|
|
* In the case where the user was previously jumping,
|
|
|
|
|
* we enter the floating stage, because it's normal for games
|
|
|
|
|
* to have a very brief floating/gliding period before applying gravity.
|
|
|
|
|
*
|
|
|
|
|
* In the case where the user was previously floating, we want the player to
|
|
|
|
|
* keep floating at this point (another function will apply gravity if we
|
|
|
|
|
* floated enough).
|
|
|
|
|
*
|
|
|
|
|
* In every other case, we return the FALLING variant,
|
|
|
|
|
* which has the same effect as returning the ON_GROUND variant,
|
|
|
|
|
* except that it means gravity is applied if we walk off a platform.
|
|
|
|
|
* *)
|
|
|
|
|
fun defaultYAxis prevAxis =
|
|
|
|
|
case prevAxis of
|
|
|
|
|
JUMPING _ => FLOATING 0
|
|
|
|
|
| FLOATING _ => prevAxis
|
2024-12-23 03:59:27 +00:00
|
|
|
| DROP_BELOW_PLATFORM => prevAxis
|
2024-12-22 05:40:33 +00:00
|
|
|
| _ => FALLING
|
|
|
|
|
|
|
|
|
|
(* We want to prevent a double jump
|
|
|
|
|
* or jumping while the player is falling
|
|
|
|
|
* so we only switch to the JUMPING case if the player
|
|
|
|
|
* is on the ground. *)
|
|
|
|
|
fun onJumpPressed (prevAxis, jumpPressed) =
|
|
|
|
|
case prevAxis of
|
|
|
|
|
ON_GROUND =>
|
|
|
|
|
if jumpPressed then (* apply gravity *) FALLING else JUMPING 0
|
|
|
|
|
| _ => prevAxis
|
|
|
|
|
|
|
|
|
|
fun checkWalls (player, walls, lst, acc) =
|
2024-12-09 04:37:40 +00:00
|
|
|
let
|
2024-12-13 22:48:34 +00:00
|
|
|
open QuadTree
|
|
|
|
|
in
|
|
|
|
|
case lst of
|
|
|
|
|
(QUERY_ON_LEFT_SIDE, wallID) :: tl =>
|
|
|
|
|
let
|
2024-12-15 09:10:19 +00:00
|
|
|
val {x = wallX, width = wallWidth, ...} =
|
|
|
|
|
Vector.sub (walls, wallID - 1)
|
|
|
|
|
|
2024-12-13 22:48:34 +00:00
|
|
|
val newX = wallX + wallWidth
|
2024-12-22 05:40:33 +00:00
|
|
|
val acc = W_X newX :: acc
|
2024-12-13 22:48:34 +00:00
|
|
|
in
|
2024-12-22 05:40:33 +00:00
|
|
|
checkWalls (player, walls, tl, acc)
|
2024-12-13 22:48:34 +00:00
|
|
|
end
|
|
|
|
|
| (QUERY_ON_RIGHT_SIDE, wallID) :: tl =>
|
|
|
|
|
let
|
2024-12-15 09:10:19 +00:00
|
|
|
val {x = wallX, width = wallWidth, ...} =
|
|
|
|
|
Vector.sub (walls, wallID - 1)
|
|
|
|
|
|
2024-12-13 22:48:34 +00:00
|
|
|
val newX = wallX - size
|
2024-12-22 05:40:33 +00:00
|
|
|
val acc = W_X newX :: acc
|
2024-12-13 22:48:34 +00:00
|
|
|
in
|
2024-12-22 05:40:33 +00:00
|
|
|
checkWalls (player, walls, tl, acc)
|
2024-12-13 22:48:34 +00:00
|
|
|
end
|
|
|
|
|
| (QUERY_ON_BOTTOM_SIDE, wallID) :: tl =>
|
|
|
|
|
let
|
2024-12-15 09:10:19 +00:00
|
|
|
val {y = wallY, ...} = Vector.sub (walls, wallID - 1)
|
|
|
|
|
|
2024-12-13 22:48:34 +00:00
|
|
|
val newY = wallY - size
|
2024-12-22 05:40:33 +00:00
|
|
|
val acc = W_Y_AXIS ON_GROUND :: W_Y newY :: acc
|
2024-12-13 22:48:34 +00:00
|
|
|
in
|
2024-12-22 05:40:33 +00:00
|
|
|
checkWalls (player, walls, tl, acc)
|
2024-12-13 22:48:34 +00:00
|
|
|
end
|
2024-12-22 05:40:33 +00:00
|
|
|
| (QUERY_ON_TOP_SIDE, wallID) :: tl => checkWalls (player, walls, tl, acc)
|
|
|
|
|
| [] => acc
|
2024-12-17 22:45:58 +00:00
|
|
|
end
|
|
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
fun checkPlatforms (player, platforms, lst, acc) =
|
2024-12-17 22:45:58 +00:00
|
|
|
let
|
|
|
|
|
open QuadTree
|
|
|
|
|
in
|
2024-12-22 05:40:33 +00:00
|
|
|
case lst of
|
2024-12-17 22:45:58 +00:00
|
|
|
platID :: tl =>
|
2024-12-22 05:40:33 +00:00
|
|
|
(case #yAxis player of
|
|
|
|
|
DROP_BELOW_PLATFORM =>
|
|
|
|
|
(* pass through, allowing player to drop below the platform *)
|
|
|
|
|
checkPlatforms (player, platforms, tl, acc)
|
|
|
|
|
| JUMPING _ =>
|
|
|
|
|
(* pass through, allowing player to jump above the platform *)
|
|
|
|
|
checkPlatforms (player, platforms, tl, acc)
|
|
|
|
|
| _ =>
|
|
|
|
|
let
|
|
|
|
|
(* default case:
|
|
|
|
|
* player will land on platform and stay on the ground there. *)
|
|
|
|
|
val {y = platY, ...} = Vector.sub (platforms, platID - 1)
|
2024-12-18 03:30:21 +00:00
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
val newY = platY - size
|
|
|
|
|
val acc = W_Y_AXIS ON_GROUND :: W_Y newY :: acc
|
|
|
|
|
in
|
|
|
|
|
checkPlatforms (player, platforms, tl, acc)
|
|
|
|
|
end)
|
|
|
|
|
| [] => acc
|
2024-12-17 22:45:58 +00:00
|
|
|
end
|
|
|
|
|
|
2024-12-23 18:49:50 +00:00
|
|
|
(* only checks for collisions with environment (walls and platforms) *)
|
|
|
|
|
fun getEnvironmentPatches (player, game) =
|
2024-12-17 22:45:58 +00:00
|
|
|
let
|
2024-12-22 05:40:33 +00:00
|
|
|
val {walls, wallTree, platformTree, platforms, enemyTree, enemies, ...} =
|
|
|
|
|
game
|
2024-12-19 07:53:31 +00:00
|
|
|
|
2024-12-23 03:59:27 +00:00
|
|
|
val {x, y, attacked, mainAttack, ...} = player
|
2024-12-19 07:53:31 +00:00
|
|
|
|
2024-12-17 22:45:58 +00:00
|
|
|
val platCollisions = QuadTree.getCollisionsBelow
|
2024-12-18 03:30:21 +00:00
|
|
|
(x, y, size, size, 0, 0, 1920, 1080, 0, platformTree)
|
2024-12-22 05:40:33 +00:00
|
|
|
val acc = checkPlatforms (player, platforms, platCollisions, [])
|
2024-12-17 22:45:58 +00:00
|
|
|
|
|
|
|
|
val wallCollisions = QuadTree.getCollisionSides
|
2024-12-18 03:30:21 +00:00
|
|
|
(x, y, size, size, 0, 0, 1920, 1080, 0, wallTree)
|
2024-12-17 22:45:58 +00:00
|
|
|
in
|
2024-12-23 18:49:50 +00:00
|
|
|
checkWalls (player, walls, wallCollisions, acc)
|
2024-12-13 22:48:34 +00:00
|
|
|
end
|
2024-12-09 04:37:40 +00:00
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
fun getMovePatches player =
|
2024-12-13 22:48:34 +00:00
|
|
|
let
|
2024-12-22 05:40:33 +00:00
|
|
|
val {xAxis, yAxis, x, y, ...} = player
|
|
|
|
|
|
2024-12-13 22:48:34 +00:00
|
|
|
val desiredX =
|
2024-12-09 04:37:40 +00:00
|
|
|
case xAxis of
|
2024-12-13 22:48:34 +00:00
|
|
|
STAY_STILL => x
|
|
|
|
|
| MOVE_LEFT => x - moveBy
|
|
|
|
|
| MOVE_RIGHT => x + moveBy
|
2024-12-09 04:37:40 +00:00
|
|
|
in
|
|
|
|
|
case yAxis of
|
2024-12-22 05:40:33 +00:00
|
|
|
ON_GROUND => [W_X desiredX]
|
2024-12-14 18:02:57 +00:00
|
|
|
| FLOATING floated =>
|
|
|
|
|
let
|
|
|
|
|
val yAxis =
|
|
|
|
|
if floated = floatLimit then FALLING else FLOATING (floated + 1)
|
|
|
|
|
in
|
2024-12-22 05:40:33 +00:00
|
|
|
[W_X desiredX, W_Y_AXIS yAxis]
|
2024-12-14 18:02:57 +00:00
|
|
|
end
|
2024-12-13 22:48:34 +00:00
|
|
|
| FALLING =>
|
2024-12-22 05:40:33 +00:00
|
|
|
let val desiredY = y + moveBy
|
|
|
|
|
in [W_X desiredX, W_Y desiredY]
|
2024-12-17 22:45:58 +00:00
|
|
|
end
|
|
|
|
|
| DROP_BELOW_PLATFORM =>
|
2024-12-22 05:40:33 +00:00
|
|
|
let val desiredY = y + moveBy
|
|
|
|
|
in [W_X desiredX, W_Y desiredY]
|
2024-12-13 22:48:34 +00:00
|
|
|
end
|
|
|
|
|
| JUMPING jumped =>
|
|
|
|
|
if jumped + moveBy > jumpLimit then
|
|
|
|
|
(* if we are above the jump limit, trigger a fall *)
|
2024-12-22 05:40:33 +00:00
|
|
|
let val newYAxis = FLOATING 0
|
|
|
|
|
in [W_X desiredX, W_Y_AXIS newYAxis]
|
2024-12-09 04:37:40 +00:00
|
|
|
end
|
|
|
|
|
else
|
2024-12-13 22:48:34 +00:00
|
|
|
(* jump *)
|
|
|
|
|
let
|
|
|
|
|
val newJumped = jumped + moveBy
|
2024-12-17 22:45:58 +00:00
|
|
|
val newYAxis = JUMPING newJumped
|
2024-12-13 22:48:34 +00:00
|
|
|
val desiredY = y - moveBy
|
|
|
|
|
in
|
2024-12-22 05:40:33 +00:00
|
|
|
[W_X desiredX, W_Y desiredY, W_Y_AXIS newYAxis]
|
2024-12-13 22:48:34 +00:00
|
|
|
end
|
2024-12-09 04:37:40 +00:00
|
|
|
end
|
2024-12-14 07:59:43 +00:00
|
|
|
|
2024-12-22 20:21:16 +00:00
|
|
|
fun getJumpPatches (player, upHeld, downHeld, acc) =
|
2024-12-14 07:59:43 +00:00
|
|
|
let
|
2024-12-22 20:21:16 +00:00
|
|
|
val {yAxis, jumpPressed, ...} = player
|
2024-12-14 07:59:43 +00:00
|
|
|
in
|
2024-12-14 21:05:51 +00:00
|
|
|
case (upHeld, downHeld) of
|
|
|
|
|
(false, false) =>
|
|
|
|
|
let
|
|
|
|
|
val yAxis = defaultYAxis yAxis
|
|
|
|
|
val jumpPressed = false
|
|
|
|
|
in
|
2024-12-22 20:21:16 +00:00
|
|
|
W_JUMP_PRESSED jumpPressed :: W_Y_AXIS yAxis :: acc
|
2024-12-14 21:05:51 +00:00
|
|
|
end
|
|
|
|
|
| (true, true) =>
|
2024-12-22 05:40:33 +00:00
|
|
|
let val yAxis = defaultYAxis yAxis
|
2024-12-22 20:21:16 +00:00
|
|
|
in W_Y_AXIS yAxis :: acc
|
2024-12-14 21:05:51 +00:00
|
|
|
end
|
|
|
|
|
| (true, false) =>
|
|
|
|
|
let
|
|
|
|
|
val yAxis = onJumpPressed (yAxis, jumpPressed)
|
|
|
|
|
val jumpPressed = true
|
|
|
|
|
in
|
2024-12-22 20:21:16 +00:00
|
|
|
W_Y_AXIS yAxis :: W_JUMP_PRESSED jumpPressed :: acc
|
2024-12-14 21:05:51 +00:00
|
|
|
end
|
|
|
|
|
| (false, true) =>
|
2024-12-22 05:40:33 +00:00
|
|
|
let
|
2024-12-18 03:30:21 +00:00
|
|
|
val jumpPressed = false
|
|
|
|
|
val yAxis = DROP_BELOW_PLATFORM
|
2024-12-22 05:40:33 +00:00
|
|
|
in
|
2024-12-22 20:21:16 +00:00
|
|
|
W_Y_AXIS yAxis :: W_JUMP_PRESSED jumpPressed :: acc
|
2024-12-14 21:05:51 +00:00
|
|
|
end
|
2024-12-14 07:59:43 +00:00
|
|
|
end
|
2024-12-15 09:10:19 +00:00
|
|
|
|
2025-01-07 13:31:17 +00:00
|
|
|
fun prevWasNotAttacking prevAttack = prevAttack <> MAIN_ATTACKING
|
|
|
|
|
|
|
|
|
|
(* called only when player has no projectiles or was not previously attacking *)
|
|
|
|
|
fun helpGetMainAttackPatches (attackHeld, chargeHeld, charge) =
|
2025-01-08 12:49:29 +00:00
|
|
|
if attackHeld andalso charge > 0 then W_MAIN_ATTACK MAIN_ATTACKING
|
|
|
|
|
else if chargeHeld andalso not attackHeld then W_MAIN_ATTACK MAIN_CHARGING
|
|
|
|
|
else W_MAIN_ATTACK MAIN_NOT_ATTACKING
|
|
|
|
|
|
|
|
|
|
fun degreesToRadians degrees = Real32.fromInt degrees * defeatedPi
|
|
|
|
|
|
|
|
|
|
fun defeatedEnemiesToProjectiles
|
|
|
|
|
(pos, defeteadEnemies, player as {x, y, ...}, acc) =
|
|
|
|
|
if pos = Vector.length defeteadEnemies then
|
|
|
|
|
Vector.fromList acc
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val diff = halfRealSize - (defeatedSize / 2.0)
|
|
|
|
|
val x = Real32.fromInt x + diff
|
|
|
|
|
val y = Real32.fromInt y + diff
|
|
|
|
|
|
|
|
|
|
val {angle} = Vector.sub (defeteadEnemies, pos)
|
|
|
|
|
val angle = degreesToRadians angle
|
|
|
|
|
|
|
|
|
|
val pelletX = ((Real32.Math.cos angle) * defeatedDistance) + x
|
|
|
|
|
val pelletY = ((Real32.Math.sin angle) * defeatedDistance) + y
|
|
|
|
|
|
|
|
|
|
val x = Real32.toInt IEEEReal.TO_NEAREST x
|
|
|
|
|
val y = Real32.toInt IEEEReal.TO_NEAREST y
|
|
|
|
|
|
|
|
|
|
val acc = {x = x, y = y} :: acc
|
|
|
|
|
in
|
|
|
|
|
defeatedEnemiesToProjectiles (pos + 1, defeteadEnemies, player, acc)
|
|
|
|
|
end
|
2024-12-22 20:21:16 +00:00
|
|
|
|
2025-01-08 13:18:35 +00:00
|
|
|
fun getThrowPatches (defeteadEnemies, projectiles, player, acc) =
|
|
|
|
|
let
|
|
|
|
|
val newProjectiles =
|
|
|
|
|
defeatedEnemiesToProjectiles (0, defeteadEnemies, player, [])
|
|
|
|
|
|
|
|
|
|
(* concatenate new projectiles with previous projectiles *)
|
|
|
|
|
val allProjectiles = Vector.concat [newProjectiles, projectiles]
|
|
|
|
|
|
|
|
|
|
(* remove defeated enemies from player record *)
|
|
|
|
|
val enemies = Vector.fromList []
|
|
|
|
|
in
|
|
|
|
|
W_MAIN_ATTACK MAIN_THROWING :: W_PROJECTILES allProjectiles
|
|
|
|
|
:: W_ENEMIES enemies :: acc
|
|
|
|
|
end
|
|
|
|
|
|
2025-01-07 13:31:17 +00:00
|
|
|
fun getMainAttackPatches
|
2025-01-08 12:49:29 +00:00
|
|
|
( prevAttack
|
|
|
|
|
, defeteadEnemies
|
|
|
|
|
, projectiles
|
|
|
|
|
, attackHeld
|
|
|
|
|
, chargeHeld
|
|
|
|
|
, charge
|
|
|
|
|
, player
|
|
|
|
|
, acc
|
|
|
|
|
) =
|
2025-01-08 13:18:35 +00:00
|
|
|
case prevAttack of
|
|
|
|
|
MAIN_NOT_ATTACKING =>
|
|
|
|
|
if attackHeld andalso Vector.length defeteadEnemies > 0 then
|
|
|
|
|
(* shoot projectiles if player was not attacking previously,
|
|
|
|
|
* and there is more than one enemy *)
|
|
|
|
|
getThrowPatches (defeteadEnemies, projectiles, player, acc)
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val mainAttack =
|
|
|
|
|
helpGetMainAttackPatches (attackHeld, chargeHeld, charge)
|
|
|
|
|
in
|
|
|
|
|
mainAttack :: acc
|
|
|
|
|
end
|
|
|
|
|
| MAIN_CHARGING =>
|
|
|
|
|
if attackHeld andalso Vector.length defeteadEnemies > 0 then
|
|
|
|
|
getThrowPatches (defeteadEnemies, projectiles, player, acc)
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val mainAttack =
|
|
|
|
|
helpGetMainAttackPatches (attackHeld, chargeHeld, charge)
|
|
|
|
|
in
|
|
|
|
|
mainAttack :: acc
|
|
|
|
|
end
|
|
|
|
|
| MAIN_ATTACKING =>
|
2025-01-08 12:49:29 +00:00
|
|
|
let
|
|
|
|
|
val mainAttack =
|
|
|
|
|
helpGetMainAttackPatches (attackHeld, chargeHeld, charge)
|
|
|
|
|
in
|
|
|
|
|
mainAttack :: acc
|
|
|
|
|
end
|
2025-01-08 13:18:35 +00:00
|
|
|
| MAIN_THROWING =>
|
|
|
|
|
if attackHeld then
|
|
|
|
|
acc
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val mainAttack =
|
|
|
|
|
helpGetMainAttackPatches (attackHeld, chargeHeld, charge)
|
|
|
|
|
in
|
|
|
|
|
mainAttack :: acc
|
|
|
|
|
end
|
2025-01-07 13:31:17 +00:00
|
|
|
|
2024-12-22 20:21:16 +00:00
|
|
|
fun getInputPatches (player: player, input) =
|
2024-12-31 10:04:40 +00:00
|
|
|
let
|
|
|
|
|
val
|
|
|
|
|
{ x
|
|
|
|
|
, y
|
|
|
|
|
, yAxis
|
|
|
|
|
, jumpPressed
|
|
|
|
|
, facing
|
|
|
|
|
, mainAttack
|
|
|
|
|
, mainAttackPressed
|
|
|
|
|
, charge
|
2025-01-07 13:31:17 +00:00
|
|
|
, enemies
|
|
|
|
|
, projectiles
|
2024-12-31 10:04:40 +00:00
|
|
|
, ...
|
|
|
|
|
} = player
|
2024-12-23 00:28:53 +00:00
|
|
|
|
2024-12-31 10:04:40 +00:00
|
|
|
val {leftHeld, rightHeld, upHeld, downHeld, attackHeld, chargeHeld} =
|
|
|
|
|
input
|
|
|
|
|
|
|
|
|
|
val xAxis = getXAxis (leftHeld, rightHeld)
|
|
|
|
|
val facing = getFacing (facing, xAxis)
|
2025-01-07 13:31:17 +00:00
|
|
|
|
2024-12-31 10:04:40 +00:00
|
|
|
val charge =
|
|
|
|
|
case mainAttack of
|
|
|
|
|
MAIN_CHARGING => Int.min (charge + 1, maxCharge)
|
|
|
|
|
| MAIN_ATTACKING => Int.max (charge - 1, 0)
|
2025-01-08 13:18:35 +00:00
|
|
|
| _ => charge
|
2024-12-31 10:04:40 +00:00
|
|
|
|
2025-01-08 12:49:29 +00:00
|
|
|
val acc = [W_X_AXIS xAxis, W_FACING facing, W_CHARGE charge]
|
|
|
|
|
|
|
|
|
|
val acc = getMainAttackPatches
|
|
|
|
|
( mainAttack
|
|
|
|
|
, enemies
|
|
|
|
|
, projectiles
|
|
|
|
|
, attackHeld
|
|
|
|
|
, chargeHeld
|
|
|
|
|
, charge
|
|
|
|
|
, player
|
|
|
|
|
, acc
|
|
|
|
|
)
|
|
|
|
|
|
2024-12-31 10:04:40 +00:00
|
|
|
val acc = getJumpPatches (player, upHeld, downHeld, acc)
|
|
|
|
|
in
|
|
|
|
|
acc
|
|
|
|
|
end
|
2024-12-22 20:21:16 +00:00
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
fun getRecoilPatches player =
|
|
|
|
|
case #recoil player of
|
|
|
|
|
NO_RECOIL => []
|
|
|
|
|
| RECOIL_LEFT recoiled =>
|
|
|
|
|
(* if player is recoiling, don't accept or adjust any input.
|
|
|
|
|
* However, if player has reached the recoil limit, exit the recoil
|
|
|
|
|
* state and accept input.
|
|
|
|
|
* *)
|
|
|
|
|
if recoiled = recoilLimit then
|
|
|
|
|
[W_RECOIL NO_RECOIL]
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val {x, y, health, attacked, facing, xAxis, ...} = player
|
|
|
|
|
(* difference between RECOIL_LEFT and RECOIL_RIGHT
|
|
|
|
|
* is the direction player moves back in *)
|
|
|
|
|
val x = x - 5
|
|
|
|
|
|
|
|
|
|
val xAxis = STAY_STILL
|
|
|
|
|
val yAxis = FALLING
|
|
|
|
|
val jumpPressed = false
|
|
|
|
|
val recoiled = recoiled + 1
|
|
|
|
|
val recoil = RECOIL_LEFT recoiled
|
|
|
|
|
val facing = getFacing (facing, xAxis)
|
|
|
|
|
in
|
|
|
|
|
[ W_X x
|
|
|
|
|
, W_X_AXIS xAxis
|
|
|
|
|
, W_Y_AXIS yAxis
|
|
|
|
|
, W_JUMP_PRESSED jumpPressed
|
|
|
|
|
, W_RECOIL recoil
|
|
|
|
|
, W_FACING facing
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
| RECOIL_RIGHT recoiled =>
|
|
|
|
|
if recoiled = recoilLimit then
|
|
|
|
|
[W_RECOIL NO_RECOIL]
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val {x, y, health, attacked, facing, xAxis, ...} = player
|
|
|
|
|
val x = x + 5
|
|
|
|
|
|
|
|
|
|
val xAxis = STAY_STILL
|
|
|
|
|
val yAxis = FALLING
|
|
|
|
|
val jumpPressed = false
|
|
|
|
|
val recoiled = recoiled + 1
|
|
|
|
|
val recoil = RECOIL_RIGHT recoiled
|
|
|
|
|
val facing = getFacing (facing, xAxis)
|
|
|
|
|
in
|
|
|
|
|
[ W_X x
|
|
|
|
|
, W_X_AXIS xAxis
|
|
|
|
|
, W_Y_AXIS yAxis
|
|
|
|
|
, W_JUMP_PRESSED jumpPressed
|
|
|
|
|
, W_RECOIL recoil
|
|
|
|
|
, W_FACING facing
|
|
|
|
|
]
|
|
|
|
|
end
|
|
|
|
|
|
2024-12-24 12:05:44 +00:00
|
|
|
fun runPhysicsAndInput (game: game_type, input) =
|
2024-12-19 03:58:37 +00:00
|
|
|
let
|
|
|
|
|
val player = #player game
|
2024-12-22 05:40:33 +00:00
|
|
|
|
|
|
|
|
val patches = getRecoilPatches player
|
|
|
|
|
val player = withPatches (player, patches)
|
|
|
|
|
|
|
|
|
|
val player =
|
|
|
|
|
(* we only accept and handle input if player is not recoiling *)
|
|
|
|
|
case #recoil player of
|
|
|
|
|
NO_RECOIL =>
|
|
|
|
|
let val patches = getInputPatches (player, input)
|
|
|
|
|
in withPatches (player, patches)
|
2024-12-19 03:58:37 +00:00
|
|
|
end
|
2024-12-22 05:40:33 +00:00
|
|
|
| _ => player
|
|
|
|
|
|
2025-01-01 14:17:42 +00:00
|
|
|
val player =
|
|
|
|
|
let
|
|
|
|
|
val e = #enemies player
|
2025-01-07 13:31:17 +00:00
|
|
|
val e =
|
|
|
|
|
Vector.map
|
|
|
|
|
(fn {angle} => {angle = if angle < 360 then angle + 5 else 0}) e
|
2025-01-01 14:17:42 +00:00
|
|
|
val patches = [W_ENEMIES e]
|
|
|
|
|
in
|
|
|
|
|
withPatches (player, patches)
|
|
|
|
|
end
|
|
|
|
|
|
2024-12-22 05:40:33 +00:00
|
|
|
val patches = getMovePatches player
|
|
|
|
|
val player = withPatches (player, patches)
|
|
|
|
|
|
2024-12-23 18:49:50 +00:00
|
|
|
val patches = getEnvironmentPatches (player, game)
|
2024-12-22 05:40:33 +00:00
|
|
|
in
|
|
|
|
|
withPatches (player, patches)
|
2024-12-19 03:58:37 +00:00
|
|
|
end
|
|
|
|
|
|
2024-12-16 00:58:59 +00:00
|
|
|
(* block is placeholder asset *)
|
2024-12-22 21:08:59 +00:00
|
|
|
fun helpGetDrawVec (x, y, size, width, height, attacked, mainAttack) =
|
|
|
|
|
case mainAttack of
|
|
|
|
|
MAIN_NOT_ATTACKING =>
|
|
|
|
|
(case attacked of
|
|
|
|
|
NOT_ATTACKED =>
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 0.5, 0.5, 0.5)
|
|
|
|
|
| ATTACKED amt =>
|
|
|
|
|
if amt mod 5 = 0 then
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 0.9, 0.9, 0.9)
|
2025-01-08 13:18:35 +00:00
|
|
|
else
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 0.5, 0.5, 0.5))
|
|
|
|
|
| MAIN_THROWING =>
|
|
|
|
|
(case attacked of
|
|
|
|
|
NOT_ATTACKED =>
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 0.5, 0.5, 0.5)
|
|
|
|
|
| ATTACKED amt =>
|
|
|
|
|
if amt mod 5 = 0 then
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 0.9, 0.9, 0.9)
|
2024-12-22 21:08:59 +00:00
|
|
|
else
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 0.5, 0.5, 0.5))
|
2024-12-31 10:04:40 +00:00
|
|
|
| MAIN_ATTACKING =>
|
|
|
|
|
(case attacked of
|
|
|
|
|
NOT_ATTACKED =>
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 1.0, 0.5, 0.5)
|
|
|
|
|
| ATTACKED amt =>
|
|
|
|
|
if amt mod 5 = 0 then
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 1.0, 0.9, 0.9)
|
|
|
|
|
else
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 1.0, 0.5, 0.5))
|
|
|
|
|
| MAIN_CHARGING =>
|
2024-12-22 21:08:59 +00:00
|
|
|
(case attacked of
|
|
|
|
|
NOT_ATTACKED =>
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 1.0, 0.5, 0.5)
|
|
|
|
|
| ATTACKED amt =>
|
|
|
|
|
if amt mod 5 = 0 then
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 1.0, 0.9, 0.9)
|
|
|
|
|
else
|
|
|
|
|
Block.lerp (x, y, size, size, width, height, 1.0, 0.5, 0.5))
|
|
|
|
|
|
|
|
|
|
fun getDrawVec (player: player, width, height) =
|
2024-12-17 09:16:22 +00:00
|
|
|
let
|
2024-12-22 21:08:59 +00:00
|
|
|
val {x, y, attacked, mainAttack, ...} = player
|
2024-12-17 09:16:22 +00:00
|
|
|
val wratio = width / 1920.0
|
|
|
|
|
val hratio = height / 1080.0
|
|
|
|
|
in
|
|
|
|
|
if wratio < hratio then
|
|
|
|
|
let
|
|
|
|
|
val scale = 1080.0 * wratio
|
|
|
|
|
val yOffset =
|
|
|
|
|
if height > scale then (height - scale) / 2.0
|
|
|
|
|
else if height < scale then (scale - height) / 2.0
|
|
|
|
|
else 0.0
|
|
|
|
|
|
|
|
|
|
val x = Real32.fromInt x * wratio
|
|
|
|
|
val y = Real32.fromInt y * wratio + yOffset
|
|
|
|
|
|
|
|
|
|
val realSize = realSize * wratio
|
|
|
|
|
in
|
2024-12-22 21:08:59 +00:00
|
|
|
helpGetDrawVec (x, y, realSize, width, height, attacked, mainAttack)
|
2024-12-17 09:16:22 +00:00
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val scale = 1920.0 * hratio
|
|
|
|
|
val xOffset =
|
|
|
|
|
if width > scale then (width - scale) / 2.0
|
|
|
|
|
else if width < scale then (scale - width) / 2.0
|
|
|
|
|
else 0.0
|
|
|
|
|
|
|
|
|
|
val x = Real32.fromInt x * hratio + xOffset
|
|
|
|
|
val y = Real32.fromInt y * hratio
|
|
|
|
|
|
|
|
|
|
val realSize = realSize * hratio
|
|
|
|
|
in
|
2024-12-22 21:08:59 +00:00
|
|
|
helpGetDrawVec (x, y, realSize, width, height, attacked, mainAttack)
|
2024-12-17 09:16:22 +00:00
|
|
|
end
|
|
|
|
|
end
|
2024-12-28 04:06:27 +00:00
|
|
|
|
|
|
|
|
fun getFieldVec (player: player, width, height) =
|
|
|
|
|
case #mainAttack player of
|
|
|
|
|
MAIN_NOT_ATTACKING => Vector.fromList []
|
2024-12-31 10:04:40 +00:00
|
|
|
| _ =>
|
2024-12-28 04:06:27 +00:00
|
|
|
let
|
|
|
|
|
val {x, y, ...} = player
|
|
|
|
|
val wratio = width / 1920.0
|
|
|
|
|
val hratio = height / 1080.0
|
|
|
|
|
in
|
|
|
|
|
if wratio < hratio then
|
|
|
|
|
let
|
|
|
|
|
val scale = 1080.0 * wratio
|
|
|
|
|
val yOffset =
|
|
|
|
|
if height > scale then (height - scale) / 2.0
|
|
|
|
|
else if height < scale then (scale - height) / 2.0
|
|
|
|
|
else 0.0
|
|
|
|
|
|
|
|
|
|
val x = (Real32.fromInt x - halfRealSize) * wratio
|
|
|
|
|
val y = (Real32.fromInt y - halfRealSize) * wratio + yOffset
|
|
|
|
|
|
|
|
|
|
val realSize = (realSize * 2.0) * wratio
|
2024-12-31 10:08:18 +00:00
|
|
|
|
|
|
|
|
val {charge, ...} = player
|
|
|
|
|
val alpha = Real32.fromInt charge / 60.0
|
2024-12-28 04:06:27 +00:00
|
|
|
in
|
|
|
|
|
Field.lerp
|
|
|
|
|
(x, y, realSize, realSize, width, height, 0.7, 0.7, 1.0, alpha)
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val scale = 1920.0 * hratio
|
|
|
|
|
val xOffset =
|
|
|
|
|
if width > scale then (width - scale) / 2.0
|
|
|
|
|
else if width < scale then (scale - width) / 2.0
|
|
|
|
|
else 0.0
|
|
|
|
|
|
|
|
|
|
val x = (Real32.fromInt x - halfRealSize) * hratio + xOffset
|
|
|
|
|
val y = (Real32.fromInt y - halfRealSize) * hratio
|
|
|
|
|
|
|
|
|
|
val realSize = (realSize * 2.0) * hratio
|
2024-12-31 10:08:18 +00:00
|
|
|
|
|
|
|
|
val {charge, ...} = player
|
|
|
|
|
val alpha = Real32.fromInt charge / 60.0
|
2024-12-28 04:06:27 +00:00
|
|
|
in
|
|
|
|
|
Field.lerp
|
|
|
|
|
(x, y, realSize, realSize, width, height, 0.7, 0.7, 1.0, alpha)
|
|
|
|
|
end
|
|
|
|
|
end
|
2025-01-01 14:17:42 +00:00
|
|
|
|
|
|
|
|
fun helpGetPelletVec
|
|
|
|
|
( playerX
|
|
|
|
|
, playerY
|
|
|
|
|
, pos
|
|
|
|
|
, enemies
|
|
|
|
|
, width
|
|
|
|
|
, height
|
|
|
|
|
, ratio
|
|
|
|
|
, xOffset
|
|
|
|
|
, yOffset
|
|
|
|
|
, acc
|
|
|
|
|
) =
|
|
|
|
|
if pos = Vector.length enemies then
|
|
|
|
|
Vector.concat acc
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val {angle} = Vector.sub (enemies, pos)
|
|
|
|
|
(* convert degrees to radians *)
|
|
|
|
|
val angle = degreesToRadians angle
|
|
|
|
|
|
|
|
|
|
(* calculate pellet's x and y *)
|
|
|
|
|
val pelletX = ((Real32.Math.cos angle) * defeatedDistance) + playerX
|
|
|
|
|
val pelletX = pelletX * ratio + xOffset
|
|
|
|
|
|
|
|
|
|
val pelletY = ((Real32.Math.sin angle) * defeatedDistance) + playerY
|
|
|
|
|
val pelletY = pelletY * ratio + yOffset
|
|
|
|
|
|
2025-01-07 13:03:17 +00:00
|
|
|
val defeatedSize = defeatedSize * ratio
|
|
|
|
|
|
2025-01-01 14:17:42 +00:00
|
|
|
val vec = Field.lerp
|
|
|
|
|
( pelletX
|
|
|
|
|
, pelletY
|
|
|
|
|
, defeatedSize
|
|
|
|
|
, defeatedSize
|
|
|
|
|
, width
|
|
|
|
|
, height
|
|
|
|
|
, 0.3
|
|
|
|
|
, 0.9
|
|
|
|
|
, 0.3
|
|
|
|
|
, 1.0
|
|
|
|
|
)
|
|
|
|
|
val acc = vec :: acc
|
|
|
|
|
in
|
|
|
|
|
helpGetPelletVec
|
|
|
|
|
( playerX
|
|
|
|
|
, playerY
|
|
|
|
|
, pos + 1
|
|
|
|
|
, enemies
|
|
|
|
|
, width
|
|
|
|
|
, height
|
|
|
|
|
, ratio
|
|
|
|
|
, xOffset
|
|
|
|
|
, yOffset
|
|
|
|
|
, acc
|
|
|
|
|
)
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
fun getPelletVec (player: player, width, height) =
|
|
|
|
|
if Vector.length (#enemies player) = 0 then
|
|
|
|
|
Vector.fromList []
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val {x, y, enemies, ...} = player
|
|
|
|
|
|
|
|
|
|
(* get centre (x, y) coordinates of player *)
|
|
|
|
|
val diff = halfRealSize - (defeatedSize / 2.0)
|
|
|
|
|
val x = Real32.fromInt x + diff
|
|
|
|
|
val y = Real32.fromInt y + diff
|
|
|
|
|
|
|
|
|
|
val wratio = width / 1920.0
|
|
|
|
|
val hratio = height / 1080.0
|
|
|
|
|
in
|
|
|
|
|
if wratio < hratio then
|
|
|
|
|
let
|
|
|
|
|
val scale = 1080.0 * wratio
|
|
|
|
|
val yOffset =
|
|
|
|
|
if height > scale then (height - scale) / 2.0
|
|
|
|
|
else if height < scale then (scale - height) / 2.0
|
|
|
|
|
else 0.0
|
2025-01-07 13:31:17 +00:00
|
|
|
in
|
2025-01-01 14:17:42 +00:00
|
|
|
helpGetPelletVec
|
|
|
|
|
(x, y, 0, enemies, width, height, wratio, 0.0, yOffset, [])
|
|
|
|
|
end
|
|
|
|
|
else
|
|
|
|
|
let
|
|
|
|
|
val scale = 1920.0 * hratio
|
|
|
|
|
val xOffset =
|
|
|
|
|
if width > scale then (width - scale) / 2.0
|
|
|
|
|
else if width < scale then (scale - width) / 2.0
|
|
|
|
|
else 0.0
|
|
|
|
|
in
|
|
|
|
|
helpGetPelletVec
|
|
|
|
|
(x, y, 0, enemies, width, height, hratio, xOffset, 0.0, [])
|
|
|
|
|
end
|
|
|
|
|
end
|
2024-12-09 04:37:40 +00:00
|
|
|
end
|