laya2.0 box2d系列三 關節(jié)

一博烂、基礎概念

參考拉小登博客 初識Box2D關節(jié)b2Joint

1.剛體rigidbody :剛體是指在運動中和受力作用后逸贾,形狀和大小不變宠互,而且內(nèi)部各點的相對位置不變的物體浴讯∏嫦幔可參考laya2.0 box2d系列一 基礎概念和剛體

2.碰撞體collider:碰撞體是給物體加一個判定框究流,當碰撞框重疊的時候,兩物體發(fā)生碰撞动遭。碰撞體是檢測物理碰撞的框架芬探,他永遠跟隨物體的剛體移動,不會產(chǎn)生偏差厘惦。碰撞體有四種:矩形碰撞體偷仿,圓形碰撞體,線形碰撞體宵蕉,多邊形碰撞體酝静。每個碰撞體都是繼承自碰撞體基類∠勐辏可參考laya2.0 box2d系列二 碰撞體

3.關節(jié)joint:關節(jié)可以對兩個或多個物體進行一種約束别智。

  • JointBase->Component 關節(jié)基類
  • DistanceJoint 距離關節(jié):兩個物體上面各自有一點,兩點之間的距離固定不變
  • GearJoint 齒輪關節(jié):用來模擬兩個齒輪間的約束關系稼稿,齒輪旋轉時薄榛,產(chǎn)生的動量有兩種輸出方式,一種是齒輪本身的角速度让歼,另一種是齒輪表面的線速度
  • MotorJoint 馬達發(fā)動機關節(jié):用來限制兩個剛體敞恋,使其相對位置和角度保持不變
  • MouseJoint 鼠標關節(jié):鼠標關節(jié)用于通過鼠標來操控物體。它試圖將物體拖向當前鼠標光標的位置谋右。而在旋轉方面就沒有限制硬猫。
  • PrismaticJoint 平移關節(jié):移動關節(jié)允許兩個物體沿指定軸相對移動,它會阻止相對旋轉
  • PulleyJoint 滑輪關節(jié):它將兩個物體接地(ground)并彼此連接改执,當一個物體上升浦徊,另一個物體就會下降
  • RevoluteJoint 旋轉關節(jié):旋轉關節(jié)強制兩個物體共享一個錨點,兩個物體相對旋轉
  • RopeJoint 繩索關節(jié):限制了兩個點之間的最大距離天梧。它能夠阻止連接的物體之間的拉伸,即使在很大的負載下
  • WeldJoint 焊接關節(jié):焊接關節(jié)的用途是使兩個物體不能相對運動霞丧,受到關節(jié)的限制呢岗,兩個剛體的相對位置和角度都保持不變,看上去像一個整體
  • WheelJoint 輪子關節(jié):圍繞節(jié)點旋轉,包含彈性屬性后豫,使得剛體在節(jié)點位置發(fā)生彈性偏移
image.png

在醫(yī)學上悉尾,骨與骨之間連接的地方稱為關節(jié)。在Box2D中挫酿,剛體與剛體之間連接的線段叫做關節(jié)构眯,不難理解吧。實際上早龟,剛體可以看做是骨頭惫霸,不過醫(yī)學上的骨頭都是同軸的,也就是說葱弟,它們都圍著同一點旋轉壹店,不信看看你自己的手腕、膝蓋芝加、手指硅卢,哈哈。如果你發(fā)現(xiàn)自己的兩個骨頭不是圍著同一個軸旋轉藏杖,趕緊去醫(yī)院将塑,因為你脫臼了!蝌麸!Box2D中的關節(jié)就沒那么多限制了点寥,可以是同軸,也可以是’脫臼”祥楣。

要創(chuàng)建b2Joint實例开财,首先要創(chuàng)建b2JointDef關節(jié)需求,這一點跟b2Body的創(chuàng)建過程是類似的误褪;然后調(diào)用initialize()函數(shù)設置并實例化關節(jié)责鳍;b2JointDef有很多的子類(如b2DistanceJointDef, b2FrictionJointDef, b2GearJointDef, b2LineJointDef等等),這些子類都繼承了initialize()方法兽间,它們也都用這個方法來創(chuàng)建历葛,不過,需要根據(jù)具體的關節(jié)需求嘀略,設置一些特殊的屬性

二恤溶、laya實現(xiàn)

1.JointBase

override protected function _onEnable():void {
    _createJoint();
}

override protected function _onAwake():void {
    _createJoint();
}

protected function _createJoint():void {
}

都留著子類去重寫了

2.DistanceJoint 參考官方文檔 物理一 距離關節(jié)

image.png

通過固定長度的關節(jié)將兩剛體聯(lián)系到一起,使這兩個剛體始終保持一定的距離帜羊。用于木棍咒程,骨骼,彈簧一樣的約束關系讼育。
image.png

  • otherBody
    [首次設置有效]關節(jié)的連接剛體帐姻,可不設置稠集,默認為左上角空剛體。

  • otherAnchor
    [首次設置有效]鏈接剛體鏈接點饥瓷,是相對于otherBody的左上角位置偏移剥纷。

  • selfAnchor
    [首次設置有效]自身剛體鏈接點,是相對于自身剛體的左上角位置偏移呢铆。

  • frequency
    彈簧系統(tǒng)的震動頻率晦鞋,可以視為彈簧的彈性系數(shù)

  • damping
    剛體在回歸到節(jié)點過程中受到的阻尼,建議取值0~1棺克。

  • length
    約束的目標靜止長度悠垛。

  • collideConnect
    [首次設置有效]兩個剛體是否可以發(fā)生碰撞,默認為false逆航。(截圖為true注意不要混淆)

官方的例子也很好理解鼎文,如果設置其中一個kinematic,不受重力影響因俐,就會固定在一點拇惋,成為一個鐘擺;如果都是動態(tài)的抹剩,則會掉下來撑帖,看起來像是自行車的兩個輪子。

3.MouseJoint鼠標關節(jié)
可以點擊剛體澳眷,然后把它拖走胡嘿。拖走之后,不松鼠標钳踊,停下來時衷敌,能看到鼠標吸附在剛體的那個位置,它就是anchor屬性拓瞪,表示關節(jié)的鏈接點缴罗。這是一個x,y屬性值 ,表示相對于自身剛體左上角的位置偏移祭埂,如果不設置則鼠標點到剛體哪里面氓,連接點就是哪里。注意這個值是laya坐標值蛆橡。

override protected function _createJoint():void {
    if (!_joint) {
        selfBody ||= owner.getComponent(RigidBody);
        if (!selfBody) throw "selfBody can not be empty";
        
        var box2d:* = window.box2d;
        var def:* = _temp || (_temp = new box2d.b2MouseJointDef());
        if (anchor) {
            var anchorPos:Point = Sprite(selfBody.owner).localToGlobal(
                Point.TEMP.setTo(anchor[0], anchor[1]), false, Physics.I.worldRoot);
        } else {
            anchorPos = Physics.I.worldRoot.globalToLocal(
                Point.TEMP.setTo(Laya.stage.mouseX, Laya.stage.mouseY));
        }
        var anchorVec:* = new box2d.b2Vec2(
            anchorPos.x / Physics.PIXEL_RATIO, anchorPos.y / Physics.PIXEL_RATIO);
        def.bodyA = Physics.I._emptyBody;
        def.bodyB = selfBody.getBody();
        def.target = anchorVec;
        def.frequencyHz = _frequency;
        def.damping = _damping;
        def.maxForce = _maxForce;
        _joint = Physics.I._createJoint(def);
    }
}

拉小登博客 讓剛體聽我的——鼠標拖動Box2D剛體使用了b2World世界的QueryPoint方法舌界,來編歷world中所有的剛體,判斷p點是否在剛體上泰演。如果是呻拌,則將剛體對應的b2Fixture傳入到callBack函數(shù)中。然后我可以利用b2Fixture.GetBody()方法獲取剛體睦焕,具體代碼如下:

private function getBodyAtMouse():b2Body
{
    //轉換鼠標坐標單位柏锄,除以30從m該為px
    var mouseVector:b2Vec2 = new b2Vec2(mouseX / 30, mouseY / 30);
    //鼠標下的剛體
    var bodyAtMouse:b2Body = null;
    //queryPoint函數(shù)中要用到的回調(diào)函數(shù)酿箭,注意,它必須有一個b2Fixture參數(shù)
    function callBack(fixture:b2Fixture):void {
        if ( fixture == null) return;
        //如果fixture不為null趾娃,設置為鼠標下的剛體
        bodyAtMouse = fixture.GetBody();
    }
    //利用QueryPoint方法查找鼠標滑過的剛體
    world.QueryPoint(callBack, mouseVector);
    //返回找到的剛體
    return bodyAtMouse;
}

4.RevoluteJoint 旋轉關節(jié)
參考拉小登博客 Box2D 關節(jié)——”馬達關節(jié)” b2RevoluteJoint
注:雖然 拉小登 在說馬達關節(jié),其實在laya中對應的是旋轉關節(jié)缔御。
“馬達關節(jié)”b2RevoluteJoint同樣連接了兩個剛體bodyA和bodyB抬闷。它只有一個節(jié)點anchor,所以兩個剛體都只能圍繞這一個節(jié)點選擇耕突。另外笤成,我們可以在這個節(jié)點anchor位置施加一個作用力maxMotorTorque,這樣節(jié)點就會想馬達一樣轉起來眷茁,所以我把它叫做”馬達關節(jié)”炕泳。還是不好理解,對吧上祈!那就再打個比方培遵,我把b2RevoluteJoint關節(jié)比作….電風扇。風扇葉是bodyA登刺,馬達是anchor籽腕,底座是bodyB,下面的圖可以更好的解釋這一點:

image.png

revoluteJoint.Initialize( bodyA, bodyB, new b2Vec2(posA.x / 30, posA.y / 30));
在LAYA中是這樣封裝的:

//if (!otherBody) throw "otherBody can not be empty";
selfBody ||= owner.getComponent(RigidBody);
if (!selfBody) throw "selfBody can not be empty";

var box2d:* = window.box2d;
var def:* = _temp || (_temp = new box2d.b2RevoluteJointDef());
var anchorPos:Point = Sprite(selfBody.owner).localToGlobal(
    Point.TEMP.setTo(anchor[0], anchor[1]), false, Physics.I.worldRoot);
var anchorVec:* = new box2d.b2Vec2(
    anchorPos.x / Physics.PIXEL_RATIO, anchorPos.y / Physics.PIXEL_RATIO);
def.Initialize(otherBody ? otherBody.getBody() : 
    Physics.I._emptyBody, selfBody.getBody(), anchorVec);
def.enableMotor = _enableMotor;
def.motorSpeed = _motorSpeed;
def.maxMotorTorque = _maxMotorTorque;
def.enableLimit = _enableLimit;
def.lowerAngle = _lowerAngle;
def.upperAngle = _upperAngle;
def.collideConnected = collideConnected;

_joint = Physics.I._createJoint(def);
}

拉小登博客 Box2D如何固定動態(tài)剛體使用旋轉關節(jié)纸俭,實現(xiàn)了一個傳送皮帶的效果皇耗。

5.平移關節(jié)PrismaticJoint
沒什么好說的,anchor是[首次設置有效]關節(jié)的控制點揍很,是相對于自身剛體的左上角位置偏移郎楼。設成1,1會向著右下角移動。

6.GearJoint 齒輪關節(jié):用來模擬兩個齒輪間的約束關系窒悔,齒輪旋轉時呜袁,產(chǎn)生的動量有兩種輸出方式,一種是齒輪本身的角速度蛉迹,另一種是齒輪表面的線速度

齒輪綁定了兩個關節(jié)傅寡,類型必須是RevoluteJoint或者PrismaticJoint。

override protected function _createJoint():void {
    if (!_joint) {
        if (!joint1) throw "Joint1 can not be empty";
        if (!joint2) throw "Joint2 can not be empty";
        
        var box2d:* = window.box2d;
        var def:* = _temp || (_temp = new box2d.b2GearJointDef());
        def.bodyA = joint1.owner.getComponent(RigidBody).getBody();
        def.bodyB = joint2.owner.getComponent(RigidBody).getBody();
        def.joint1 = joint1.joint;
        def.joint2 = joint2.joint;
        def.ratio = _ratio;
        def.collideConnected = collideConnected;
        _joint = Physics.I._createJoint(def);
    }
}

源代碼很少北救,屬性就2個荐操。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市珍策,隨后出現(xiàn)的幾起案子托启,更是在濱河造成了極大的恐慌,老刑警劉巖攘宙,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屯耸,死亡現(xiàn)場離奇詭異拐迁,居然都是意外死亡,警方通過查閱死者的電腦和手機疗绣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門线召,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人多矮,你說我怎么就攤上這事缓淹。” “怎么了塔逃?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵讯壶,是天一觀的道長。 經(jīng)常有香客問我湾盗,道長伏蚊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任格粪,我火速辦了婚禮躏吊,結果婚禮上,老公的妹妹穿的比我還像新娘匀借。我一直安慰自己颜阐,他們只是感情好,可當我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布吓肋。 她就那樣靜靜地躺著凳怨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪是鬼。 梳的紋絲不亂的頭發(fā)上肤舞,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音均蜜,去河邊找鬼李剖。 笑死,一個胖子當著我的面吹牛囤耳,可吹牛的內(nèi)容都是我干的篙顺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼充择,長吁一口氣:“原來是場噩夢啊……” “哼德玫!你這毒婦竟也來了?” 一聲冷哼從身側響起椎麦,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤宰僧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后观挎,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體琴儿,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡段化,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了造成。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片显熏。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖谜疤,靈堂內(nèi)的尸體忽然破棺而出佃延,到底是詐尸還是另有隱情,我是刑警寧澤夷磕,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站仔沿,受9級特大地震影響坐桩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜封锉,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一绵跷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧成福,春花似錦碾局、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蕴潦,卻和暖如春像啼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背潭苞。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工忽冻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人此疹。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓僧诚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蝗碎。 傳聞我的和親對象是個殘疾皇子湖笨,可洞房花燭夜當晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容