? ?最近打算做一個2D投籃游戲,由于對于BOX2D等物理引擎并不熟悉,加之一開始低估了游戲所需要的碰撞檢測復雜度,認為僅僅涉及4面墻,籃球,籃板,籃筐,籃網的碰撞檢測并不復雜。因此決定自己實現所需要的碰撞檢測。結果實際開始做時磕磕碰碰遇到了許多問題。
? ? 1、如何實現像素級碰撞檢測。
? ?as3原生的hitTestObject只能檢測矩形,對于圓形等其他形狀就不適用了;打算用hitTestPoint來檢測籃球與籃板四個邊角,籃筐前后框點,在實踐嘗試中發現是有問題的,在涉及物體旋轉的情況下檢測就不精確了。因此只能自己實現像素級碰撞檢測。在網上查找了許多資料,終于找到比較好的解決思路:利用疊加模式檢測兩物體不透明像素部分。
分享一位國外大牛寫的不規則物體像素級碰撞檢測算法及詳解
2、計算碰撞物體的反彈速度及方向。
? ?我們可以常見的使用BOX2D等物理引擎實現的游戲,如桌球游戲,球與球相撞、球與桌的相撞,根據碰撞角度不同,反彈速度和方向也是不同的。把事情交給物理引擎解決,當然是高枕無憂,如果想自己計算出反彈速度及方向。那就不僅是寫寫代碼的問題,而是要通過數學、物理來解決。基本該問題分為兩部分解決:
a)恢復現場:由于物體的移動是按幀改變的,所以物體位置變化不是連續的,而是離散的。當碰撞發生時,兩物體已經相交重疊了,而實際計算反彈速度和方向,需要在物體剛剛相碰撞一刻的情況下進行。因此需要將兩物體合理地恢復到剛剛碰撞的位置。實際物理引擎的處理非常復雜,而本游戲則是采用簡單方法處理。將球按反速度一點點回退,直到球與碰撞點的距離剛好為球的半徑。
b)利用向量原理計算反彈速度及方向。實話說,自己憑空想的話怎么也想不到是通過向量的思路得出答案。剛開始做時琢磨了很久,查了一些資料,終于在一個帖子找到答案,這不就是高中學的空間向量嘛?赤果果的數學題啊~~
向量幾何在游戲編程中的使用
?
我們現在的任務是:已知物體的速度向量S和邊界向量b,求它的反射向量F。我們先來看一下在碰撞過程中都有哪些向量關系:
設b是障礙向量,S是入射速度向量,F是反射速度向量,也就是我們要計算的向量。A是入射角度,A'是反射角度,A=A'。N是b的法向量,即N垂直于b。n是與N共線的向量,n'是N方向的單位向量。T是垂直于N的向量。根據向量加法,現在有關系:
(1) S + n = T
(2) n + T = F
合并,得
F = 2*T - S?
又已知T = S + n,
最終得 F = 2(S + n) - S = S - 2n
?
實際寫代碼是,Sx,Sy,nx,ny都是可以計算出來的,通過公式最終求出Fx,Fy。
?
3、畫出瞄準線。
許多主流投籃類游戲都能在籃球投出前畫出瞄準線。說下實現思路。根據鼠標按下時的位置和當前位置可計算出初始速度和方向。既然知道了速度,就可根據時間計算距離。因此可計算投出后每隔一段時間后(如每隔0.1s),小球的舞臺坐標,并依次draw出一個個點,看起來就是一條瞄準線。有個必須要注意的細節。畫點的時候,要考慮重力對于垂直速度的改變。并且改變值要與實際小球渲染時的速度改變相同。如渲染時每隔0.1s計算一次重力因素對垂直速度的改變。在瞄準畫線時也需要每隔0.1s改變一次垂直速度。只有這樣,瞄準線才是正確的。
?
實現過程折騰了很久,解決了以上問題后終于使投籃過程顯得比較真實。盡管如此,這樣一個自己現實的簡單碰撞檢測,使用很局限,游戲玩法稍微深挖,像要在場景加入新的物體,就無法勝任了。最終學習了下BOX2D發現也不復雜,還是改成用Box2d物理引擎來做,通過筆者一番蛋疼的折騰后也證實,如果想要認認真真做一個物理游戲,用物理引擎才是正確的做法,把專業任務講給專業的系統去處理。
這里分享自己做這個小游戲的經驗,存當拋磚引玉,希望有人碰到某些特定需求,可以用上這些技巧。
游戲源碼下載地址:
不使用物理引擎,自己動手做真實物理的模擬投籃游戲
?