some basic, not-quite-perfect, collision detection

GitOrigin-RevId: 32ba9d7687026097427338933cbcd06aed8dbf1e
This commit is contained in:
Colin McMillen 2019-12-12 13:33:52 -05:00
parent 1c7e058cb9
commit 11ea98345d

View File

@ -8,7 +8,7 @@ namespace Jumpy {
class Player { class Player {
enum Facing { Left, Right }; enum Facing { Left, Right };
enum Pose { Walking, Standing, Crouching, Stretching, SwordSwing, Jumping }; enum Pose { Walking, Standing, Crouching, Stretching, SwordSwing, Jumping };
enum AirState { Jumping, Ground }; enum AirState { Jumping, Ground, Falling };
private Texture2D texture; private Texture2D texture;
private const int spriteSize = 48; private const int spriteSize = 48;
@ -17,9 +17,9 @@ namespace Jumpy {
private const int moveSpeed = 200; private const int moveSpeed = 200;
private const int jumpSpeed = 600; private const int jumpSpeed = 600;
private const int gravity = 2000; private const int gravity = 2000;
private const int groundLevel = Camera.Height - spriteSize / 2 + bottomPadding - 32; private const int groundLevel = 10000;
private Point position = new Point(Camera.Width / 2, groundLevel); private Point position = new Point(Camera.Width / 2, 10);
private Facing facing = Facing.Right; private Facing facing = Facing.Right;
private Pose pose = Pose.Standing; private Pose pose = Pose.Standing;
private AirState airState = AirState.Ground; private AirState airState = AirState.Ground;
@ -35,19 +35,56 @@ namespace Jumpy {
// instead of complicated if-statements in this function. // instead of complicated if-statements in this function.
public void Update( public void Update(
GameTime time, History<GamePadState> gamePad, List<Rectangle> collisionTargets) { GameTime time, History<GamePadState> gamePad, List<Rectangle> collisionTargets) {
Point oldPosition = position;
AirState oldAirState = airState;
UpdateFromGamePad(time, gamePad); UpdateFromGamePad(time, gamePad);
Rectangle playerBbox = bool someIntersection = false;
new Rectangle(position.X - spriteWidth, position.Y - 9, spriteWidth * 2, 28);
Debug.AddRect(playerBbox, Color.Red); Rectangle playerBbox = new Rectangle(position.X - spriteWidth, position.Y - 8, spriteWidth * 2, 27);
bool standingOnGround = false;
foreach (var rect in collisionTargets) { foreach (var rect in collisionTargets) {
playerBbox = new Rectangle(position.X - spriteWidth, position.Y - 8, spriteWidth * 2, 27);
if (playerBbox.Intersects(rect)) { if (playerBbox.Intersects(rect)) {
someIntersection = true;
if (oldPosition.Y > position.Y) {
int diff = playerBbox.Top - rect.Bottom;
position.Y -= diff;
ySpeed *= 0.9;
} else {
airState = AirState.Ground;
int diff = playerBbox.Bottom - rect.Top;
position.Y -= diff;
}
Debug.AddRect(rect, Color.Yellow); Debug.AddRect(rect, Color.Yellow);
} else {
playerBbox.Height += 1;
if (playerBbox.Intersects(rect)) {
standingOnGround = true;
Debug.AddRect(rect, Color.Cyan);
} else { } else {
Debug.AddRect(rect, Color.Green); Debug.AddRect(rect, Color.Green);
} }
} }
} }
if (oldAirState != AirState.Ground && standingOnGround) {
airState = AirState.Ground;
ySpeed = 0.0;
}
if (airState == AirState.Ground && !standingOnGround) {
airState = AirState.Falling;
ySpeed = 0.0;
}
if (airState == AirState.Ground) {
Debug.AddRect(playerBbox, Color.Red);
} else if (airState == AirState.Jumping) {
Debug.AddRect(playerBbox, Color.Orange);
} else {
Debug.AddRect(playerBbox, Color.Yellow);
}
}
void UpdateFromGamePad(GameTime time, History<GamePadState> gamePad) { void UpdateFromGamePad(GameTime time, History<GamePadState> gamePad) {
if (gamePad[0].IsButtonDown(Buttons.A) && airState == AirState.Ground) { if (gamePad[0].IsButtonDown(Buttons.A) && airState == AirState.Ground) {
@ -90,7 +127,7 @@ namespace Jumpy {
pose = Pose.SwordSwing; pose = Pose.SwordSwing;
} }
if (airState == AirState.Jumping) { if (airState == AirState.Jumping || airState == AirState.Falling) {
position.Y += (int) (ySpeed * time.ElapsedGameTime.TotalSeconds); position.Y += (int) (ySpeed * time.ElapsedGameTime.TotalSeconds);
ySpeed += gravity * (float) time.ElapsedGameTime.TotalSeconds; ySpeed += gravity * (float) time.ElapsedGameTime.TotalSeconds;
if (position.Y > groundLevel) { if (position.Y > groundLevel) {