248 lines
8.8 KiB
Standard ML
248 lines
8.8 KiB
Standard ML
structure PlayerVec =
|
|
struct
|
|
open EntityType
|
|
open PlayerType
|
|
|
|
val walkRightFrames =
|
|
#[ PlayerWalkRight1.lerp
|
|
, PlayerWalkRight2.lerp
|
|
, PlayerWalkRight3.lerp
|
|
, PlayerWalkRight4.lerp
|
|
, PlayerWalkRight5.lerp
|
|
, PlayerWalkRight6.lerp
|
|
, PlayerWalkRight7.lerp
|
|
, PlayerWalkRight8.lerp
|
|
]
|
|
|
|
val walkLeftFrames =
|
|
#[ PlayerWalkLeft1.lerp
|
|
, PlayerWalkLeft2.lerp
|
|
, PlayerWalkLeft3.lerp
|
|
, PlayerWalkLeft4.lerp
|
|
, PlayerWalkLeft5.lerp
|
|
, PlayerWalkLeft6.lerp
|
|
, PlayerWalkLeft7.lerp
|
|
, PlayerWalkLeft8.lerp
|
|
]
|
|
|
|
val attackLeftProjectiles =
|
|
#[ PlayerAttackLeftProjectile1.lerp
|
|
, PlayerAttackLeftProjectile2.lerp
|
|
, PlayerAttackLeftProjectile3.lerp
|
|
, PlayerAttackLeftProjectile4.lerp
|
|
, PlayerAttackLeftProjectile5.lerp
|
|
, PlayerAttackLeftProjectile6.lerp
|
|
, PlayerAttackLeftProjectile7.lerp
|
|
, PlayerAttackLeftProjectile8.lerp
|
|
, PlayerAttackLeftProjectile9.lerp
|
|
, PlayerAttackLeftProjectile10.lerp
|
|
, PlayerAttackLeftProjectile11.lerp
|
|
, PlayerAttackLeftProjectile12.lerp
|
|
, PlayerAttackLeftProjectile13.lerp
|
|
, PlayerAttackLeftProjectile14.lerp
|
|
, PlayerAttackLeftProjectile15.lerp
|
|
, PlayerAttackLeftProjectile16.lerp
|
|
, PlayerAttackLeftProjectile17.lerp
|
|
, PlayerAttackLeftProjectile18.lerp
|
|
, PlayerAttackLeftProjectile19.lerp
|
|
, PlayerAttackLeftProjectile20.lerp
|
|
, PlayerAttackLeftProjectile21.lerp
|
|
, PlayerAttackLeftProjectile22.lerp
|
|
, PlayerAttackLeftProjectile23.lerp
|
|
, PlayerAttackLeftProjectile24.lerp
|
|
, PlayerAttackLeftProjectile25.lerp
|
|
]
|
|
|
|
val attackRightProjectiles =
|
|
#[ PlayerAttackRightProjectile1.lerp
|
|
, PlayerAttackRightProjectile2.lerp
|
|
, PlayerAttackRightProjectile3.lerp
|
|
, PlayerAttackRightProjectile4.lerp
|
|
, PlayerAttackRightProjectile5.lerp
|
|
, PlayerAttackRightProjectile6.lerp
|
|
, PlayerAttackRightProjectile7.lerp
|
|
, PlayerAttackRightProjectile8.lerp
|
|
, PlayerAttackRightProjectile9.lerp
|
|
, PlayerAttackRightProjectile10.lerp
|
|
, PlayerAttackRightProjectile11.lerp
|
|
, PlayerAttackRightProjectile12.lerp
|
|
, PlayerAttackRightProjectile13.lerp
|
|
, PlayerAttackRightProjectile14.lerp
|
|
, PlayerAttackRightProjectile15.lerp
|
|
, PlayerAttackRightProjectile16.lerp
|
|
, PlayerAttackRightProjectile17.lerp
|
|
, PlayerAttackRightProjectile18.lerp
|
|
, PlayerAttackRightProjectile19.lerp
|
|
, PlayerAttackRightProjectile20.lerp
|
|
, PlayerAttackRightProjectile21.lerp
|
|
, PlayerAttackRightProjectile22.lerp
|
|
, PlayerAttackRightProjectile23.lerp
|
|
, PlayerAttackRightProjectile24.lerp
|
|
, PlayerAttackRightProjectile25.lerp
|
|
]
|
|
|
|
fun getIdle (player, rx, ry, ww, wh) =
|
|
case #facing player of
|
|
FACING_RIGHT => PlayerStandingRight.lerp (rx, ry, 3.0, ww, wh)
|
|
| FACING_LEFT => PlayerStandingLeft.lerp (rx, ry, 3.0, ww, wh)
|
|
|
|
fun getWalk (rx, ry, ww, wh, walkFrames, animTimer) =
|
|
let
|
|
val frame = (animTimer div 4) mod Vector.length walkFrames
|
|
val func = Vector.sub (walkFrames, Int.max (frame, 0))
|
|
in
|
|
func (rx, ry, 3.0, ww, wh)
|
|
end
|
|
|
|
fun getWhenOnGround (player, rx, ry, ww, wh) =
|
|
case #xAxis player of
|
|
MOVE_RIGHT => getWalk (rx, ry, ww, wh, walkRightFrames, #animTimer player)
|
|
| MOVE_LEFT => getWalk (rx, ry, ww, wh, walkLeftFrames, #animTimer player)
|
|
| STAY_STILL => getIdle (player, rx, ry, ww, wh)
|
|
|
|
fun getWhenJumpingRight (player, amt, rx, ry, ww, wh) =
|
|
if amt < 3 then PlayerJumpRight1.lerp (rx, ry, 3.0, ww, wh)
|
|
else if amt < 6 then PlayerJumpRight2.lerp (rx, ry, 3.0, ww, wh)
|
|
else if amt < 9 then PlayerJumpRight3.lerp (rx, ry, 3.0, ww, wh)
|
|
else if amt < 12 then PlayerJumpRight4.lerp (rx, ry, 3.0, ww, wh)
|
|
else PlayerJumpRight5.lerp (rx, ry, 3.0, ww, wh)
|
|
|
|
fun getWhenJumpingLeft (player, amt, rx, ry, ww, wh) =
|
|
if amt < 3 then PlayerJumpLeft1.lerp (rx, ry, 3.0, ww, wh)
|
|
else if amt < 6 then PlayerJumpLeft2.lerp (rx, ry, 3.0, ww, wh)
|
|
else if amt < 9 then PlayerJumpLeft3.lerp (rx, ry, 3.0, ww, wh)
|
|
else if amt < 12 then PlayerJumpLeft4.lerp (rx, ry, 3.0, ww, wh)
|
|
else PlayerJumpLeft5.lerp (rx, ry, 3.0, ww, wh)
|
|
|
|
fun getWhenJumping (player, amt, rx, ry, ww, wh) =
|
|
case #facing player of
|
|
FACING_RIGHT => getWhenJumpingRight (player, amt, rx, ry, ww, wh)
|
|
| FACING_LEFT => getWhenJumpingLeft (player, amt, rx, ry, ww, wh)
|
|
|
|
fun getWhenFloating (player, rx, ry, ww, wh) =
|
|
case #facing player of
|
|
FACING_RIGHT => PlayerJumpRight5.lerp (rx, ry, 3.0, ww, wh)
|
|
| FACING_LEFT => PlayerJumpLeft5.lerp (rx, ry, 3.0, ww, wh)
|
|
|
|
fun getWhenFalling (player, rx, ry, ww, wh) =
|
|
case #facing player of
|
|
FACING_RIGHT => PlayerFallRight.lerp (rx, ry, 3.0, ww, wh)
|
|
| FACING_LEFT => PlayerFallLeft.lerp (rx, ry, 3.0, ww, wh)
|
|
|
|
fun getWhenDropping (player, rx, ry, ww, wh) =
|
|
let
|
|
val animTimer = #animTimer player
|
|
in
|
|
getWhenJumping (player, animTimer, rx, ry, ww, wh)
|
|
end
|
|
|
|
fun getWhenNotAttacked (player, rx, ry, ww, wh) =
|
|
case #yAxis player of
|
|
ON_GROUND => getWhenOnGround (player, rx, ry, ww, wh)
|
|
| JUMPING amt => getWhenJumping (player, amt, rx, ry, ww, wh)
|
|
| FLOATING _ => getWhenFloating (player, rx, ry, ww, wh)
|
|
| FALLING => getWhenFalling (player, rx, ry, ww, wh)
|
|
| DROP_BELOW_PLATFORM => getWhenDropping (player, rx, ry, ww, wh)
|
|
|
|
fun getWhenAttacked (player, amt, rx, ry, ww, wh) =
|
|
case #facing player of
|
|
FACING_RIGHT =>
|
|
(* todo: hurt sprite/animation if amt mod 5 = 0 then *)
|
|
PlayerStandingRight.lerp (rx, ry, 3.0, ww, wh)
|
|
| FACING_LEFT =>
|
|
(* todo: hurt sprite/animation if amt mod 5 = 0 then *)
|
|
PlayerStandingLeft.lerp (rx, ry, 3.0, ww, wh)
|
|
|
|
fun helpGet
|
|
( player: player
|
|
, x
|
|
, y
|
|
, xOffset
|
|
, yOffset
|
|
, ratio
|
|
, rx
|
|
, ry
|
|
, windowWidth
|
|
, windowHeight
|
|
) =
|
|
case #mainAttack player of
|
|
MAIN_ATTACKING {animTimer = amt, ...} =>
|
|
(case #facing player of
|
|
FACING_RIGHT =>
|
|
let
|
|
val playerVec = PlayerAttackStandRight.lerp
|
|
(rx, ry, 3.0, windowWidth, windowHeight)
|
|
|
|
(* adding playerWidth to x so that projectile starts from
|
|
* the rightmost pixel of the player *)
|
|
val projX = x + Constants.playerWidth
|
|
val projY = y + Constants.projectileOffsetY
|
|
val projX = (Real32.fromInt projX + xOffset) * ratio
|
|
val projY = (Real32.fromInt projY + yOffset) * ratio
|
|
|
|
val func = Vector.sub (attackRightProjectiles, amt)
|
|
val projectilesVec = func
|
|
(projX, projY, 3.0, windowWidth, windowHeight)
|
|
in
|
|
Vector.concat [playerVec, projectilesVec]
|
|
end
|
|
| FACING_LEFT =>
|
|
let
|
|
val playerVec = PlayerAttackStandLeft.lerp
|
|
(rx, ry, 3.0, windowWidth, windowHeight)
|
|
|
|
(* subtracting projectileWidth from x it looks like
|
|
* the projectile starts from player's leftmost side this way. *)
|
|
val projX = x - Constants.projectileWidth
|
|
val projY = y + Constants.projectileOffsetY
|
|
val projX = (Real32.fromInt projX + xOffset) * ratio
|
|
val projY = (Real32.fromInt projY + yOffset) * ratio
|
|
|
|
val func = Vector.sub (attackLeftProjectiles, amt)
|
|
val projectilesVec = func
|
|
(projX, projY, 3.0, windowWidth, windowHeight)
|
|
in
|
|
Vector.concat [playerVec, projectilesVec]
|
|
end)
|
|
| _ =>
|
|
case #attacked player of
|
|
NOT_ATTACKED =>
|
|
getWhenNotAttacked (player, rx, ry, windowWidth, windowHeight)
|
|
| ATTACKED amt =>
|
|
getWhenAttacked (player, amt, rx, ry, windowWidth, windowHeight)
|
|
|
|
fun get (player: player, width, height) =
|
|
let
|
|
val {x, y, attacked, facing, ...} = player
|
|
val wratio = width / Constants.worldWidthReal
|
|
val hratio = height / Constants.worldHeightReal
|
|
in
|
|
if wratio < hratio then
|
|
let
|
|
val scale = Constants.worldHeightReal * wratio
|
|
val yOffset =
|
|
if height > scale then (height - scale) / 2.0
|
|
else if height < scale then (scale - height) / 2.0
|
|
else 0.0
|
|
|
|
val rx = Real32.fromInt x * wratio
|
|
val ry = Real32.fromInt y * wratio + yOffset
|
|
in
|
|
helpGet (player, x, y, 0.0, yOffset, wratio, rx, ry, width, height)
|
|
end
|
|
else
|
|
let
|
|
val scale = Constants.worldWidthReal * hratio
|
|
val xOffset =
|
|
if width > scale then (width - scale) / 2.0
|
|
else if width < scale then (scale - width) / 2.0
|
|
else 0.0
|
|
|
|
val rx = Real32.fromInt x * hratio + xOffset
|
|
val ry = Real32.fromInt y * hratio
|
|
in
|
|
helpGet (player, x, y, xOffset, 0.0, hratio, rx, ry, width, height)
|
|
end
|
|
end
|
|
end
|