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

标签 c#

我从另一个游戏中抢走了这段瓷砖碰撞代码,但本着理解而不只是窃取的精神,我希望获得一些帮助来理解它到底是做什么的。具体来说,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/

相关文章:

c# - 如何使用 JSON 嵌套对象

c# - 检查 block blob 是否存在失败

c# - 用于检查字符串是否以某个子字符串开头的正则表达式模式?

c# - 无法在 ssl 模式下使用端口 25 发送电子邮件?

c# - basicHttpBinding 和 webHttpBinding 在一起

c# - VS2017 安装项目 - 在哪里?

c# - 如何在 Orchard 的特殊区域中为特殊小部件创建 View 替代?

c# - vb6 com 服务器中属性和事件之间的歧义

C# SelectVoice 在 Windows 应用程序中没有改变,但在控制台中改变

c# - 如何使用 CancellationTokenSource 关闭另一个线程上的对话框?