這兩天在用cocos-js 開發一個一堆小球碰來碰去的遊戲,就打算選擇一款實體引擎來簡化代碼。第一開始打算用box2d(網上一片好評),但是看看之後發現box2d适用于js-HTML版本,對js打包版本(jsb)是不适用的(我沒有深入探究,不知道是不是)。于是打算使用Chipmunk來開發。但由于Chipmunk沒有js文檔,隻有C++版本的(官網位址:http://chipmunk-physics.net/),百度也找不到合适的教程,在做碰撞監聽這塊兒時,廢了很大功夫,在一定程度上是根據C++文檔來猜js中對應的函數的。。。是以做完之後,寫出這篇部落格來友善有同樣需求的哥們兒。(但不知效果如何)
部落格中如有錯誤的地方,請大家指出,謝謝!
Cocos IDE工程代碼免費下載下傳位址:http://download.csdn.net/detail/u013647453/8910481
(目前功能有随機産生小球,點選螢幕産生小球,小球碰撞的監聽和處理)
(注釋掉的代碼大家可以忽略)
1.先對Chipmunk的核心進行簡單介紹。(摘自Cocos官方文檔:http://cn.cocos2d-x.org/tutorial/show?id=2706)
Chipmunk實體引擎有一些自己的核心概念,這些核心概念主要有:
空間(space):實體空間,所有物體都在這個空間中發生。
物體(body):實體空間中的物體。
形狀(shape):物體的形狀。
關節(joint):用于連接配接兩個物體的限制。
使用Chipmunk實體引擎進行開發的一般步驟,如下圖所示。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zMxIjNzEDM5EzNxcDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
2.遊戲Demo的概述
- 隻有一個scene:PlayingScene和一個layer:PlayingLayer。大家隻需要關注PlayingLayer中代碼即可。
- PlayingLayer代碼結構概述:(重點關注紅色标注的函數代碼)
ctor(): initPhysicsWorld:建立實體空間(space),設定重力,設定空間邊緣及其彈性、摩擦和碰撞檢測要用到的參數:shape.setCollisionType(constant),這個參數相當于物體的一個标志。對于所有參與碰撞的物體,要監聽其碰撞的話都應該設定這個标志,在添加碰撞監聽、處理監聽到的事件時都要用到。 scheduleUpdate:調用update函數,用來告訴Chipmunk引擎更新界面。 schedule:每兩秒調用addBall()來随機添加一個小球。 onEnter(): this.space.addCollisionHandler( COLLISION_TYPEA, COLLISION_TYPEB //要監聽的兩種碰撞物體的标志 collisionBegin, collisionPre, collisionPost, collisionSeparate //碰撞過程的回調函數): space添加碰撞監聽,需要針對每個碰撞的情況來添加監聽。小球遊戲中參與碰撞的物體有:上、左、右邊界; 下邊界 ; 小球 (因為小球碰到下邊界将來要特殊處理,是以在這裡把邊界分為兩部分)。碰撞的情況有:小球和小球;小球和上、左、右邊界;小球和下邊界。那麼這裡需要添加三類監聽。 cc.EventListener.create():手勢監聽,用來監聽觸摸手勢,在觸摸位置添加小球。
update():用來告訴Chipmunk引擎更新界面。
addBall():在空間(space)中添加物體。添加body:設定形狀、位置、速度;添加shape:設定形狀、彈性、摩擦和碰撞檢測要用到的參數;添加sprite。
碰撞後的回調函數:(摘自http://my.oschina.net/lonewolf/blog/173593)
collisionBegin():碰撞開始時調用,碰撞處理代碼可以放在這裡
collisionPre():持續碰撞(相交),可以設定相交時獨自的摩擦,彈力等
collisionPost():調用完collisionPre後,做後期處理,比如計算破壞等
collisionSeparate():物體分開,當删除一個shape時也會調用
3.從下圖的角度來看Chipmunk
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zMxIjNzEDM5EzNxcDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
重點函數及其完成的功能:
initialPhysicsWorld:建立實體空間(space),指定空間邊界。
addBall:建立空間中的物體,建立空間中的形狀,連結精靈與物體。
addCollisionHandler:檢測(監聽)碰撞。
collisionBegin:處理碰撞。
簡化的過程是這樣的:
建立一個space,給space添加物體。然後隻需要通知Chipmunk更新界面就行了(update函數)。
附加解釋:
邊界是不動的物體,小球是動的物體。
Chipmunk更新界面時是根據space設定的屬性:gravity等;邊界的屬性:彈性、摩擦、碰撞物體的标志;小球的屬性:初速度、位置、彈性、摩擦、碰撞物體的标志 這些屬性,然後通過時間的推移,并處理過碰撞之後,來計算并更新小球未來的位置的。
給space添加的碰撞監聽其實就是告訴Chipmunk在物體碰撞的過程中(碰到、相交、分離),如果碰撞的兩個物體的COLLISION_TYPE(碰撞物體的标志)跟傳遞的兩個參數一緻的話,就調用所傳遞的collisionBegin,collisionPre,collisionPost,collisionSeparate函數。
4.代碼解讀
詳細代碼就請大家下載下傳代碼來看吧,加了英文注釋(歡迎吐槽),一方面是中文編碼問題,另一方面是我自己的習慣問題,不習慣的哥們兒還請見諒,不過都是常見英文,比較容易了解。
Cocos IDE工程代碼免費下載下傳位址:http://download.csdn.net/detail/u013647453/8910481
(注釋掉的代碼大家可以忽略)
為什麼不把代碼貼上來呢?
因為我在讀别人部落格的時候,感覺把代碼分散開來,然後在代碼前加一句說明并沒有實際意義,相對直接讀有注釋的源代碼來說,後者可以有一個整體的感覺,而非零散的代碼片段,另外加上注釋後,并不會影響對代碼的了解。
主要參考的部落格:
http://my.oschina.net/lonewolf/blog/173593
http://www.cnblogs.com/linn/p/3656041.html
http://cn.cocos2d-x.org/tutorial/show?id=2706
Chipmunk官網(有C++ API文檔和一些教程):
http://chipmunk-physics.net/
如有謬誤,歡迎指出,謝謝!
最後,附上Android真機的運作截圖(其實沒什麼用):