Cocos 物理系统
官方文檔鏈接:https://docs.cocos.com/creator/2.3/manual/zh/physics/physics/physics-manager.html
Cocos 物理系統(tǒng)
物理系統(tǒng)將 box2d 作為內(nèi)部物理系統(tǒng),并且隱藏了大部分 box2d 實(shí)現(xiàn)細(xì)節(jié)(比如創(chuàng)建剛體,同步剛體信息到節(jié)點(diǎn)中等)。 你可以通過(guò)物理系統(tǒng)訪(fǎng)問(wèn)一些 box2d 常用的功能,比如點(diǎn)擊測(cè)試,射線(xiàn)測(cè)試,設(shè)置測(cè)試信息等。
物理系統(tǒng)相關(guān)設(shè)置
開(kāi)啟物理系統(tǒng)
物理系統(tǒng)默認(rèn)是關(guān)閉的,如果需要使用物理系統(tǒng),那么首先需要做的事情就是開(kāi)啟物理系統(tǒng),否則你在編輯器里做的所有物理編輯都不會(huì)產(chǎn)生任何效果。
在onLoad里添加:
cc.director.getPhysicsManager().enabled = true;
繪制物理調(diào)試信息
物理系統(tǒng)默認(rèn)是不繪制任何調(diào)試信息的,如果需要繪制調(diào)試信息,請(qǐng)使用 debugDrawFlags。 物理系統(tǒng)提供了各種各樣的調(diào)試信息,你可以通過(guò)組合這些信息來(lái)繪制相關(guān)的內(nèi)容。
cc.director.getPhysicsManager().debugDrawFlags = cc.PhysicsManager.DrawBits.e_aabbBit |cc.PhysicsManager.DrawBits.e_pairBit |cc.PhysicsManager.DrawBits.e_centerOfMassBit |cc.PhysicsManager.DrawBits.e_jointBit |cc.PhysicsManager.DrawBits.e_shapeBit;
設(shè)置繪制標(biāo)志位為 0,即可以關(guān)閉繪制。
cc.director.getPhysicsManager().debugDrawFlags = 0;
物理單位到像素單位的轉(zhuǎn)換
box2d 使用 米-千克-秒(MDS) 單位制,box2d 在這樣的單位制下運(yùn)算的表現(xiàn)是最佳的。 但是我們?cè)?2D 游戲運(yùn)算中一般使用 像素 來(lái)作為長(zhǎng)度單位制,所以我們需要一個(gè)比率來(lái)進(jìn)行物理單位到像素單位上的相互轉(zhuǎn)換。
一般情況下我們把這個(gè)比率設(shè)置為 32,這個(gè)值可以通過(guò) cc.PhysicsManager.PTM_RATIO 獲取,并且這個(gè)值是只讀的。
通常用戶(hù)是不需要關(guān)心這個(gè)值的,物理系統(tǒng)內(nèi)部會(huì)自動(dòng)對(duì)物理單位與像素單位進(jìn)行轉(zhuǎn)換,用戶(hù)訪(fǎng)問(wèn)和設(shè)置的都是進(jìn)行 2d 游戲開(kāi)發(fā)中所熟悉的像素單位。
設(shè)置物理重力
重力是物理表現(xiàn)中非常重要的一點(diǎn),大部分物理游戲都會(huì)使用到重力這一物理特性。
默認(rèn)的重力加速度是 (0, -320) 像素/秒^2,按照上面描述的轉(zhuǎn)換規(guī)則,即 (0, -10) 米/秒^2。
如果希望重力加速度為 0,可以這樣設(shè)置:
cc.director.getPhysicsManager().gravity = cc.v2();
如果希望修改重力加速度為其他值,比如每秒加速降落 640 像素,那么可以這樣設(shè)置:
cc.director.getPhysicsManager().gravity = cc.v2(0, -640);
設(shè)置物理步長(zhǎng)
步長(zhǎng):更新的頻率(時(shí)間單位)
物理系統(tǒng)是按照一個(gè)固定的步長(zhǎng)來(lái)更新物理世界的,默認(rèn)這個(gè)步長(zhǎng)即是你的游戲的幀率:1/framerate。
但是有的游戲可能會(huì)不希望按照這么高的頻率來(lái)更新物理世界,畢竟這個(gè)操作是比較消耗時(shí)間的,那么你可以通過(guò)降低步長(zhǎng)來(lái)達(dá)到這個(gè)效果。
var manager = cc.director.getPhysicsManager();// 開(kāi)啟物理步長(zhǎng)的設(shè)置
manager.enabledAccumulator = true;// 物理步長(zhǎng),默認(rèn) FIXED_TIME_STEP 是 1/60
manager.FIXED_TIME_STEP = 1/30;// 每次更新物理系統(tǒng)處理速度的迭代次數(shù),默認(rèn)為 10
manager.VELOCITY_ITERATIONS = 8;// 每次更新物理系統(tǒng)處理位置的迭代次數(shù),默認(rèn)為 10
manager.POSITION_ITERATIONS = 8;
注意:降低物理步長(zhǎng)和各個(gè)屬性的迭代次數(shù),都會(huì)降低物理的檢測(cè)頻率,所以會(huì)更有可能發(fā)生剛體穿透的情況,使用時(shí)需要考慮到這個(gè)情況。
查詢(xún)物體
通常你可能想知道在給定的場(chǎng)景中都有哪些實(shí)體。 比如如果一個(gè)炸彈爆炸了,在范圍內(nèi)的物體都會(huì)受到傷害,或者在策略類(lèi)游戲中,可能會(huì)希望讓用戶(hù)選擇一個(gè)范圍內(nèi)的單位進(jìn)行拖動(dòng)。
物理系統(tǒng)提供了幾個(gè)方法來(lái)高效快速地查找某個(gè)區(qū)域中有哪些物體,每種方法通過(guò)不同的方式來(lái)檢測(cè)物體,基本滿(mǎn)足游戲所需。
點(diǎn)測(cè)試
點(diǎn)測(cè)試將測(cè)試是否有碰撞體會(huì)包含一個(gè)世界坐標(biāo)系下的點(diǎn),如果測(cè)試成功,則會(huì)返回一個(gè)包含這個(gè)點(diǎn)的碰撞體。注意,如果有多個(gè)碰撞體同時(shí)滿(mǎn)足條件,下面的接口只會(huì)返回一個(gè)隨機(jī)的結(jié)果。
var collider = cc.director.getPhysicsManager().testPoint(point);
矩形測(cè)試
矩形測(cè)試將測(cè)試指定的一個(gè)世界坐標(biāo)系下的矩形,如果一個(gè)碰撞體的包圍盒與這個(gè)矩形有重疊部分,則這個(gè)碰撞體會(huì)給添加到返回列表中。
var colliderList = cc.director.getPhysicsManager().testAABB(rect);
射線(xiàn)測(cè)試
射線(xiàn)檢測(cè)用來(lái)檢測(cè)給定的線(xiàn)段穿過(guò)哪些碰撞體,我們還可以獲取到碰撞體在線(xiàn)段穿過(guò)碰撞體的那個(gè)點(diǎn)的法線(xiàn)向量和其他一些有用的信息。
var results = cc.director.getPhysicsManager().rayCast(p1, p2, type);for (var i = 0; i < results.length; i++) {var result = results[i];var collider = result.collider;var point = result.point;var normal = result.normal;var fraction = result.fraction;
}
射線(xiàn)檢測(cè)的最后一個(gè)參數(shù)指定檢測(cè)的類(lèi)型,射線(xiàn)檢測(cè)支持四種類(lèi)型。這是因?yàn)?box2d 的射線(xiàn)檢測(cè)不是從射線(xiàn)起始點(diǎn)最近的物體開(kāi)始檢測(cè)的,所以檢測(cè)結(jié)果不能保證結(jié)果是按照物體距離射線(xiàn)起始點(diǎn)遠(yuǎn)近來(lái)排序的。CocosCreator 物理系統(tǒng)將根據(jù)射線(xiàn)檢測(cè)傳入的檢測(cè)類(lèi)型來(lái)決定是否對(duì) box2d 檢測(cè)結(jié)果進(jìn)行排序,這個(gè)類(lèi)型會(huì)影響到最后返回給用戶(hù)的結(jié)果。
cc.RayCastType.Any
檢測(cè)射線(xiàn)路徑上任意的碰撞體,一旦檢測(cè)到任何碰撞體,將立刻結(jié)束檢測(cè)其他的碰撞體,最快。
cc.RayCastType.Closest
檢測(cè)射線(xiàn)路徑上最近的碰撞體,這是射線(xiàn)檢測(cè)的默認(rèn)值,稍慢。
cc.RayCastType.All
檢測(cè)射線(xiàn)路徑上的所有碰撞體,檢測(cè)到的結(jié)果順序不是固定的。在這種檢測(cè)類(lèi)型下,一個(gè)碰撞體可能會(huì)返回多個(gè)結(jié)果,這是因?yàn)?box2d 是通過(guò)檢測(cè)夾具(fixture)來(lái)進(jìn)行物體檢測(cè)的,而一個(gè)碰撞體中可能由多個(gè)夾具(fixture)組成的,慢。更多細(xì)節(jié)可到 物理碰撞組件 查看。
cc.RayCastType.AllClosest
檢測(cè)射線(xiàn)路徑上所有碰撞體,但是會(huì)對(duì)返回值進(jìn)行刪選,只返回每一個(gè)碰撞體距離射線(xiàn)起始點(diǎn)最近的那個(gè)點(diǎn)的相關(guān)信息,最慢。
射線(xiàn)檢測(cè)的結(jié)果
射線(xiàn)檢測(cè)的結(jié)果包含了許多有用的信息,你可以根據(jù)實(shí)際情況來(lái)選擇如何使用這些信息。
collider
指定射線(xiàn)穿過(guò)的是哪一個(gè)碰撞體。
point
指定射線(xiàn)與穿過(guò)的碰撞體在哪一點(diǎn)相交。
normal
指定碰撞體在相交點(diǎn)的表面的法線(xiàn)向量。
fraction
指定相交點(diǎn)在射線(xiàn)上的分?jǐn)?shù)。
可以通過(guò)下面這張圖更好的理解射線(xiàn)檢測(cè)的結(jié)果。
總結(jié)
以上是生活随笔為你收集整理的Cocos 物理系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Cocos事件监听(JS)
- 下一篇: Cocos Creator里localS