我一直在爲一個學校項目開發我自己的物理引擎,最近我遇到了一個問題:每個像素在大精靈上的碰撞使我的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;
}
在我用來測試的例子中,我在另一個代表地板(736x79)的精靈中放了4個精靈。當我將代表地板的精靈更改爲更大的精靈(3600x270)時,FPS會下降。我知道這個問題出現在像素碰撞中,因爲我正在使用探查器。
有沒有人有任何想法如何優化碰撞?
P.S .:對不起,如果我不清楚我的問題。我的英文不是很好。
編輯:第一個問題是通過使用@pinckerman提供的解決方案解決的,但我發現另一個與像素碰撞檢測有關。 當一個精靈與一個紋理的透明部分碰撞時,我們得到相交的部分並檢查該部分的所有像素。問題是:當透明部分足夠大以覆蓋整個精靈時,我會檢查該精靈的整個紋理(當前使用的是50x50像素,即2500像素)。有沒有辦法不檢查整個紋理?
感謝
我不是專家,但我不認爲你應該對像地板這樣的東西進行像素碰撞檢查。如果你想要地形碰撞做某種多邊形碰撞檢查。或者如果地板只是平坦的做一個矩形甚至一個線路交叉口檢查。對不起,但我無法幫助您優化您的算法。 –
不要使用這個。這是殺人兇手。使用線,框,圓,多邊形碰撞。或者全部組合在一起,但不是像素碰撞。這只是浪費資源。 –
我覺得有必要給我的人羣添加我的聲音,並指出你正在遇到性能問題,從事這種碰撞檢測。在紋理上調用'GetData()'會安裝渲染pipeline_,這將阻止GPU和CPU以最高效率一起工作。在大多數情況下,使用幾何碰撞檢測會更好 - 儘管當然這種學習練習沒有任何問題。有關更多信息,請參閱[本文](http://blogs.msdn.com/b/shawnhar/archive/2008/04/14/stalling-the-pipeline.aspx)。 –