1. 程式人生 > >2D地圖擦除演算法

2D地圖擦除演算法

.  關於2D地圖擦除演算法,去年我寫過一個實現,勉強實現了地形擦除,但跟最終效果還相差甚遠,這次我寫了一個完整的實現,在此記錄,留個印象。

.  去年的版本<<演算法 & 資料結構——裁剪多邊形>>,因為受限於當時框架用GDI實現的渲染器,只有擦除地形沒有擦除地圖,這次換了OpenGL渲染器,終於可以實現最終效果了。

這個演算法看似簡單,實際上就是很簡單,大致可分為三個部分。

地圖擦除:擦除地圖的影象,產生視覺效果。

地形擦除:擦除地圖的形狀,用於物理計算。

橡皮擦:用於定義擦除的形狀。

地圖擦除

假設這是一副畫在紙上的彩筆畫,如果要擦除畫上的一部分,有過生活經驗的人立馬就能想到用橡皮擦就好了,很多演算法靈感來自生活,生活多姿多彩的人適合做程式設計師。這個實現過程大概就是:繫結地圖到當前渲染目標,渲染“橡皮擦”讓其覆蓋範圍內的畫素,從而達到擦除效果。

橡皮擦

接著上一個環節,“橡皮擦”可以是從檔案讀取的一張圖,也可以是程式生成的一張圖。如果從檔案讀取,設定合適的BlendFunc,直接渲染覆蓋畫素顏色就行了,本例使用程式生成的圖,因為這個靈活度更高。

這是一個正10邊形的“橡皮擦”,從圖中可看出,裡面有幾條線,把正10邊形分割成了8個三角形,這8把三角形的面積和形狀等於這個正10邊形,如果你困惑為什麼要切成三角形,你運氣很好,有一個大佬剛好懂你的困惑,併為你量身定做了一篇答案<<演算法 & 資料結構——任意多邊形填充>>。

以上則是地圖的擦除效果,其中有一處細節,擦除的邊緣有點生硬,如果要製作類似《彈彈堂》這樣的遊戲,地圖是通過炮彈炸掉的,那麼被擦除的邊緣應該留下被炸過的痕跡,不用做的太真實,只要讓邊緣產生一些不一樣的漸變色就行了,要實現這一點,只需擴充套件一下“橡皮擦”的邊緣。

柔滑邊緣,用於生成描邊。

拆分三角網格,用於渲染。

柔滑邊緣後的擦除效果。

地形擦除

以上是一張加了地形的圖,你沒有看錯,就只是多了一個黑邊。

現在要通過“橡皮擦”擦除這個黑邊,與地圖擦除不同的是,地圖擦除是覆蓋畫素,而地形則是幾何計算。

演算法:

  1. 從“橡皮擦”與地形相交部分計算出N條切線。

  2. 取第i(0 <= i < N)條切線將地形一分為二。

  3. 丟棄完全包含在“橡皮擦”內的地形。

  4. i + 1,返回 2。

  5. 當前地形被切分完畢,如果還有下一個地形則返回 1,否則結束。

最終效果