2

我一直在为一个学校项目开发自己的物理引擎,最近遇到了一个问题:大型精灵上的每像素碰撞使我的 FPS 下降了很多。

这是我的像素碰撞代码。在输入以下代码之前,我使用Intersects()它来查看它们的边界框是否发生碰撞。

private bool PerPixelCollision(IObject a, IObject b)
{

    Color[] bitsA = new Color[a.Texture.Width * a.Texture.Height];
    a.Texture.GetData(bitsA);
    Color[] bitsB = new Color[b.Texture.Width * b.Texture.Height];
    b.Texture.GetData(bitsB);

    // Calculate the intersecting rectangle
    int x1 = Math.Max(a.Bounds.X, b.Bounds.X);
    int x2 = Math.Min(a.Bounds.X + a.Bounds.Width, b.Bounds.X + b.Bounds.Width);

    int y1 = Math.Max(a.Bounds.Y, b.Bounds.Y);
    int y2 = Math.Min(a.Bounds.Y + a.Bounds.Height, b.Bounds.Y + b.Bounds.Height);

    Color c;
    Color d;
    // For each single pixel in the intersecting rectangle
    for (int y = y1; y < y2; ++y)
    {
        for (int x = x1; x < x2; ++x)
        {
            // Get the color from each texture
            c = bitsA[(x - a.Bounds.X) + (y - a.Bounds.Y) * a.Texture.Width];
            d = bitsB[(x - b.Bounds.X) + (y - b.Bounds.Y) * b.Texture.Width];

            if (c.A != 0 && d.A != 0) // If both colors are not transparent (the alpha channel is not 0), then there is a collision
            {
                return true;
            }
        }
    }
    // If no collision occurred by now, we're clear.
    return false;
}

在我用来测试的示例中,我将 4 个精灵放入另一个代表地板 (736x79) 的精灵中。当我将代表地板的精灵更改为更大的精灵 (3600x270) 时,FPS 下降。我知道问题出在像素冲突中,因为我正在使用分析器。

有谁知道如何优化碰撞?

PS:对不起,如果我对我的问题不够清楚。我的英语不怎么好。

编辑:第一个问题是通过使用@pinckerman 提供的解决方案解决的,但我发现了另一个与像素碰撞检测相关的问题。当精灵与纹理的透明部分发生碰撞时,我们会得到相交的部分并检查该部分的所有像素。问题是:当透明部分大到足以覆盖整个精灵时,我会检查该精灵的整个纹理(目前使用 50x50 纹理,即 2500 像素)。有没有办法不检查整个纹理?

谢谢

4

1 回答 1

2

我很确定你的 FPS 下降了很多,因为你在做

Color[] bitsA = new Color[a.Texture.Width * a.Texture.Height];
a.Texture.GetData(bitsA);
Color[] bitsB = new Color[b.Texture.Width * b.Texture.Height];
b.Texture.GetData(bitsB);

在您的方法开始时。
我想您调用PerPixelCollision每个Update循环并在每个游戏循环中创建和处理数百万个值,这不是一件非常有效的事情。

一个大精灵创建一个巨大的Color[]数组:你的数组越大,这个方法就越慢。

编辑:

对于您的第二个问题,我认为,如果您事先不知道“大”纹理的透明区域在哪里,那么无论如何您都必须检查整个精灵。
如果你的精灵不是太大,那不会对性能造成很大的浪费。

PS:我看到你Rectangle自己得到了相交,也许你会发现这个方法有用。

于 2013-09-16T15:54:44.253 回答