diff --git a/fcore/game-type.sml b/fcore/game-type.sml index e9bd219..dc353e9 100644 --- a/fcore/game-type.sml +++ b/fcore/game-type.sml @@ -102,7 +102,7 @@ struct , health = 1 , xAxis = EntityType.MOVE_RIGHT , yAxis = EntityType.FALLING - , variant = EnemyType.STRAIGHT_BAT + , variant = EnemyType.PATROL_SLIME , batDirY = EnemyType.UP , platID = ~1 , nextPlatID = ~1 @@ -110,7 +110,22 @@ struct , batMaxY = 485 , batMinY = 625 } - val enemies = enemyMapFromList ([enemy1], EnemyMap.empty) + val enemy2 = + { id = 2 + , x = 351 + , y = 555 + , health = 1 + , xAxis = EntityType.MOVE_RIGHT + , yAxis = EntityType.FALLING + , variant = EnemyType.PATROL_SLIME + , batDirY = EnemyType.UP + , platID = ~1 + , nextPlatID = ~1 + , batRest = 0 + , batMaxY = 485 + , batMinY = 625 + } + val enemies = enemyMapFromList ([enemy1, enemy2], EnemyMap.empty) val graph = Graph.fromPlatforms (platforms, platformTree) in { player = player diff --git a/fcore/game-update.sml b/fcore/game-update.sml index 4abb683..8a5a7dc 100644 --- a/fcore/game-update.sml +++ b/fcore/game-update.sml @@ -21,6 +21,11 @@ struct val (player, enemies) = PlayerAttack.attackEnemies (player, enemies, enemyTree) + val projectiles = #projectiles player + val (fallingEnemies, enemies) = + PlayerAttack.projectileHitEnemy + (projectiles, enemies, enemyTree, fallingEnemies) + val enemies = Enemy.update (enemies, walls, wallTree, platforms, platformTree, player, graph) diff --git a/fcore/player/player-attack.sml b/fcore/player/player-attack.sml index 5c170c3..3252c87 100644 --- a/fcore/player/player-attack.sml +++ b/fcore/player/player-attack.sml @@ -8,33 +8,24 @@ struct open EnemyType - fun onAttacked (enemyID, enemy, enemyMap, defeatedList) = + fun defeatEnemy (enemyID, enemyMap, defeatedList) = + let + val defeatedList = {angle = 1} :: defeatedList + val enemyMap = EnemyMap.remove (enemyID, enemyMap) + in + (defeatedList, enemyMap) + end + + fun onPlayerAttack (enemyID, enemy, enemyMap, defeatedList) = case #variant enemy of - PATROL_SLIME => - let - val defeatedList = {angle = 1} :: defeatedList - val enemyMap = EnemyMap.remove (enemyID, enemyMap) - in - (defeatedList, enemyMap) - end - | FOLLOW_SLIME => - let - val defeatedList = {angle = 1} :: defeatedList - val enemyMap = EnemyMap.remove (enemyID, enemyMap) - in - (defeatedList, enemyMap) - end - | STRAIGHT_BAT => - let - val defeatedList = {angle = 1} :: defeatedList - val enemyMap = EnemyMap.remove (enemyID, enemyMap) - in - (defeatedList, enemyMap) - end + PATROL_SLIME => defeatEnemy (enemyID, enemyMap, defeatedList) + | FOLLOW_SLIME => defeatEnemy (enemyID, enemyMap, defeatedList) + | STRAIGHT_BAT => defeatEnemy (enemyID, enemyMap, defeatedList) fun fold (enemyID, (), (defeatedList, enemyMap)) = case EnemyMap.get (enemyID, enemyMap) of - SOME enemy => onAttacked (enemyID, enemy, enemyMap, defeatedList) + SOME enemy => + onPlayerAttack (enemyID, enemy, enemyMap, defeatedList) | NONE => (defeatedList, enemyMap) end) @@ -66,4 +57,60 @@ struct end | _ => (player, enemyMap) end + + structure ProjectileHitEnemy = + MakeQuadTreeFold + (struct + type env = unit + type state = EnemyType.falling_enemy list * EnemyMap.t + + open EnemyType + + fun onDefeated (enemyID, enemy, enemyMap, fallingList) = + let + val {x, y, variant, ...} = enemy + val fallingList = {x = x, y = y, variant = variant} :: fallingList + val enemyMap = EnemyMap.remove (enemyID, enemyMap) + in + (fallingList, enemyMap) + end + + fun onProjectileAttack (enemyID, enemy, enemyMap, fallingList) = + case #variant enemy of + PATROL_SLIME => onDefeated (enemyID, enemy, enemyMap, fallingList) + | FOLLOW_SLIME => onDefeated (enemyID, enemy, enemyMap, fallingList) + | STRAIGHT_BAT => onDefeated (enemyID, enemy, enemyMap, fallingList) + + fun fold (enemyID, (), (fallingList, enemyMap)) = + case EnemyMap.get (enemyID, enemyMap) of + SOME enemy => + onProjectileAttack (enemyID, enemy, enemyMap, fallingList) + | NONE => (fallingList, enemyMap) + end) + + fun helpProjectileHitEnemy (pos, projectiles, enemyTree, enemyMap, newFalling) = + if pos = Vector.length projectiles then + (newFalling, enemyMap) + else + let + val {x, y, ...}: PlayerType.player_projectile = + Vector.sub (projectiles, pos) + val size = Constants.projectileSizeInt + val (newFalling, enemyMap) = ProjectileHitEnemy.foldRegion + (x, y, size, size, (), (newFalling, enemyMap), enemyTree) + in + helpProjectileHitEnemy + (pos + 1, projectiles, enemyTree, enemyMap, newFalling) + end + + fun projectileHitEnemy (projectiles, enemyMap, enemyTree, oldFalling) = + let + val (newFalling, enemyMap) = helpProjectileHitEnemy + (0, projectiles, enemyTree, enemyMap, []) + + val newFalling = Vector.fromList newFalling + val allFalling = Vector.concat [newFalling, oldFalling] + in + (allFalling, enemyMap) + end end