diff --git a/fcore/constants.sml b/fcore/constants.sml index 795bd6b..e9aef27 100644 --- a/fcore/constants.sml +++ b/fcore/constants.sml @@ -30,7 +30,10 @@ struct val enemySize = 35 val enemySizeReal: Real32.real = 35.0 val moveEnemyBy = 3 + val batRestLimit = 55 + val moveBatX = 1 + val moveBatY = 2 val moveProjectileBy = 11 end diff --git a/fcore/enemy/enemy-behaviour.sml b/fcore/enemy/enemy-behaviour.sml index 8abeec1..6d67e95 100644 --- a/fcore/enemy/enemy-behaviour.sml +++ b/fcore/enemy/enemy-behaviour.sml @@ -502,50 +502,58 @@ struct fun updateStraightBat (player, enemy, walls, wallTree, projectileTree, enemyList, fallingList) = let - val {x, y, batRest, ...} = enemy + val {x, y, batRest, batDirY, batMinY, batMaxY, xAxis, ...} = enemy + val size = Constants.enemySize - in - if QuadTree.hasCollisionAt (x, y, size, size, ~1, wallTree) then - (* has collision with wall *) - let - val enemy = - if batRest >= Constants.batRestLimit then - (* make enemy move in opposite direction *) - case #xAxis enemy of - MOVE_RIGHT => - EnemyPatch.withPatches - ( enemy - , [ EnemyPatch.W_X_AXIS MOVE_LEFT - , EnemyPatch.W_X (x - (Constants.moveEnemyBy * 9)) - ] - ) - | MOVE_LEFT => - EnemyPatch.withPatches - ( enemy - , [ EnemyPatch.W_X_AXIS MOVE_RIGHT - , EnemyPatch.W_X (x + (Constants.moveEnemyBy * 9)) - ] - ) - | _ => enemy + val moveByY = Constants.moveBatY + val moveByX = Constants.moveBatX + + val patches = + (* get apatches for up/down movement *) + case batDirY of + UP => + if y - moveByY <= batMaxY then + [EnemyPatch.W_BAT_DIR_Y DOWN, EnemyPatch.W_Y (y + moveByY)] else - (* keep resting until we hit rest limit *) - EnemyPatch.withPatch (enemy, EnemyPatch.W_BAT_REST (batRest + 1)) - in - (enemy :: enemyList, fallingList) - end - else - (* no collision, so continue moving in direction *) - let - val patches = - case #xAxis enemy of - MOVE_RIGHT => [EnemyPatch.W_X (x + Constants.moveEnemyBy)] - | MOVE_LEFT => [EnemyPatch.W_X (x - Constants.moveEnemyBy)] - | STAY_STILL => [] - val patches = EnemyPatch.W_BAT_REST 0 :: patches - val enemy = EnemyPatch.withPatches (enemy, patches) - in - (enemy :: enemyList, fallingList) - end + [EnemyPatch.W_Y (y - moveByY)] + | DOWN => + if y + moveByY >= batMinY then + [EnemyPatch.W_BAT_DIR_Y UP, EnemyPatch.W_Y (y - moveByY)] + else + [EnemyPatch.W_Y (y + moveByY)] + + val patches = + (* get patches for horizontal movement *) + if QuadTree.hasCollisionAt (x, y, size, size, ~1, wallTree) then + (* has collision with wall *) + if batRest >= Constants.batRestLimit then + (* make enemy move in opposite direction *) + case xAxis of + MOVE_RIGHT => + EnemyPatch.W_X_AXIS MOVE_LEFT :: EnemyPatch.W_X (x - 1) + :: patches + | MOVE_LEFT => + EnemyPatch.W_X_AXIS MOVE_RIGHT :: EnemyPatch.W_X (x + 1) + :: patches + | _ => patches + else + (* keep resting until we hit rest limit *) + EnemyPatch.W_BAT_REST (batRest + 1) :: patches + else + (* no collision, so continue moving in direction *) + let + val patches = + case xAxis of + MOVE_RIGHT => EnemyPatch.W_X (x + moveByX) :: patches + | MOVE_LEFT => EnemyPatch.W_X (x - moveByX) :: patches + | STAY_STILL => patches + in + EnemyPatch.W_BAT_REST 0 :: patches + end + + val enemy = EnemyPatch.withPatches (enemy, patches) + in + (enemy :: enemyList, fallingList) end fun updateEnemyState diff --git a/fcore/game-type.sml b/fcore/game-type.sml index 1ec3bac..8fc6efe 100644 --- a/fcore/game-type.sml +++ b/fcore/game-type.sml @@ -234,8 +234,8 @@ struct , nextPlatID = ~1 , batRest = 0 , batDirY = UP - , batMaxY = 635 - , batMinY = 475 + , batMaxY = 485 + , batMinY = 625 } val enemies = Vector.fromList [enemy1] val graph = Graph.fromPlatforms (platforms, platformTree) diff --git a/fcore/quad-tree-fold.sml b/fcore/quad-tree-fold.sml index e860226..b034167 100644 --- a/fcore/quad-tree-fold.sml +++ b/fcore/quad-tree-fold.sml @@ -10,9 +10,15 @@ signature MAKE_QUAD_TREE_FOLD = sig structure Fn: QUAD_FOLDER - val foldRegion: int * int * int * int * - Fn.env * Fn.state * {tree: QuadTreeType.t, width: int, height: int} - -> Fn.state + val foldRegion: + int + * int + * int + * int + * Fn.env + * Fn.state + * {tree: QuadTreeType.t, width: int, height: int} + -> Fn.state end functor MakeQuadTreeFold(Fn: QUAD_FOLDER): MAKE_QUAD_TREE_FOLD = @@ -50,38 +56,79 @@ struct val state = if vtl then - helpFoldRegion - (rx, ry, rw, rh, env, state, qx, qy, hw, hh, Vector.sub (nodes, tlIdx)) + helpFoldRegion + ( rx + , ry + , rw + , rh + , env + , state + , qx + , qy + , hw + , hh + , Vector.sub (nodes, tlIdx) + ) else state - val state = + val state = if vtr then - helpFoldRegion - (rx, ry, rw, rh, env, state, qx + hw, qy, hw, hh, Vector.sub (nodes, trIdx)) - else + helpFoldRegion + ( rx + , ry + , rw + , rh + , env + , state + , qx + hw + , qy + , hw + , hh + , Vector.sub (nodes, trIdx) + ) + else state - val state = + val state = if vbl then helpFoldRegion - (rx, ry, rw, rh, env, state, qx, qy + hh, hw, hh, Vector.sub (nodes, blIdx)) + ( rx + , ry + , rw + , rh + , env + , state + , qx + , qy + hh + , hw + , hh + , Vector.sub (nodes, blIdx) + ) else state in if vbr then - helpFoldRegion - (rx, ry, rw, rh, env, state, qw + hw, qy + hh, hw, hh, Vector.sub (nodes, brIdx)) + helpFoldRegion + ( rx + , ry + , rw + , rh + , env + , state + , qw + hw + , qy + hh + , hw + , hh + , Vector.sub (nodes, brIdx) + ) else state end - | LEAF items => - foldRegionVec (rx, ry, rw, rh, env, state, 0, items) + | LEAF items => foldRegionVec (rx, ry, rw, rh, env, state, 0, items) fun foldRegion (rx, ry, rw, rh, env, state, tree) = - let - val {width, height, tree} = tree - in - helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree) + let val {width, height, tree} = tree + in helpFoldRegion (rx, ry, rw, rh, env, state, 0, 0, width, height, tree) end end diff --git a/fcore/quad-tree-type.sml b/fcore/quad-tree-type.sml index c931951..7f46775 100644 --- a/fcore/quad-tree-type.sml +++ b/fcore/quad-tree-type.sml @@ -2,51 +2,33 @@ signature QUAD_TREE_TYPE = sig type item = {itemID: int, startX: int, startY: int, width: int, height: int} - datatype t = - NODE of t vector - | LEAF of item vector + datatype t = NODE of t vector | LEAF of item vector val tlIdx: int val trIdx: int val blIdx: int val brIdx: int - val isColliding: int * int * int * int * - int * int * int * int - -> bool + val isColliding: int * int * int * int * int * int * int * int -> bool - val isCollidingPlus: int * int * int * int * - int * int * int * int - -> bool + val isCollidingPlus: int * int * int * int * int * int * int * int -> bool - val isCollidingItem: int * int * int * int * - int * item - -> bool + val isCollidingItem: int * int * int * int * int * item -> bool - val visitTopLeft: int * int * int * int * - int * int * int * int - -> bool + val visitTopLeft: int * int * int * int * int * int * int * int -> bool - val visitTopRight: int * int * int * int * - int * int * int * int - -> bool + val visitTopRight: int * int * int * int * int * int * int * int -> bool - val visitBottomLeft: int * int * int * int * - int * int * int * int - -> bool + val visitBottomLeft: int * int * int * int * int * int * int * int -> bool - val visitBottomRight: int * int * int * int * - int * int * int * int - -> bool + val visitBottomRight: int * int * int * int * int * int * int * int -> bool end structure QuadTreeType :> QUAD_TREE_TYPE = struct type item = {itemID: int, startX: int, startY: int, width: int, height: int} - datatype t = - NODE of t vector - | LEAF of item vector + datatype t = NODE of t vector | LEAF of item vector val tlIdx = 0 val trIdx = 1 diff --git a/fcore/quad-tree.sml b/fcore/quad-tree.sml index 43e3f06..611ae87 100644 --- a/fcore/quad-tree.sml +++ b/fcore/quad-tree.sml @@ -26,7 +26,7 @@ struct val vec = Vector.fromList [] val tree = LEAF vec in - { tree = tree, width = width, height = height } + {tree = tree, width = width, height = height} end fun mkItem (id, startX, startY, width, height) : item = @@ -41,10 +41,8 @@ struct val maxSize = 16 fun mkLeaf items = - let - val items = Vector.fromList items - in - LEAF items + let val items = Vector.fromList items + in LEAF items end fun splitLeaf @@ -65,7 +63,7 @@ struct val tr = mkLeaf tr val bl = mkLeaf bl val br = mkLeaf br - val nodes = Vector.fromList [tl, tr, bl, br] + val nodes = Vector.fromList [tl, tr, bl, br] in NODE nodes end @@ -101,20 +99,18 @@ struct val tl = Vector.sub (nodes, tlIdx) val tl = - if vtl then - helpInsert (ix, iy, iw, ih, itemID, qw, qy, hw, hh, tl) - else - tl + if vtl then helpInsert (ix, iy, iw, ih, itemID, qw, qy, hw, hh, tl) + else tl val tr = Vector.sub (nodes, trIdx) val tr = if vtr then helpInsert (ix, iy, iw, ih, itemID, qx + hw, qy, hw, hh, tr) - else + else tr val bl = Vector.sub (nodes, blIdx) - val bl = + val bl = if vbl then helpInsert (ix, iy, iw, ih, itemID, qx, qy + hh, hw, hh, bl) else @@ -124,7 +120,7 @@ struct val br = if vbr then helpInsert (ix, iy, iw, ih, itemID, qx + hw, qy + hh, hw, hh, br) - else + else br val nodes = Vector.fromList [tl, tr, bl, br] @@ -160,35 +156,40 @@ struct fun insert (iX, iY, iW, iH, itemID, tree: t) = let val {width, height, tree} = tree - val tree = - helpInsert (iX, iY, iW, iH, itemID, 0, 0, width, height, tree) + val tree = helpInsert (iX, iY, iW, iH, itemID, 0, 0, width, height, tree) in {width = width, height = height, tree = tree} end - structure GetCollisions = MakeQuadTreeFold (struct - type env = unit - type state = int list - fun fold (itemID, (), lst) = itemID :: lst - end) + structure GetCollisions = + MakeQuadTreeFold + (struct + type env = unit + type state = int list + fun fold (itemID, (), lst) = itemID :: lst + end) fun getCollisions (itemX, itemY, itemWidth, itemHeight, _, tree) = GetCollisions.foldRegion (itemX, itemY, itemWidth, itemHeight, (), [], tree) - structure HasCollisionAt = MakeQuadTreeFold (struct - type env = unit - type state = bool - fun fold _ = true - end) + structure HasCollisionAt = + MakeQuadTreeFold + (struct + type env = unit + type state = bool + fun fold _ = true + end) fun hasCollisionAt (ix, iy, iw, ih, _, tree) = HasCollisionAt.foldRegion (ix, iy, iw, ih, (), false, tree) - structure GetItemID = MakeQuadTreeFold (struct - type env = unit - type state = int - fun fold (itemID, (), curID) = Int.max (itemID, curID) - end) + structure GetItemID = + MakeQuadTreeFold + (struct + type env = unit + type state = int + fun fold (itemID, (), curID) = Int.max (itemID, curID) + end) fun getItemID (ix, iy, iw, ih, tree) = GetItemID.foldRegion (ix, iy, iw, ih, (), ~1, tree)