add ability to charge for attack

This commit is contained in:
2024-12-31 10:04:40 +00:00
parent eacc68e80e
commit f199da790d
4 changed files with 81 additions and 87 deletions

View File

@@ -19,7 +19,7 @@ sig
datatype facing = FACING_LEFT | FACING_RIGHT datatype facing = FACING_LEFT | FACING_RIGHT
datatype main_attack = MAIN_NOT_ATTACKING | MAIN_ATTACKING of int datatype main_attack = MAIN_NOT_ATTACKING | MAIN_ATTACKING | MAIN_CHARGING
type defeated_enemies = {x: int, y: int} type defeated_enemies = {x: int, y: int}
@@ -50,8 +50,8 @@ sig
| W_X of int | W_X of int
| W_Y of int | W_Y of int
| W_JUMP_PRESSED of bool | W_JUMP_PRESSED of bool
| W_MAIN_ATTACK_PRESSED of bool
| W_ENEMIES of defeated_enemies vector | W_ENEMIES of defeated_enemies vector
| W_CHARGE of int
type enemy = {id: int, health: int, x: int, y: int} type enemy = {id: int, health: int, x: int, y: int}
@@ -90,7 +90,7 @@ struct
datatype facing = FACING_LEFT | FACING_RIGHT datatype facing = FACING_LEFT | FACING_RIGHT
datatype main_attack = MAIN_NOT_ATTACKING | MAIN_ATTACKING of int datatype main_attack = MAIN_NOT_ATTACKING | MAIN_ATTACKING | MAIN_CHARGING
type defeated_enemies = {x: int, y: int} type defeated_enemies = {x: int, y: int}
@@ -121,8 +121,8 @@ struct
| W_X of int | W_X of int
| W_Y of int | W_Y of int
| W_JUMP_PRESSED of bool | W_JUMP_PRESSED of bool
| W_MAIN_ATTACK_PRESSED of bool
| W_ENEMIES of defeated_enemies vector | W_ENEMIES of defeated_enemies vector
| W_CHARGE of int
type enemy = {id: int, health: int, x: int, y: int} type enemy = {id: int, health: int, x: int, y: int}

View File

@@ -79,7 +79,26 @@ struct
val size = Player.size val size = Player.size
in in
case mainAttack of case mainAttack of
MAIN_NOT_ATTACKING => MAIN_ATTACKING =>
let
(* when attacking, player collision should be larger than player themselves *)
val x = x - Player.halfSize
val y = y - Player.halfSize
val size = size * 2
val enemyCollisions = QuadTree.getCollisions
(x, y, size, size, 0, 0, 1920, 1080, 0, enemyTree)
val patches =
checkEnemiesWhileAttacking (player, enemies, enemyCollisions, [])
val player = Player.withPatches (player, patches)
val enemyCollisions = Vector.fromList enemyCollisions
val enemies = filterEnemyCollisions
(Vector.length enemies - 1, enemyCollisions, enemies, [])
in
(player, enemies)
end
| _ =>
(case attacked of (case attacked of
NOT_ATTACKED => NOT_ATTACKED =>
let let
@@ -117,25 +136,6 @@ struct
in in
(player, enemies) (player, enemies)
end) end)
| MAIN_ATTACKING amt =>
let
(* when attacking, player collision should be larger than player themselves *)
val x = x - Player.halfSize
val y = y - Player.halfSize
val size = size * 2
val enemyCollisions = QuadTree.getCollisions
(x, y, size, size, 0, 0, 1920, 1080, 0, enemyTree)
val patches =
checkEnemiesWhileAttacking (player, enemies, enemyCollisions, [])
val player = Player.withPatches (player, patches)
val enemyCollisions = Vector.fromList enemyCollisions
val enemies = filterEnemyCollisions
(Vector.length enemies - 1, enemyCollisions, enemies, [])
in
(player, enemies)
end
end end
fun update (game, input) = fun update (game, input) =

View File

@@ -211,7 +211,7 @@ struct
, enemies , enemies
, charge , charge
) )
| W_MAIN_ATTACK_PRESSED mainAttackPressed => | W_ENEMIES enemies =>
mkPlayer mkPlayer
( health ( health
, xAxis , xAxis
@@ -227,7 +227,7 @@ struct
, enemies , enemies
, charge , charge
) )
| W_ENEMIES enemies => | W_CHARGE charge =>
mkPlayer mkPlayer
( health ( health
, xAxis , xAxis
@@ -268,7 +268,6 @@ struct
val floatLimit = 3 val floatLimit = 3
val recoilLimit = 15 val recoilLimit = 15
val attackedLimit = 55 val attackedLimit = 55
val mainAttackLimit = 15
val maxCharge = 60 val maxCharge = 60
(* helper functions checking input *) (* helper functions checking input *)
@@ -476,68 +475,48 @@ struct
end end
end end
fun getMainAttackPatches (prevAttack, attackHeld, mainAttackPressed) = fun getMainAttackPatches (attackHeld, chargeHeld, charge) =
case prevAttack of if attackHeld andalso charge > 0 then MAIN_ATTACKING
MAIN_NOT_ATTACKING => else if chargeHeld andalso not attackHeld then MAIN_CHARGING
if attackHeld andalso not mainAttackPressed then MAIN_ATTACKING 0 else MAIN_NOT_ATTACKING
else prevAttack
| MAIN_ATTACKING amt =>
if amt = mainAttackLimit then MAIN_NOT_ATTACKING
else let val amt = amt + 1 in MAIN_ATTACKING amt end
fun getInputPatches (player: player, input) = fun getInputPatches (player: player, input) =
case #mainAttack player of let
MAIN_NOT_ATTACKING => val
let { x
val , y
{ x , yAxis
, y , jumpPressed
, yAxis , facing
, jumpPressed , mainAttack
, facing , mainAttackPressed
, mainAttack , charge
, mainAttackPressed , ...
, ... } = player
} = player
val {leftHeld, rightHeld, upHeld, downHeld, attackHeld} = input val {leftHeld, rightHeld, upHeld, downHeld, attackHeld, chargeHeld} =
input
val xAxis = getXAxis (leftHeld, rightHeld) val xAxis = getXAxis (leftHeld, rightHeld)
val facing = getFacing (facing, xAxis) val facing = getFacing (facing, xAxis)
val mainAttack = val mainAttack = getMainAttackPatches (attackHeld, chargeHeld, charge)
getMainAttackPatches (mainAttack, attackHeld, mainAttackPressed)
val mainAttackPressed = val charge =
case mainAttack of case mainAttack of
MAIN_ATTACKING _ => true MAIN_CHARGING => Int.min (charge + 1, maxCharge)
| _ => attackHeld | MAIN_ATTACKING => Int.max (charge - 1, 0)
| MAIN_NOT_ATTACKING => charge
val acc = val acc =
[ W_X_AXIS xAxis [ W_X_AXIS xAxis
, W_FACING facing , W_FACING facing
, W_MAIN_ATTACK mainAttack , W_MAIN_ATTACK mainAttack
, W_MAIN_ATTACK_PRESSED mainAttackPressed , W_CHARGE charge
] ]
val acc = getJumpPatches (player, upHeld, downHeld, acc) val acc = getJumpPatches (player, upHeld, downHeld, acc)
in in
acc acc
end end
| MAIN_ATTACKING _ =>
let
val {mainAttack, mainAttackPressed, ...} = player
val {attackHeld, ...} = input
val mainAttack =
getMainAttackPatches (mainAttack, attackHeld, mainAttackPressed)
val mainAttackPressed =
case mainAttack of
MAIN_ATTACKING _ => true
| _ => mainAttackPressed
in
[ W_X_AXIS STAY_STILL
, W_MAIN_ATTACK mainAttack
, W_MAIN_ATTACK_PRESSED mainAttackPressed
]
end
fun getRecoilPatches player = fun getRecoilPatches player =
case #recoil player of case #recoil player of
@@ -631,7 +610,16 @@ struct
Block.lerp (x, y, size, size, width, height, 0.9, 0.9, 0.9) Block.lerp (x, y, size, size, width, height, 0.9, 0.9, 0.9)
else else
Block.lerp (x, y, size, size, width, height, 0.5, 0.5, 0.5)) Block.lerp (x, y, size, size, width, height, 0.5, 0.5, 0.5))
| MAIN_ATTACKING _ => | 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 =>
(case attacked of (case attacked of
NOT_ATTACKED => NOT_ATTACKED =>
Block.lerp (x, y, size, size, width, height, 1.0, 0.5, 0.5) Block.lerp (x, y, size, size, width, height, 1.0, 0.5, 0.5)
@@ -682,7 +670,7 @@ struct
fun getFieldVec (player: player, width, height) = fun getFieldVec (player: player, width, height) =
case #mainAttack player of case #mainAttack player of
MAIN_NOT_ATTACKING => Vector.fromList [] MAIN_NOT_ATTACKING => Vector.fromList []
| MAIN_ATTACKING amt => | _ =>
let let
val {x, y, ...} = player val {x, y, ...} = player
val wratio = width / 1920.0 val wratio = width / 1920.0
@@ -700,7 +688,7 @@ struct
val y = (Real32.fromInt y - halfRealSize) * wratio + yOffset val y = (Real32.fromInt y - halfRealSize) * wratio + yOffset
val realSize = (realSize * 2.0) * wratio val realSize = (realSize * 2.0) * wratio
val alpha = Real32.fromInt amt / Real32.fromInt mainAttackLimit val alpha = 1.0
in in
Field.lerp Field.lerp
(x, y, realSize, realSize, width, height, 0.7, 0.7, 1.0, alpha) (x, y, realSize, realSize, width, height, 0.7, 0.7, 1.0, alpha)
@@ -717,7 +705,7 @@ struct
val y = (Real32.fromInt y - halfRealSize) * hratio val y = (Real32.fromInt y - halfRealSize) * hratio
val realSize = (realSize * 2.0) * hratio val realSize = (realSize * 2.0) * hratio
val alpha = Real32.fromInt amt / Real32.fromInt mainAttackLimit val alpha = 1.0
in in
Field.lerp Field.lerp
(x, y, realSize, realSize, width, height, 0.7, 0.7, 1.0, alpha) (x, y, realSize, realSize, width, height, 0.7, 0.7, 1.0, alpha)

View File

@@ -7,6 +7,7 @@ struct
, upHeld = ref false , upHeld = ref false
, downHeld = ref false , downHeld = ref false
, attackHeld = ref false , attackHeld = ref false
, chargeHeld = ref false
, width = ref (1920.0 : Real32.real) , width = ref (1920.0 : Real32.real)
, height = ref (1080.0 : Real32.real) , height = ref (1080.0 : Real32.real)
} }
@@ -17,6 +18,7 @@ struct
, upHeld = !(#upHeld state) , upHeld = !(#upHeld state)
, downHeld = !(#downHeld state) , downHeld = !(#downHeld state)
, attackHeld = !(#attackHeld state) , attackHeld = !(#attackHeld state)
, chargeHeld = !(#chargeHeld state)
} }
fun getWidth () = fun getWidth () =
@@ -51,6 +53,10 @@ struct
if action = PRESS then (#attackHeld state) := true if action = PRESS then (#attackHeld state) := true
else if action = RELEASE then (#attackHeld state) := false else if action = RELEASE then (#attackHeld state) := false
else () else ()
else if key = KEY_L then
if action = PRESS then (#chargeHeld state) := true
else if action = RELEASE then (#chargeHeld state) := false
else ()
else else
() ()