মাইক্রোসফ্ট সরবরাহিত উদাহরণটি দেখে মনে হচ্ছে যেন সংঘর্ষ সনাক্তকরণ (যা আমি দেখতে পাচ্ছি) তাতে একটি ছোট ত্রুটি ঘটবে। যখন ব্যবহারকারী একটি আনপাসেবল টাইলের সাথে সংঘর্ষ হয় তখন ছেদটির গভীরতা গণনা করা হয়। গভীরতার মানগুলি 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;
}