mirror of
https://github.com/TheRavenwoodArts/LunaLightXMG.git
synced 2026-07-30 22:05:02 -07:00
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:
+3
-3
@@ -5,17 +5,17 @@ namespace LunaLightXMG
|
|||||||
public class BoundingBox
|
public class BoundingBox
|
||||||
{
|
{
|
||||||
public Rectangle Bounds { get; private set; }
|
public Rectangle Bounds { get; private set; }
|
||||||
|
|
||||||
public BoundingBox(Rectangle bounds)
|
public BoundingBox(Rectangle bounds)
|
||||||
{
|
{
|
||||||
Bounds = bounds;
|
Bounds = bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Intersects(BoundingBox other)
|
public bool Intersects(BoundingBox other)
|
||||||
{
|
{
|
||||||
return Bounds.Intersects(other.Bounds);
|
return Bounds.Intersects(other.Bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update(Vector2 position, int width, int height)
|
public void Update(Vector2 position, int width, int height)
|
||||||
{
|
{
|
||||||
Bounds = new Rectangle((int)position.X, (int)position.Y, width, height);
|
Bounds = new Rectangle((int)position.X, (int)position.Y, width, height);
|
||||||
|
|||||||
+36
-2
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-7
@@ -105,13 +105,13 @@ namespace LunaLightXMG
|
|||||||
sinkBeats = Content.Load<SoundEffect>("music/sinkBeats");
|
sinkBeats = Content.Load<SoundEffect>("music/sinkBeats");
|
||||||
// load player sprite
|
// load player sprite
|
||||||
player.LoadContent(Content); // player sprite is now handled in player.cs
|
player.LoadContent(Content); // player sprite is now handled in player.cs
|
||||||
|
|
||||||
// Spawn 10 enemies at the start of the level
|
// Spawn 10 enemies at the start of the level
|
||||||
enemies = SpawnEnemies(numOfEnemies);
|
enemies = SpawnEnemies(numOfEnemies);
|
||||||
|
|
||||||
// Test Render Target Handler
|
// Test Render Target Handler
|
||||||
renderHandler = new RenderHandler(GraphicsDevice, spriteBatch, retroWidth, retroHeight);
|
renderHandler = new RenderHandler(GraphicsDevice, spriteBatch, retroWidth, retroHeight);
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
debugFont = Content.Load<SpriteFont>("fonts/debugFont");
|
debugFont = Content.Load<SpriteFont>("fonts/debugFont");
|
||||||
debugGrid = Content.Load<Texture2D>("debugGrid");
|
debugGrid = Content.Load<Texture2D>("debugGrid");
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -130,7 +133,7 @@ namespace LunaLightXMG
|
|||||||
hsp = 0;
|
hsp = 0;
|
||||||
}
|
}
|
||||||
position.X += hsp; // Horizontal move
|
position.X += hsp; // Horizontal move
|
||||||
|
|
||||||
// Vertical collision prediction
|
// Vertical collision prediction
|
||||||
float onePixv = Math.Sign(vsp);
|
float onePixv = Math.Sign(vsp);
|
||||||
if (CollisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms))
|
if (CollisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms))
|
||||||
@@ -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)
|
||||||
@@ -168,17 +173,26 @@ namespace LunaLightXMG
|
|||||||
}
|
}
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DumpFractions()
|
private void DumpFractions()
|
||||||
{
|
{
|
||||||
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)
|
||||||
{
|
{
|
||||||
hsp += hsp_frac;
|
hsp += hsp_frac;
|
||||||
|
|||||||
@@ -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..
|
||||||
Reference in New Issue
Block a user