use timing information introduced in MAIN_ATTACKING case so that a second attack is required to add a falling enemy to the player's list
This commit is contained in:
@@ -4,60 +4,78 @@ struct
|
||||
structure PlayerAttackEnemy =
|
||||
MakeQuadTreeFold
|
||||
(struct
|
||||
type env = unit
|
||||
type env = Time.time
|
||||
type state = FallingEnemyMap.t * EnemyMap.t
|
||||
|
||||
open EnemyType
|
||||
|
||||
fun defeatEnemy (enemyID, enemyMap, fallingMap) =
|
||||
fun defeatEnemy (enemyID, enemyMap, fallingMap, time) =
|
||||
case EnemyMap.get (enemyID, enemyMap) of
|
||||
SOME (enemy: EnemyType.enemy) =>
|
||||
let
|
||||
val {x, y, variant, ...} = enemy
|
||||
val fallenEnemy = {x = x, y = y, variant = variant}
|
||||
val fallingMap = FallingEnemyMap.add (enemyID, fallenEnemy, fallingMap)
|
||||
val enemyMap = EnemyMap.remove (enemyID, enemyMap)
|
||||
in
|
||||
(fallingMap, enemyMap)
|
||||
end
|
||||
| NONE => (fallingMap, enemyMap)
|
||||
SOME (enemy: EnemyType.enemy) =>
|
||||
let
|
||||
val {x, y, variant, ...} = enemy
|
||||
val fallenEnemy =
|
||||
{x = x, y = y, variant = variant, time = time}
|
||||
val fallingMap =
|
||||
FallingEnemyMap.add (enemyID, fallenEnemy, fallingMap)
|
||||
val enemyMap = EnemyMap.remove (enemyID, enemyMap)
|
||||
in
|
||||
(fallingMap, enemyMap)
|
||||
end
|
||||
| NONE => (fallingMap, enemyMap)
|
||||
|
||||
fun shieldSlimeAttacked (enemyID, enemy, enemyMap, fallingMap) =
|
||||
fun shieldSlimeAttacked (enemyID, enemy, enemyMap, fallingMap, time) =
|
||||
if #shieldOn enemy then (fallingMap, enemyMap)
|
||||
else defeatEnemy (enemyID, enemyMap, fallingMap)
|
||||
else defeatEnemy (enemyID, enemyMap, fallingMap, time)
|
||||
|
||||
fun onPlayerAttack (enemyID, enemy, enemyMap, fallingMap) =
|
||||
fun onPlayerAttack (enemyID, enemy, enemyMap, fallingMap, time) =
|
||||
case #variant enemy of
|
||||
PATROL_SLIME => defeatEnemy (enemyID, enemyMap, fallingMap)
|
||||
| FOLLOW_SLIME => defeatEnemy (enemyID, enemyMap, fallingMap)
|
||||
| STRAIGHT_BAT => defeatEnemy (enemyID, enemyMap, fallingMap)
|
||||
PATROL_SLIME => defeatEnemy (enemyID, enemyMap, fallingMap, time)
|
||||
| FOLLOW_SLIME => defeatEnemy (enemyID, enemyMap, fallingMap, time)
|
||||
| STRAIGHT_BAT => defeatEnemy (enemyID, enemyMap, fallingMap, time)
|
||||
| SHIELD_SLIME =>
|
||||
shieldSlimeAttacked (enemyID, enemy, enemyMap, fallingMap)
|
||||
shieldSlimeAttacked (enemyID, enemy, enemyMap, fallingMap, time)
|
||||
|
||||
fun fold (enemyID, (), (fallingMap, enemyMap)) =
|
||||
fun fold (enemyID, time, (fallingMap, enemyMap)) =
|
||||
case EnemyMap.get (enemyID, enemyMap) of
|
||||
SOME enemy =>
|
||||
onPlayerAttack (enemyID, enemy, enemyMap, fallingMap)
|
||||
onPlayerAttack (enemyID, enemy, enemyMap, fallingMap, time)
|
||||
| NONE => (fallingMap, enemyMap)
|
||||
end)
|
||||
|
||||
structure PlayerAttackFalling =
|
||||
MakeQuadTreeFold
|
||||
(struct
|
||||
type env = unit
|
||||
type env = Time.time
|
||||
type state = PlayerType.defeated_enemies list * FallingEnemyMap.t
|
||||
|
||||
fun fold (fallingID, (), (defeatedList, fallingMap)) =
|
||||
let
|
||||
val defeatedList = {angle = 1} :: defeatedList
|
||||
val fallingMap = FallingEnemyMap.remove (fallingID, fallingMap)
|
||||
in
|
||||
(defeatedList, fallingMap)
|
||||
end
|
||||
open Time
|
||||
|
||||
fun fold (fallingID, mainAttackTime, (defeatedList, fallingMap)) =
|
||||
case FallingEnemyMap.get (fallingID, fallingMap) of
|
||||
SOME {time = fallingStartTime, ...} =>
|
||||
if mainAttackTime > fallingStartTime then
|
||||
let
|
||||
val defeatedList = {angle = 1} :: defeatedList
|
||||
val fallingMap =
|
||||
FallingEnemyMap.remove (fallingID, fallingMap)
|
||||
in
|
||||
(defeatedList, fallingMap)
|
||||
end
|
||||
else
|
||||
(defeatedList, fallingMap)
|
||||
| NONE => (defeatedList, fallingMap)
|
||||
end)
|
||||
|
||||
fun helpAttackEnemies
|
||||
(projectileX, projectileY, enemyMap, enemyTree, fallingMap, player) =
|
||||
( projectileX
|
||||
, projectileY
|
||||
, enemyMap
|
||||
, enemyTree
|
||||
, fallingMap
|
||||
, player
|
||||
, mainAttackTime
|
||||
) =
|
||||
let
|
||||
val width = Constants.projectileWidth
|
||||
val height = Constants.projectileHeight
|
||||
@@ -68,13 +86,20 @@ struct
|
||||
, projectileY
|
||||
, width
|
||||
, height
|
||||
, ()
|
||||
, mainAttackTime
|
||||
, ([], fallingMap)
|
||||
, fallingTree
|
||||
)
|
||||
|
||||
val (fallingMap, enemyMap) = PlayerAttackEnemy.foldRegion
|
||||
(projectileX, projectileY, width, height, (), (fallingMap, enemyMap), enemyTree)
|
||||
( projectileX
|
||||
, projectileY
|
||||
, width
|
||||
, height
|
||||
, mainAttackTime
|
||||
, (fallingMap, enemyMap)
|
||||
, enemyTree
|
||||
)
|
||||
|
||||
val defeatedList = Vector.fromList defeatedList
|
||||
val defeatedList = Vector.concat [defeatedList, #enemies player]
|
||||
@@ -91,7 +116,7 @@ struct
|
||||
val {x, y, facing, mainAttack, ...} = player
|
||||
in
|
||||
case mainAttack of
|
||||
MAIN_ATTACKING _ =>
|
||||
MAIN_ATTACKING {timePressed, ...} =>
|
||||
(case facing of
|
||||
FACING_RIGHT =>
|
||||
let
|
||||
@@ -105,6 +130,7 @@ struct
|
||||
, enemyTree
|
||||
, fallingMap
|
||||
, player
|
||||
, timePressed
|
||||
)
|
||||
end
|
||||
| FACING_LEFT =>
|
||||
@@ -119,6 +145,7 @@ struct
|
||||
, enemyTree
|
||||
, fallingMap
|
||||
, player
|
||||
, timePressed
|
||||
)
|
||||
end)
|
||||
| _ => (player, enemyMap, fallingMap)
|
||||
@@ -128,15 +155,16 @@ struct
|
||||
structure ProjectileHitEnemy =
|
||||
MakeQuadTreeFold
|
||||
(struct
|
||||
type env = unit
|
||||
type env = Time.time
|
||||
type state = FallingEnemyMap.t * EnemyMap.t
|
||||
|
||||
open EnemyType
|
||||
|
||||
fun onDefeated (enemyID, enemy, enemyMap, fallingMap) =
|
||||
fun onDefeated (enemyID, enemy, enemyMap, fallingMap, currentTime) =
|
||||
let
|
||||
val {x, y, variant, ...} = enemy
|
||||
val fallingItem = {x = x, y = y, variant = variant}
|
||||
val fallingItem =
|
||||
{x = x, y = y, variant = variant, time = currentTime}
|
||||
val fallingMap =
|
||||
FallingEnemyMap.add (enemyID, fallingItem, fallingMap)
|
||||
val enemyMap = EnemyMap.remove (enemyID, enemyMap)
|
||||
@@ -144,26 +172,34 @@ struct
|
||||
(fallingMap, enemyMap)
|
||||
end
|
||||
|
||||
fun onShieldSlimeAttacked (enemyID, enemy, enemyMap, fallingMap) =
|
||||
fun onShieldSlimeAttacked
|
||||
(enemyID, enemy, enemyMap, fallingMap, currentTime) =
|
||||
if #shieldOn enemy then (fallingMap, enemyMap)
|
||||
else onDefeated (enemyID, enemy, enemyMap, fallingMap)
|
||||
else onDefeated (enemyID, enemy, enemyMap, fallingMap, currentTime)
|
||||
|
||||
fun onProjectileAttack (enemyID, enemy, enemyMap, fallingMap) =
|
||||
fun onProjectileAttack
|
||||
(enemyID, enemy, enemyMap, fallingMap, currentTime) =
|
||||
case #variant enemy of
|
||||
PATROL_SLIME => onDefeated (enemyID, enemy, enemyMap, fallingMap)
|
||||
| FOLLOW_SLIME => onDefeated (enemyID, enemy, enemyMap, fallingMap)
|
||||
| STRAIGHT_BAT => onDefeated (enemyID, enemy, enemyMap, fallingMap)
|
||||
PATROL_SLIME =>
|
||||
onDefeated (enemyID, enemy, enemyMap, fallingMap, currentTime)
|
||||
| FOLLOW_SLIME =>
|
||||
onDefeated (enemyID, enemy, enemyMap, fallingMap, currentTime)
|
||||
| STRAIGHT_BAT =>
|
||||
onDefeated (enemyID, enemy, enemyMap, fallingMap, currentTime)
|
||||
| SHIELD_SLIME =>
|
||||
onShieldSlimeAttacked (enemyID, enemy, enemyMap, fallingMap)
|
||||
onShieldSlimeAttacked
|
||||
(enemyID, enemy, enemyMap, fallingMap, currentTime)
|
||||
|
||||
fun fold (enemyID, (), (fallingMap, enemyMap)) =
|
||||
fun fold (enemyID, currentTime, (fallingMap, enemyMap)) =
|
||||
case EnemyMap.get (enemyID, enemyMap) of
|
||||
SOME enemy =>
|
||||
onProjectileAttack (enemyID, enemy, enemyMap, fallingMap)
|
||||
onProjectileAttack
|
||||
(enemyID, enemy, enemyMap, fallingMap, currentTime)
|
||||
| NONE => (fallingMap, enemyMap)
|
||||
end)
|
||||
|
||||
fun helpProjectileHitEnemy (pos, projectiles, enemyTree, enemyMap, fallingMap) =
|
||||
fun helpProjectileHitEnemy
|
||||
(pos, projectiles, enemyTree, enemyMap, fallingMap, currentTime) =
|
||||
if pos = Vector.length projectiles then
|
||||
(fallingMap, enemyMap)
|
||||
else
|
||||
@@ -172,12 +208,14 @@ struct
|
||||
Vector.sub (projectiles, pos)
|
||||
val size = Constants.projectileSizeInt
|
||||
val (fallingMap, enemyMap) = ProjectileHitEnemy.foldRegion
|
||||
(x, y, size, size, (), (fallingMap, enemyMap), enemyTree)
|
||||
(x, y, size, size, currentTime, (fallingMap, enemyMap), enemyTree)
|
||||
in
|
||||
helpProjectileHitEnemy
|
||||
(pos + 1, projectiles, enemyTree, enemyMap, fallingMap)
|
||||
(pos + 1, projectiles, enemyTree, enemyMap, fallingMap, currentTime)
|
||||
end
|
||||
|
||||
fun projectileHitEnemy (projectiles, enemyMap, enemyTree, fallingMap) =
|
||||
helpProjectileHitEnemy (0, projectiles, enemyTree, enemyMap, fallingMap)
|
||||
fun projectileHitEnemy
|
||||
(projectiles, enemyMap, enemyTree, fallingMap, currentTime) =
|
||||
helpProjectileHitEnemy
|
||||
(0, projectiles, enemyTree, enemyMap, fallingMap, currentTime)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user