ตัวอย่างที่ Microsoft เตรียมไว้ให้ดูเหมือนว่าการตรวจจับการชน (จากสิ่งที่ฉันเห็น) จะมีข้อผิดพลาดเล็กน้อย เมื่อผู้ใช้ชนกับไทล์ Unpassable ความลึกของจุดตัดจะถูกคำนวณ ค่าความลึกที่น้อยกว่า X และ Y ถูกใช้เพื่อกำหนดตำแหน่งของผู้ใช้ดังนั้นจึงไม่เกิดการชนกับไทล์อีกต่อไป แต่ถ้าผู้ใช้เดินทางในแนวทแยงมุมสิ่งนี้จะส่งผลให้ผู้ใช้ไม่ได้จบลงอย่างแม่นยำในจุดที่ตัวละครจะชนกับไทล์ก่อน?
ฉันอาจผิด แต่นั่นเป็นเพียงวิธีที่ฉันเห็น
private void HandleCollisions()
{
// Get the player's bounding rectangle and find neighboring tiles.
Rectangle bounds = BoundingRectangle;
int leftTile = (int)Math.Floor((float)bounds.Left / Tile.Width);
int rightTile = (int)Math.Ceiling(((float)bounds.Right / Tile.Width)) - 1;
int topTile = (int)Math.Floor((float)bounds.Top / Tile.Height);
int bottomTile = (int)Math.Ceiling(((float)bounds.Bottom / Tile.Height)) - 1;
// Reset flag to search for ground collision.
isOnGround = false;
// For each potentially colliding tile,
for (int y = topTile; y <= bottomTile; ++y)
{
for (int x = leftTile; x <= rightTile; ++x)
{
// If this tile is collidable,
TileCollision collision = Level.GetCollision(x, y);
if (collision != TileCollision.Passable)
{
// Determine collision depth (with direction) and magnitude.
Rectangle tileBounds = Level.GetBounds(x, y);
Vector2 depth = RectangleExtensions.GetIntersectionDepth(bounds, tileBounds);
if (depth != Vector2.Zero)
{
float absDepthX = Math.Abs(depth.X);
float absDepthY = Math.Abs(depth.Y);
// Resolve the collision along the shallow axis.
if (absDepthY < absDepthX || collision == TileCollision.Platform)
{
// If we crossed the top of a tile, we are on the ground.
if (previousBottom <= tileBounds.Top)
isOnGround = true;
// Ignore platforms, unless we are on the ground.
if (collision == TileCollision.Impassable || IsOnGround)
{
// Resolve the collision along the Y axis.
Position = new Vector2(Position.X, Position.Y + depth.Y);
// Perform further collisions with the new bounds.
bounds = BoundingRectangle;
}
}
else if (collision == TileCollision.Impassable) // Ignore platforms.
{
// Resolve the collision along the X axis.
Position = new Vector2(Position.X + depth.X, Position.Y);
// Perform further collisions with the new bounds.
bounds = BoundingRectangle;
}
}
}
}
}
// Save the new bounds bottom.
previousBottom = bounds.Bottom;
}