Bound player position by both edges of the World.

Fixes #10 and #22.

GitOrigin-RevId: 166be078982f148035072b717b668d47d7541571
This commit is contained in:
Colin McMillen 2020-01-29 17:43:32 -05:00
parent ab62e8929a
commit fe64ec705d
2 changed files with 21 additions and 6 deletions

View File

@ -55,11 +55,14 @@ namespace SemiColinGames {
// Broad test: remove all collision targets nowhere near the player. // Broad test: remove all collision targets nowhere near the player.
var candidates = new List<Aabb>(); var candidates = new List<Aabb>();
// TODO: This is strictly larger than it needs to be. We could expand only in the actual // Expand the box in the direction of movement. The center is the midpoint of the line
// direction of movement. // between the player's current position and their desired movement. The width increases by
// the magnitude of the movement in each direction. We add 1 to each dimension just to be
// sure (the only downside is a small number of false-positive AABBs, which should be
// discarded by later tests anyhow.)
Aabb largeBox = new Aabb( Aabb largeBox = new Aabb(
new Vector2(position.X, position.Y), // current player position new Vector2(position.X + movement.X / 2, position.Y + movement.Y / 2),
new Vector2(halfSize.X + Math.Abs(movement.X), halfSize.Y + Math.Abs(movement.Y))); new Vector2(halfSize.X + Math.Abs(movement.X) + 1, halfSize.Y + Math.Abs(movement.Y) + 1));
foreach (var box in collisionTargets) { foreach (var box in collisionTargets) {
if (box.Intersect(largeBox) != null) { if (box.Intersect(largeBox) != null) {
Debug.AddRect(box, Color.Green); Debug.AddRect(box, Color.Green);

View File

@ -153,14 +153,26 @@ namespace SemiColinGames {
} }
} }
tiles = tilesList.ToArray(); tiles = tilesList.ToArray();
collisionTargets = new Aabb[tiles.Length];
// Because we added tiles from left to right, the collisionTargets are sorted by x-position.
// We maintain this invariant so that it's possible to efficiently find collisionTargets that
// are nearby a given x-position.
collisionTargets = new Aabb[tiles.Length + 2];
// Add a synthetic collisionTarget on the left side of the world.
collisionTargets[0] = new Aabb(new Vector2(-1, 0), new Vector2(1, float.MaxValue));
// Now add all the normal collisionTargets for every static terrain tile.
Vector2 halfSize = new Vector2(TileSize / 2, TileSize / 2); Vector2 halfSize = new Vector2(TileSize / 2, TileSize / 2);
for (int i = 0; i < tiles.Length; i++) { for (int i = 0; i < tiles.Length; i++) {
Vector2 center = new Vector2( Vector2 center = new Vector2(
tiles[i].Position.Left + halfSize.X, tiles[i].Position.Top + halfSize.Y); tiles[i].Position.Left + halfSize.X, tiles[i].Position.Top + halfSize.Y);
collisionTargets[i] = new Aabb(center, halfSize); collisionTargets[i + 1] = new Aabb(center, halfSize);
} }
// Add a final synthetic collisionTarget on the right side of the world.
collisionTargets[tiles.Length + 1] = new Aabb(
new Vector2(Width * TileSize + 1, 0), new Vector2(1, float.MaxValue));
} }
public void Draw(SpriteBatch spriteBatch, Camera camera) { public void Draw(SpriteBatch spriteBatch, Camera camera) {