Files
sml-projects/fcore/level/enemy/falling-enemies.sml

148 lines
4.2 KiB
Standard ML

structure FallingEnemies =
struct
open EnemyType
open EntityType
(* - Generating tree of falling enemies - *)
structure FallingTree =
MakeGapMapFolder
(struct
structure Pair = FallingEnemyPair
type env = unit
type state = QuadTree.t
fun fold (fallingID, falling: EnemyType.falling_enemy, (), quadTree) =
let
val {x, y, ...} = falling
val size = Constants.enemySize
in
QuadTree.insert (x, y, size, size, fallingID, quadTree)
end
end)
fun generateTree falling =
FallingTree.foldUnordered
( falling
, ()
, QuadTree.create (Constants.worldWidth, Constants.worldHeight)
)
(* - Updating position of fallingEnemies
* - and filtering out enemies which are no longer in world bounds - *)
structure UpdateFalling =
MakeGapMapFolder
(struct
structure Pair = FallingEnemyPair
type env = unit
type state = FallingEnemyMap.t
fun fold (fallingID, fallingEnemy, (), fallingMap) =
let
val {x, y, variant} = fallingEnemy
val size = Constants.enemySize
val ww = Constants.worldWidth
val wh = Constants.worldHeight
in
if Collision.isCollidingPlus (x, y, size, size, 0, 0, ww, wh) then
let
val newFalling =
{x = x, y = y - Constants.moveEnemyBy, variant = variant}
in
FallingEnemyMap.add (fallingID, newFalling, fallingMap)
end
else
(* filter out since not in world bounds *)
fallingMap
end
end)
fun update fallingEnemies =
UpdateFalling.foldUnordered (fallingEnemies, (), FallingEnemyMap.empty)
(* - Drawing falling enemies - *)
structure FallingDrawVec =
MakeGapMapFolder
(struct
structure Pair = FallingEnemyPair
type env =
{ width: Real32.real
, height: Real32.real
, ratio: Real32.real
, xOffset: Real32.real
, yOffset: Real32.real
}
type state = Real32.real vector list
fun helpGetDrawVec
(fallingEnemy, width, height, ratio, xOffset, yOffset, acc) =
let
val {x, y, variant = _} = fallingEnemy
val x = Real32.fromInt x * ratio + xOffset
val y = Real32.fromInt y * ratio + yOffset
val size = Real32.fromInt Constants.enemySize * ratio
val vec = Block.lerp
(x, y, size, size, width, height, 0.3, 0.3, 0.3)
in
vec :: acc
end
fun fold (_, fallingEnemy, env, acc) =
let
val {width, height, ratio, xOffset, yOffset} = env
in
helpGetDrawVec
(fallingEnemy, width, height, ratio, xOffset, yOffset, acc)
end
end)
fun getDrawVec (game: LevelType.level_type, width, height) =
let
val fallingEnemies = #fallingEnemies game
val wratio = width / Constants.worldWidthReal
val hratio = height / Constants.worldHeightReal
val env =
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
in
{ width = width
, height = height
, ratio = wratio
, xOffset = 0.0
, yOffset = yOffset
}
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
in
{ width = width
, height = height
, ratio = hratio
, xOffset = xOffset
, yOffset = 0.0
}
end
val lst = FallingDrawVec.foldUnordered (fallingEnemies, env, [])
in
Vector.concat lst
end
end