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.
var candidates = new List<Aabb>();
// TODO: This is strictly larger than it needs to be. We could expand only in the actual
// direction of movement.
// Expand the box in the direction of movement. The center is the midpoint of the line
// 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(
new Vector2(position.X, position.Y), // current player position
new Vector2(halfSize.X + Math.Abs(movement.X), halfSize.Y + Math.Abs(movement.Y)));
new Vector2(position.X + movement.X / 2, position.Y + movement.Y / 2),
new Vector2(halfSize.X + Math.Abs(movement.X) + 1, halfSize.Y + Math.Abs(movement.Y) + 1));
foreach (var box in collisionTargets) {
if (box.Intersect(largeBox) != null) {
Debug.AddRect(box, Color.Green);

View File

@ -153,14 +153,26 @@ namespace SemiColinGames {
}
}
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);
for (int i = 0; i < tiles.Length; i++) {
Vector2 center = new Vector2(
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) {