使用四叉樹優化碰撞檢測


四叉樹是干什么的?

百度百科
四元樹又稱四叉樹是一種樹狀數據結構,在每一個節點上會有四個子區塊。四元樹常應用於二維空間數據的分析與分類。 它將數據區分成為四個象限。數據范圍可以是方形或矩形或其他任意形狀。
從定義我們可以看出重點信息:

  1. 樹狀結構
  2. 四個區塊
  3. 分類
  4. 矩形

圖示講解

講解之前需要先說明一下四叉樹是用來做什么的,明白了原理才好理解它的行為。
使用四叉樹就是使用分類的方法,減少碰撞節點的個數,只取出與給定碰撞體相同區域或者壓在碰撞體所在區域邊上的對象。

  1. 將游戲屏幕分為四個區域。
    916005-20160612193213793-1006655096.png
  2. 插入對象
    916005-20160612193357043-1288525697.png
  3. 插入的對象超過了我們設置的閾值時,划分
    916005-20160612193417902-1220978536.png
  4. 插入的對象再次超過了我們設置的閾值時,繼續分。
    916005-20160612193502902-1720204858.png

分析

插入

從上面的圖示我們可以很好理解四叉樹的原理。涉及的都是插入操作。
那么插入操作具體都做了什么呢?
image.png
image.png
從代碼中我們可以看出:

  1. 當插入第一個對象的時候只走了2;這個時候沒有子樹,所以不會走1,因為objects(管理的對象)的長度還沒有超過我們設置的閾值MAX_OBJECTS,所以也不會走3。
  2. 一直插入,當objects中的數量,超過了我們設置的閾值MAX_OBJECT,就會開始划分,產生子樹,有了nodes,划分之后將自己管理的節點插入到子樹中。再此之前,都不會走1,因為還沒有產生子樹。
  3. 划分之后再次插入新對象,如果對象可以獲得對應的象限,就會走1 不會走2和3,如果沒有獲得對應的象限才會走2,3(沒有獲得的情況可能是你創建的對象在屏幕外,游戲中很多情況是敵人從屏幕外走進屏幕的,具體可參考我做的《星際迷航》或者《星際戰》游戲)。

更新對象

image.png
我是把四插入作為了對象管理器使用,要不然對象也需要更新,所以有了這一步操作。如果不這樣你需要自己創建對象管理器,一個一個放進去,刪除。通過四叉樹直接管理省了不少事情。

更新象限信息。

這是一個遞歸操作,更新象限做的事情比較多了。

  1. 檢查對象是否存活,如果死亡就回收,我這里使用了對象池,所以對象實現了poolAble接口。
    image.png

  2. 判斷對象的所占區域是否在四叉樹的區域內
    這里需要說明的是一個四叉樹本身的區域是它管理的四個象限這么大。也就是一個四叉樹管理四個象限
    83792-20170717120708910-531711251.jpg
    image.png
    不在管理區域的話需要判斷當前this是否為根節點,如果是說明對象已經出屏了。(這個時候可以通過對象實現的isVisible接口來控制是否回收,因為不是所有在屏幕外的都要回收,比如要進入屏幕的敵人,是不可能回收的,所以需要自己用isVisible接口來控制)。如果不是就將對象放入根節點,重新划分。

  3. 在管理區域內,就看看在四叉樹管理的哪個象限里。更新象限信息。
    image.png
    如果沒有變化什么都不過,如果有變化,先判斷象限是否為-1,為什么會出現-1,也就是不在四個象限的任何一個象限?因為壓線了。此番操作后的結果如下圖。
    83792-20170717120718847-65956331.jpg

根據給定矩形獲取對象列表

image.png

  1. 第一個是步長,用於獲取深度,當然深度越長,處理的時間越長,獲取的對象也精細。這個可以根據自己游戲的同屏四叉樹層級而定了。
  2. 如果通過obj的rect獲得對象所在象限如果獲得了對應的象限,用獲得的象限的四叉樹再獲取。如果壓線的話就需要將碰撞的兩個象限的內容都取出來。
  3. 返回四叉樹中沒有分割象限的對象。

怎么用呢?

image.png
自然就是把要碰撞的對象傳給retrieve函數獲得需要碰撞的對象列表進行碰撞檢測了。
也就是文章靠頭說的:
使用四叉樹就目的是為了減少碰撞節點的個數。使用的是分類的方法。
至於用什么樣的碰撞檢測函數,不是四叉樹關心的事情,
image.png
至於用幾個四叉樹管理對象,也不是四叉樹關心的事情。
image.png

結語

想要demo的同學可以去我的微店或者官方creator商城購買《跨引擎游戲框架》源碼,跟demo是一個項目。買過的同學請加我好友,群已經建好,有更新我會群里直接發包。

源碼購買入口:
image.png
demo展示:
image.png

項目截圖:
image.png
框架的相關模塊教程可以到《我的專輯》游戲開發進階教程中獲取。
后續還會推出更多與框架有關的教程:如:戰斗框架,教學框架等等。並附帶完整的游戲實現(飛行射擊游戲為例,學會做飛行射擊游戲不是目的,目的是通過這一款游戲,你可以獲得做其他所有類型的游戲的思路)。希望可以在不餓死自己的前提下幫助更過的朋友們快速找到開發思路。

長按下方二維碼,關注《微笑游戲》公眾號,獲取更多精彩內容。
image

歡迎掃碼關注公眾號《微笑游戲》,瀏覽更多內容。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM