摘要:MSDN論壇上面有人問的問題 - 關於2D碰撞範例的疑問
由sonic10690作者所發問
內容
因為3D實在是難以前進
所以就退回來研究2D了
今天研究了兩個在Creator的2D碰撞範例
分別是
Collision Series 1: 2D Rectangle Collision
Collision Series 2: 2D Per-Pixel Collision
由sonic10690作者所發問
內容
因為3D實在是難以前進
所以就退回來研究2D了
今天研究了兩個在Creator的2D碰撞範例
分別是
Collision Series 1: 2D Rectangle Collision
Collision Series 2: 2D Per-Pixel Collision
不過其實這算是同一個範例
算是基礎到進階吧
第一個拿到範例的問題一就是此範例中所用的圖片
不管是磚塊還是人都是bmp的格式
而且我還開啟圖片明明周圍的顏色是紫色的
可是為什麼直接將它貼上去的話
居然變成透明色了
問題二:
再來就是想問一下Color的結構
我的映象中應該是很簡單的RGB而已
可是在範例Collision Series 2: 2D Per-Pixel Collision中
我發現我又不懂color的結構了Orz
順便在這裡問一下
有什麼辦法可以讀取到color裡面值來看一下
因為範例中的blockTexture.GetData(blockTextureData);
這行應該已經把所有像素點的資料都傳過去了
可是卻不知道到底是什麼數值
問題三:
還有關於GetData這函式去查了MSDN它只有說Copies texture data into an array
貼圖資料就是指像素資料RGB等資訊吧?(此為個人認知不知是否有錯)
問題四:
Collision Series 2: 2D Per-Pixel Collision中的函式static bool IntersectPixels()
這裡是用像素來判斷有沒有碰撞到
可是我看不太懂下列迴圈的意思
for (int x = left; x < right; x++)
{
// Get the color of both pixels at this point
Color colorA = dataA[(x - rectangleA.Left) +
(y - rectangleA.Top) * rectangleA.Width];
Color colorB = dataB[(x - rectangleB.Left) +
(y - rectangleB.Top) * rectangleB.Width];
// If both pixels are not completely transparent,
if (colorA.A != 0 && colorB.A != 0)
{
// then an intersection has been found
return true;
}
}
}
疑問一
Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width];
為何要乘上矩形A的寬這跟Color什麼關係呢?
還有Color成員變數A是指Alpha值的意思嗎?
// then an intersection has been found
return true;
}
為什麼兩個不等於就代表碰到呢@@||
看來有必要重新認識一下Alpha值了
不好意思ㄧ下提了這麼多問題QQ
不過這應該都算是2D常見的問題吧
回答
// Extract collision data
問 題一 、那張圖片我們可以使用DirectX的工具來做,或者說一般的繪圖工具都可以,他的原理就是說,我們會找一個平常不會用的顏色,像是綠色 (0,255,0)、桃紅色(255,0,255),這些平常不常用的顏色來做跟圖形與空白的區別,這個部分就跟alpha遮罩有關係,我們決定好背井透 明的顏色以後,會給他一個alpha值,在XNA中Content Processor可以針對那些顏色、alpha去做設定,看看哪些要慮掉之類的。你可以點一下Content中的resource,你在看看他們屬性, 可以看到下圖的東西
可以看到他現在設定的顏色RGB為(255,0,255)
還有一個關鍵就是Color Key Enable這個屬性要為True
這樣Content processor在處理圖片的時候,就會把那些條件的顏色處理掉。讓你看不到
問題二、 color的結構主要重點就在於RGBA這四個而已,顏色都是由這四個屬性混搭而成。
如果要看他裡面有甚麼RGB數值的話,可以用設定中斷點的方式,就是在
blockTextureData =
new Color[blockTexture.Width * blockTexture.Height];
blockTexture.GetData(blockTextureData);
personTextureData =
new Color[personTexture.Width * personTexture.Height];
personTexture.GetData(personTextureData);
你可以在GetData的地方設定中斷點,按下F9設定
不過這邊建議你是在下一行設定,因為顏色那些資料複製,是在那函數中設定的,如果在那行設定的話,一執行到那行才中斷,那行的指令都還沒開始,所以你看到的資料都是0。
問題三、Texture2D.GetData<T>(<T> array); 這個函數會把現在Content處理好的資料抓出來,也就是抓出RGBA的資料。
如果要看他抓的資料的話,可以用中斷點來看。
問題四、這個範例主要用pixel去判斷碰撞問題,他的圖片都是只有Alpha的數值,沒有RGBA那些數值(你可以用中斷點去看)。所以他的偵測方式當然就是看看A值是不是計算過後不等於0。
你說為什麼要乘上矩形的高度,這是跟他的儲存方式有關係,因為他是將資料存乘一維矩陣... 當然你可以試試看2為矩陣去做,只是迴圈設計的部分要想一想(內部迴圈越多可能會導致速度會越慢)
他碰撞想法是由alpha來看,255是黑色,也就是你看到的那個人跟錐子,當發生交集時候兩個同時取出的Pixel值都是255,所以就是非0,這樣就發生碰撞了。
希望以上回答的你看得懂。
在MSDN論壇發問的問題,我會的或是可以馬上回覆的我就會回覆,像sonic在那邊還有另一個問題,只是那個3D動畫的問題,我現在雖然知道他怎麼做,只是有些部分需要研究一下,所以沒這麼快回覆...
還有之所以會把問題COPY過來,是因為這樣有人有相同的問題,可以來看看這個文章