pass in AABBs instead of Rectangles to Player.Update

GitOrigin-RevId: 08fe1aaf34210415acaa41e7e407eb1275602889
This commit is contained in:
Colin McMillen 2020-01-29 16:11:28 -05:00
parent 946497160b
commit 793b292a29
3 changed files with 27 additions and 40 deletions

View File

@ -37,38 +37,29 @@ namespace SemiColinGames {
public Point Position { get { return position; } } public Point Position { get { return position; } }
private Rectangle Bbox(Point position) { public void Update(float modelTime, History<Input> input, Aabb[] collisionTargets) {
return new Rectangle(position.X - spriteWidth, position.Y - 7, spriteWidth * 2, 26); Aabb BoxOffset(Point position, int yOffset) {
}
private Aabb Box(Point position) {
return Box(position, 0);
}
private Aabb Box(Point position, int yOffset) {
return new Aabb(new Vector2(position.X, position.Y - 7 + spriteHeight + yOffset), return new Aabb(new Vector2(position.X, position.Y - 7 + spriteHeight + yOffset),
new Vector2(spriteWidth, spriteHeight)); new Vector2(spriteWidth, spriteHeight));
} }
public void Update(float modelTime, History<Input> input, Rectangle[] collisionTargets) { Aabb Box(Point position) {
return BoxOffset(position, 0);
}
Vector2 movement = HandleInput(modelTime, input); Vector2 movement = HandleInput(modelTime, input);
// TODO: we shouldn't hardcode the tile sizes here.
Vector2 halfBoxSize = new Vector2(World.TileSize / 2, World.TileSize / 2);
// Broad test: remove all collision targets nowhere near the player. // Broad test: remove all collision targets nowhere near the player.
List<Rectangle> candidates = new List<Rectangle>(); var candidates = new List<Aabb>();
// TODO: This is strictly larger than it needs to be. We could expand only in the actual // TODO: This is strictly larger than it needs to be. We could expand only in the actual
// direction of movement. // direction of movement.
Aabb largeBox = new Aabb( Aabb largeBox = new Aabb(
new Vector2(position.X, position.Y - 7 + spriteHeight), // current player position new Vector2(position.X, position.Y - 7 + spriteHeight), // current player position
new Vector2(spriteWidth + Math.Abs(movement.X), spriteHeight + Math.Abs(movement.Y))); new Vector2(spriteWidth + Math.Abs(movement.X), spriteHeight + Math.Abs(movement.Y)));
for (int i = 0; i < collisionTargets.Length; i++) { foreach (var box in collisionTargets) {
Rectangle rect = collisionTargets[i];
Aabb box = new Aabb(
new Vector2(rect.X + World.TileSize / 2, rect.Y + World.TileSize / 2), halfBoxSize);
if (box.Intersect(largeBox) != null) { if (box.Intersect(largeBox) != null) {
Debug.AddRect(box, Color.Green); Debug.AddRect(box, Color.Green);
candidates.Add(rect); candidates.Add(box);
} }
} }
@ -80,9 +71,7 @@ namespace SemiColinGames {
Point newPosition = new Point(position.X, position.Y + dy); Point newPosition = new Point(position.X, position.Y + dy);
Aabb player = Box(newPosition); Aabb player = Box(newPosition);
bool reject = false; bool reject = false;
foreach (var rect in candidates) { foreach (var box in candidates) {
Aabb box = new Aabb(
new Vector2(rect.X + World.TileSize / 2, rect.Y + World.TileSize / 2), halfBoxSize);
if (box.Intersect(player) != null) { if (box.Intersect(player) != null) {
reject = true; reject = true;
break; break;
@ -96,9 +85,7 @@ namespace SemiColinGames {
Point newPosition = new Point(position.X + dx, position.Y); Point newPosition = new Point(position.X + dx, position.Y);
Aabb player = Box(newPosition); Aabb player = Box(newPosition);
bool reject = false; bool reject = false;
foreach (var rect in candidates) { foreach (var box in candidates) {
Aabb box = new Aabb(
new Vector2(rect.X + World.TileSize / 2, rect.Y + World.TileSize / 2), halfBoxSize);
if (box.Intersect(player) != null) { if (box.Intersect(player) != null) {
reject = true; reject = true;
break; break;
@ -111,24 +98,21 @@ namespace SemiColinGames {
} }
bool standingOnGround = false; bool standingOnGround = false;
Aabb groundIntersect = Box(position, 1); Aabb groundIntersect = BoxOffset(position, 1);
foreach (var rect in candidates) { foreach (var box in candidates) {
Aabb box = new Aabb(
new Vector2(rect.X + World.TileSize / 2, rect.Y + World.TileSize / 2), halfBoxSize);
if (groundIntersect.Intersect(box) != null) { if (groundIntersect.Intersect(box) != null) {
standingOnGround = true; standingOnGround = true;
Debug.AddRect(rect, Color.Cyan); break;
// break;
} }
} }
if (standingOnGround) { if (standingOnGround) {
jumps = 1; jumps = 1;
ySpeed = -0.0001f; ySpeed = -0.0001f;
// Debug.AddRect(playerBbox, Color.Red); Debug.AddRect(Box(position), Color.Cyan);
} else { } else {
jumps = 0; jumps = 0;
// Debug.AddRect(playerBbox, Color.Orange); Debug.AddRect(Box(position), Color.Orange);
} }
if (movement.X > 0) { if (movement.X > 0) {

View File

@ -93,8 +93,7 @@ namespace SemiColinGames {
if (!paused) { if (!paused) {
float modelTime = (float) gameTime.ElapsedGameTime.TotalSeconds; float modelTime = (float) gameTime.ElapsedGameTime.TotalSeconds;
Clock.AddModelTime(modelTime); Clock.AddModelTime(modelTime);
Rectangle[] collisionTargets = world.CollisionTargets; player.Update(modelTime, input, world.CollisionTargets);
player.Update(modelTime, input, collisionTargets);
camera.Update(player.Position); camera.Update(player.Position);
} }

View File

@ -83,7 +83,7 @@ namespace SemiColinGames {
public const int TileSize = 16; public const int TileSize = 16;
readonly Tile[] tiles; readonly Tile[] tiles;
readonly Rectangle[] collisionTargets; readonly Aabb[] collisionTargets;
public int Width { get; private set; } public int Width { get; private set; }
public int Height { get; private set; } public int Height { get; private set; }
@ -153,9 +153,13 @@ namespace SemiColinGames {
} }
} }
tiles = tilesList.ToArray(); tiles = tilesList.ToArray();
collisionTargets = new Rectangle[tiles.Length]; collisionTargets = new Aabb[tiles.Length];
Vector2 halfSize = new Vector2(TileSize / 2, TileSize / 2);
for (int i = 0; i < tiles.Length; i++) { for (int i = 0; i < tiles.Length; i++) {
collisionTargets[i] = tiles[i].Position; Vector2 center = new Vector2(
tiles[i].Position.Left + halfSize.X, tiles[i].Position.Top + halfSize.Y);
collisionTargets[i] = new Aabb(center, halfSize);
} }
} }
@ -165,7 +169,7 @@ namespace SemiColinGames {
} }
} }
public Rectangle[] CollisionTargets { public Aabb[] CollisionTargets {
get { return collisionTargets; } get { return collisionTargets; }
} }
} }