帮助理解代码片段(AABB碰撞)

时间:2011-08-29 00:48:14

标签: c#

我从另一个游戏中抢走了这块瓷砖碰撞代码,但本着理解而不仅仅是偷窃的精神,我想帮助了解它究竟是做什么的。具体来说,x1,y1,x2,y2的功能是什么,以及为什么它选择在对象的实际边界框之外开始和结束一个图块。

...
    ...
        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。

1 个答案:

答案 0 :(得分:3)

它在对象的边界框之外选择开始和结束图块,因为对象可能正在移动,并且具有速度。

x1,y1,x2,y2是解决碰撞后对象的外边界。

该函数返回一个新的对象速度,以防止对象发生碰撞。