我从另一个游戏中抢走了这段瓷砖碰撞代码,但本着理解而不只是窃取的精神,我希望获得一些帮助来理解它到底是做什么的。具体来说,x1、y1、x2、y2 的函数是什么,以及为什么它选择对象实际边界框之外的开始和结束一个图 block 。
...
...
Int32 Tile.Size = 16;
...
...
...
private Vector2 CheckTileCollision(Vector2 velocity)
{
// Find all the tiles we intersect with, including a layer outside.
Int32 startx = (Int32)((Single)this.Left / Tile.Size) - 1;
Int32 endx = (Int32)((Single)this.Right / Tile.Size) + 1;
Int32 starty = (Int32)((Single)this.Top / Tile.Size) - 1;
Int32 endy = (Int32)((Single)this.Bottom / Tile.Size) + 1;
// The following are array positions, not world positions.
Int32 x1 = -1; // Only set when there's a horizontal collision
Int32 y1 = -1; // Only set when there's a horizontal collision
Int32 x2 = -1; // Only set when there's a vertical collision
Int32 y2 = -1; // Only set when there's a vertical collision
Vector2 newVelocity = velocity;
Vector2 nextPosition = this.position + velocity;
for (Int32 x = startx; x <= endx; x += 1)
{
for (Int32 y = starty; y <= endy; y += 1)
{
if (realm.TileAt(x, y).IsSolid) // We only collide with solid tiles.
{
// The world coordinates of a tile.
Vector2 tilePosition = new Vector2(x * Tile.Size, y * Tile.Size);
// Check if we intersect the tile.
if (nextPosition.X + this.Width > tilePosition.X &&
nextPosition.X < tilePosition.X + Tile.Size &&
nextPosition.Y + this.Height > tilePosition.Y &&
nextPosition.Y < tilePosition.Y + Tile.Size)
{
realm.Tiles[x, y].Debug = true;
if (this.Bottom <= tilePosition.Y) // if the bottom is above or touching the tile top
{
x2 = x; // x2 is set to current tile array position, not world position
y2 = y; // y2 is set to current tile array position, not world position
if (x2 != x1)
newVelocity.Y = tilePosition.Y - (position.Y + this.Height);
}
else if (this.Right <= tilePosition.X) // if the right side is to the left or touching the tile left
{
x1 = x; // x1 is set to current tile array position, not world position
y1 = y; // y1 is set to current tile array position, not world position
if (y1 != y2)
newVelocity.X = tilePosition.X - (position.X + this.Width);
if (x2 == x1)
newVelocity.Y = this.Velocity.Y;
}
else if (this.Left >= tilePosition.X + Tile.Size)// if the left side is to the right or touching the tile right
{
x1 = x; // x1 is set to current tile array position, not world position
y1 = y; // y1 is set to current tile array position, not world position
if (y1 != y2)
newVelocity.X = (tilePosition.X + Tile.Size) - position.X;
if (x2 == x1)
newVelocity.Y = this.Velocity.Y;
}
else if (this.Top >= tilePosition.Y + Tile.Size) // if the top is below or touching the tile bottom
{
x2 = x; // x2 is set to current tile array position, not world position
y2 = y; // y2 is set to current tile array position, not world position
newVelocity.Y = (tilePosition.Y + Tile.Size) - position.Y;
if (y2 == y1)
newVelocity.X = this.Velocity.X;
}
}
}
}
}
return newVelocity;
}
...
编辑
向代码中添加了更多注释,并修复了 ifs。
最佳答案
它会选取对象边界框之外的开始和结束图 block ,因为该对象可能正在移动,并且具有速度。
x1、y1、x2、y2 是对象解决碰撞后的外部边界。
该函数返回对象的新速度,以防止对象发生碰撞。
关于c# - 帮助理解代码片段(AABB碰撞),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7229589/