一博烂、基礎概念
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ā)生彈性偏移
在醫(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é)
通過固定長度的關節(jié)將兩剛體聯(lián)系到一起,使這兩個剛體始終保持一定的距離帜羊。用于木棍咒程,骨骼,彈簧一樣的約束關系讼育。
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,下面的圖可以更好的解釋這一點:
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個荐操。