Microsoft가 제공 한 예는 충돌 감지 (내가 볼 수있는 것)에 작은 오류가있는 것처럼 보입니다. 사용자가 통과 할 수없는 타일과 충돌하면 교차 깊이가 계산됩니다. 더 작은 깊이 값 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;
}