Stuck in wall bug (#5)

* Created a GetCollisionSide method.

* Bug Fixed and Tested

Co-authored-by: jme9 <jme9@pdx.edu>
This commit is contained in:
J. M. Ellis
2025-05-17 18:55:17 -07:00
committed by GitHub
parent 218f4da157
commit b9b339d51c
5 changed files with 90 additions and 19 deletions
+36 -2
View File
@@ -33,13 +33,47 @@ namespace LunaLightXMG
} }
// Method to check if a position is colliding with any wall // Method to check if a position is colliding with any wall
public static bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platforms) public static bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platform)
{ {
if (IsColliding(position + new Vector2(1, 0), boundingBox, platforms) || IsColliding(position + new Vector2(-1, 0), boundingBox, platforms)) if (IsColliding(position + new Vector2(1, 0), boundingBox, platform) || IsColliding(position + new Vector2(-1, 0), boundingBox, platform))
{ {
return true; return true;
} }
return false; return false;
} }
// Method to get the collision side
public enum CollisionSide
{
None,
Top,
Bottom,
Left,
Right
}
public static CollisionSide GetCollisionSide(Vector2 position, BoundingBox boundingBox, Platform[] platform)
{
if (IsColliding(position + new Vector2(-1, 0), boundingBox, platform))
{
return CollisionSide.Left;
}
else if (IsColliding(position + new Vector2(1, 0), boundingBox, platform))
{
return CollisionSide.Right;
}
else if (IsColliding(position + new Vector2(0, -1), boundingBox, platform))
{
return CollisionSide.Top;
}
else if (IsColliding(position + new Vector2(0, 1), boundingBox, platform))
{
return CollisionSide.Bottom;
}
else
{
return CollisionSide.None;
}
}
} }
} }
+6 -4
View File
@@ -224,10 +224,12 @@ namespace LunaLightXMG
spriteBatch.DrawString(debugFont, $"VSP: {player.vsp}", new Vector2(10, 10), Color.White); spriteBatch.DrawString(debugFont, $"VSP: {player.vsp}", new Vector2(10, 10), Color.White);
spriteBatch.DrawString(debugFont, $"Grounded: {player.grounded}", new Vector2(10, 30), Color.White); spriteBatch.DrawString(debugFont, $"Grounded: {player.grounded}", new Vector2(10, 30), Color.White);
spriteBatch.DrawString(debugFont, $"Walled: {player.walled}", new Vector2(10, 50), Color.White); spriteBatch.DrawString(debugFont, $"Walled: {player.walled}", new Vector2(10, 50), Color.White);
spriteBatch.DrawString(debugFont, $"Position: {player.position}", new Vector2(10, 70), Color.White); spriteBatch.DrawString(debugFont, $"Collision Side: {player.collisionSide}", new Vector2(10, 70), Color.White);
spriteBatch.DrawString(debugFont, $"Camera Position: {camera2D.Position}", new Vector2(10, 90), Color.White);
spriteBatch.DrawString(debugFont, $"Camera Rotation: {camera2D.Rotation}", new Vector2(10, 110), Color.White); spriteBatch.DrawString(debugFont, $"Position: {player.position}", new Vector2(10, 90), Color.White);
spriteBatch.DrawString(debugFont, $"Render Target Zoom: {renderHandler.ZoomLevel}", new Vector2(10, 130), Color.White); spriteBatch.DrawString(debugFont, $"Camera Position: {camera2D.Position}", new Vector2(10, 110), Color.White);
spriteBatch.DrawString(debugFont, $"Camera Rotation: {camera2D.Rotation}", new Vector2(10, 130), Color.White);
spriteBatch.DrawString(debugFont, $"Render Target Zoom: {renderHandler.ZoomLevel}", new Vector2(10, 150), Color.White);
spriteBatch.DrawString(debugFont, $"Camera Rotation Control - Rotate left: K, Rotate right: L", new Vector2(10, 190), Color.White); spriteBatch.DrawString(debugFont, $"Camera Rotation Control - Rotate left: K, Rotate right: L", new Vector2(10, 190), Color.White);
+18 -4
View File
@@ -27,8 +27,11 @@ namespace LunaLightXMG
private Texture2D texture; private Texture2D texture;
public Vector2 position; public Vector2 position;
public BoundingBox boundingBox { get; private set; } public BoundingBox boundingBox { get; private set; }
public CollisionManager.CollisionSide collisionSide { get; private set; }
private CollisionManager collisionManager; private CollisionManager collisionManager;
public Player(Vector2 initPosition) public Player(Vector2 initPosition)
{ {
hsp = 0; hsp = 0;
@@ -150,6 +153,8 @@ namespace LunaLightXMG
walled = CollisionManager.WallCheck(position, boundingBox, platforms); walled = CollisionManager.WallCheck(position, boundingBox, platforms);
if (walled) if (walled)
wasWalled = walled; wasWalled = walled;
collisionSide = CollisionManager.GetCollisionSide(position, boundingBox, platforms);
} }
private float Approach(float start, float end, float shift) private float Approach(float start, float end, float shift)
@@ -173,10 +178,19 @@ namespace LunaLightXMG
{ {
if (grounded) if (grounded)
{ {
float adjustedPosX = (float)Math.Round(position.X); if (collisionSide == CollisionManager.CollisionSide.Right)
float adjustedPosY = (float)Math.Round(position.Y); {
position.X = adjustedPosX; position.X = (float)Math.Floor(position.X);
position.Y = adjustedPosY; }
else if (collisionSide == CollisionManager.CollisionSide.Left)
{
position.X = (float)Math.Ceiling(position.X);
}
else
{
position.X = (float)Math.Round(position.X);
}
position.Y = (float)Math.Round(position.Y);
} }
if (vsp >= 0) if (vsp >= 0)
+21
View File
@@ -0,0 +1,21 @@
## Stuck in the wall.. - April 13th, 2025
**Description:**
When the playerjumps and moves to the right into a wall, slides down the wall and hits the ground, the player then gets stuck one pixel into the wall.
**Likely Cause:**
Our players movement is calculated as floating point values for smooth movement, however to ensure pixel perfect rendering we most round the player position to an integer value when the player stops.
When the player jumps into a wall to the right the player x position stops at a floating point value and then rounds to the nearest integer once the player hits the ground. This can lead to the player position being rounded into the wall.
**Possible Fix:**
Detect which side of the player bounding box is hitting the wall, e.g. left or right and decide to round up or down depending on the side.
**Fixed:**
Added a new method to the collision manager that gets the side of the players bounding box that hits a wall. We can use this to decide whther we need to round up or down when cleaning up player position values.
I also added logic to get top, bottom and none for future things..