use new collision-detection algorithm with old resolution algorithm (wip, slightly hacky)

GitOrigin-RevId: 998aa02a561ebf9f745b08b1186d39afad92a38e
This commit is contained in:
Colin McMillen 2020-01-29 14:39:25 -05:00
parent 08792320df
commit f2db2f4b9e

View File

@ -38,6 +38,15 @@ namespace SemiColinGames {
return new Rectangle(position.X - spriteWidth, position.Y - 7, spriteWidth * 2, 26); return new Rectangle(position.X - spriteWidth, position.Y - 7, spriteWidth * 2, 26);
} }
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 + 13 + yOffset),
new Vector2(spriteWidth, 13));
}
public void Update(float modelTime, History<Input> input, Rectangle[] collisionTargets) { public void Update(float modelTime, History<Input> input, Rectangle[] collisionTargets) {
Point oldPosition = position; Point oldPosition = position;
Vector2 movement = HandleInput(modelTime, input); Vector2 movement = HandleInput(modelTime, input);
@ -47,21 +56,26 @@ namespace SemiColinGames {
Rectangle playerBbox = Bbox(position); Rectangle playerBbox = Bbox(position);
bool standingOnGround = false; bool standingOnGround = false;
// TODO: we shouldn't hardcode the tile sizes here.
Vector2 halfBoxSize = new Vector2(World.TileSize / 2, World.TileSize / 2);
foreach (var rect in collisionTargets) { foreach (var rect in collisionTargets) {
Aabb rectBox = new Aabb(
new Vector2(rect.X + World.TileSize / 2, rect.Y + World.TileSize / 2), halfBoxSize);
Aabb playerBox = Box(position);
playerBbox = Bbox(position); playerBbox = Bbox(position);
// first we check for left-right collisions... // first we check for left-right collisions...
if (playerBbox.Intersects(rect)) { if (playerBox.Intersect(rectBox) != null) {
if (oldBbox.Right <= rect.Left && playerBbox.Right > rect.Left) { if (oldBbox.Right <= rect.Left && playerBbox.Right > rect.Left) {
position.X = rect.Left - spriteWidth; position.X = rect.Left - spriteWidth;
} }
if (oldBbox.Left >= rect.Right && playerBbox.Left < rect.Right) { if (oldBbox.Left >= rect.Right && playerBbox.Left < rect.Right) {
position.X = rect.Right + spriteWidth; position.X = rect.Right + spriteWidth;
} }
playerBbox = Bbox(position); playerBox = Box(position);
} }
// after fixing that, we check for hitting our head or hitting the ground. // after fixing that, we check for hitting our head or hitting the ground.
if (playerBbox.Intersects(rect)) { if (playerBox.Intersect(rectBox) != null) {
if (oldPosition.Y > position.Y) { if (oldPosition.Y > position.Y) {
int diff = playerBbox.Top - rect.Bottom; int diff = playerBbox.Top - rect.Bottom;
position.Y -= diff; position.Y -= diff;
@ -72,8 +86,8 @@ namespace SemiColinGames {
position.Y -= diff; position.Y -= diff;
} }
} else { } else {
playerBbox.Height += 1; playerBox = Box(position, 1);
if (playerBbox.Intersects(rect)) { if (playerBox.Intersect(rectBox) != null) {
standingOnGround = true; standingOnGround = true;
Debug.AddRect(rect, Color.Cyan); Debug.AddRect(rect, Color.Cyan);
} else { } else {