物理エンジンライブラリ Box2DFlashAS3 ジョイント2(直動ジョイント・歯車ジョイント)
直動ジョイントと歯車ジョイント(ギアジョイント)についてのメモ。
サンプルコードでは、回転ジョイントも使ってます。
直動ジョイント(PrismaticJoint)
- 物体がリフトのように一定方向に動くジョイント。
- 軸に沿って一定方向に動く。
- モーターを使って、動かすこともできる。
- 物があたっても回転しない、軸に沿った方向にしか動かない。
使い方
- 繋げる2つの物体(b2Body)を指定
- 繋げる場所(座標)(b2Vec2)を1ヶ所指定
- 軸(座標(ベクトル))(b2Vec2)を1ヶ所指定
- ジョイントの性質(b2PrismaticJointDef)を設定(モーター使用等)
- ジョイントの初期化→ジョイント登録
歯車ジョイント(GearJoint)
- その名の通り、歯車のような働きをするジョイント。
- 繋げたもの同士で、互いの運動量が影響しあう。
- 実際の歯車のように運動方向は逆に伝わるっぽい(右回転→左回転)。
- 繋げた物体の、運動量を合計して、比率を決めて運動量を割り振るっぽい。
- 繋げられるのは、回転ジョイントと直動ジョイントだけ。
使い方
- 繋げる2つの物体(b2Body)を指定(回転ジョイントか直動ジョイントで繋いであるもの)
- 繋げる2つの物体のジョイント(b2Joint)を指定
- ジョイントの性質(b2GearJointDef)を設定(比率等)/li>
- ジョイント登録
サンプルコード
※Box2Dのまとめたクラス(Box2DBase)を作って、基本クラスで使ってます。ソースは物理エンジンライブラリ Box2DFlashAS3(基本)にあります。
Actionscript:
-
public class StudyB2Joint2 extends B2Base
-
{
-
-
private var m_display_blocks:Sprite; //表示用
-
-
public function StudyB2Joint2()
-
{
-
super(24, 10, 10);
-
-
//表示用設定
-
this.m_display_blocks = new Sprite;
-
this.addChild(m_display_blocks);
-
-
//drawGrid(600, 500, 50);
-
-
this.makeGake(); //崖作成
-
-
this.makeLift1(); //左のリフトとぐるぐる円盤(直動ジョイント+回転ジョイント+歯車ジョイント)
-
this.makeLift2(); //真ん中のリフト2つ(直動ジョイント+歯車ジョイント)
-
-
this.makeGuruguru1(); //ぐるぐる円盤(回転ジョイント+歯車ジョイント)
-
-
this.initKinokoL(); //クリックできる大きいきのこ
-
this.initKinokoS(); //降ってくる小さいきのこ
-
-
//this.setDebugDraw();
-
-
this.addEventListener(Event.ENTER_FRAME, update, false, 0, true);
-
}
-
-
-
//崖作成
-
private function makeGake():void {
-
-
//左の崖
-
this.makeB2BodyBox(100, 100, 75, 450, 0, 0, 0.5, 0.5);
-
-
//真ん中の崖2つ
-
//上段
-
this.makeB2BodyBox(100, 150, 250, 225, 0, 0, 0.5, 0.5);
-
this.makeB2BodyBox(100, 150, 525, 225, 0, 0, 0.5, 0.5);
-
//中段
-
this.makeB2BodyBox(25, 100, 212.5, 350, 0, 0, 0.5, 0.5);
-
this.makeB2BodyBox(25, 100, 562.5, 350, 0, 0, 0.5, 0.5);
-
//下段
-
this.makeB2BodyBox(100, 100, 250, 450, 0, 0, 0.5, 0.5);
-
this.makeB2BodyBox(100, 100, 525, 450, 0, 0, 0.5, 0.5);
-
}
-
-
-
//左の崖 上下移動リフトとぐるぐる円盤きのこ
-
//:直動ジョイント+回転ジョイント+歯車ジョイント
-
private var m_b2_lift_ud_body:b2Body;
-
private var m_b2_lift_ud_joint:b2PrismaticJoint;
-
-
private function makeLift1():void {
-
-
//表示用
-
var lift_disp:Sprite = new board_100_mc as Sprite; //リフト
-
var circle_disp:Sprite = new kinoko_kurukuru_red_mc as Sprite; //ぐるぐる回る円盤
-
circle_disp.width = 60;
-
circle_disp.height = 60;
-
-
var ground:b2Body = this.m_b2_world.GetGroundBody();
-
-
//上下するリフト(直動ジョイント)
-
var lift:b2Body = this.makeB2BodyBox(100, 10, 75, 395, 0, 1, 0.5, 0.5, lift_disp, this.m_display_blocks);
-
-
//軸(沿って動く方向)
-
var axis:b2Vec2 = new b2Vec2(0, -1.0); //上垂直方向に
-
-
var pj_def:b2PrismaticJointDef = new b2PrismaticJointDef;
-
pj_def.enableMotor = true; //モーター使う
-
pj_def.maxMotorForce = 30000; //小さいとモーターが進まない
-
pj_def.motorSpeed = 5.0;
-
-
pj_def.Initialize(ground, lift, lift.GetPosition(), axis);
-
var joint1:b2PrismaticJoint = this.m_b2_world.CreateJoint(pj_def) as b2PrismaticJoint;
-
-
this.m_b2_lift_ud_body = lift;
-
this.m_b2_lift_ud_joint = joint1;
-
-
-
//ぐるぐる回るきのこ円(回転ジョイント)
-
var circle:b2Body = this.makeB2BodyCircle(60, 75, 50, 1, 0.5, 0.5, circle_disp, this.m_display_blocks);
-
-
//衝突しないようにする
-
circle.GetShapeList().m_filter.maskBits = 0;
-
-
//回転ジョイント
-
var rj_def:b2RevoluteJointDef = new b2RevoluteJointDef;
-
rj_def.Initialize(ground, circle, circle.GetPosition());
-
-
var joint2:b2Joint = this.m_b2_world.CreateJoint(rj_def);
-
-
-
//歯車ジョイントで繋ぐ(直動ジョイントと歯車ジョイント)
-
var gj_def:b2GearJointDef = new b2GearJointDef();
-
gj_def.body1 = lift;
-
gj_def.body2 = circle;
-
gj_def.joint1 = joint1;
-
gj_def.joint2 = joint2;
-
-
//運動量の比率
-
//0=伝えない 1=同等
-
//1より上=body1の力が大きく伝わる??
-
//1より下(小数点以下)=body2の力が大きく伝わる??
-
//マイナス=力の方向が同じになる
-
gj_def.ratio = 1.0;
-
-
this.m_b2_world.CreateJoint(gj_def);
-
}
-
-
-
//真ん中の崖2つ 左右移動のリスト2つ
-
//:直動ジョイント+歯車ジョイント
-
private var m_b2_lift_lr_body:b2Body;
-
private var m_b2_lift_lr_joint:b2PrismaticJoint;
-
-
private function makeLift2():void {
-
-
//表示用
-
var lift1_disp:Sprite = new board_80_mc as Sprite; //リフト上段
-
var lift2_disp:Sprite = new board_80_mc as Sprite; //リフト下段
-
-
var ground:b2Body = this.m_b2_world.GetGroundBody();
-
-
//左右移動リフト上段(モーターあり)
-
var lift1:b2Body = this.makeB2BodyBox(75, 10, 265.5, 145, 0, 1, 0.5, 0.5, lift1_disp, this.m_display_blocks);
-
-
//軸(沿って動く方向)
-
var axis:b2Vec2 = new b2Vec2(1.0, 0); //右水平方向に
-
-
var pj_def1:b2PrismaticJointDef = new b2PrismaticJointDef;
-
pj_def1.enableMotor = true;
-
pj_def1.maxMotorForce = 30000;
-
pj_def1.motorSpeed = 5.0;
-
-
pj_def1.Initialize(ground, lift1, lift1.GetPosition(), axis);
-
var joint1:b2PrismaticJoint = this.m_b2_world.CreateJoint(pj_def1) as b2PrismaticJoint;
-
-
this.m_b2_lift_lr_body = lift1;
-
this.m_b2_lift_lr_joint = joint1;
-
-
//左右移動リフト下段(モーターなし)
-
var lift2:b2Body = this.makeB2BodyBox(75, 10, 515, 395, 0, 1, 0.5, 0.5, lift2_disp, this.m_display_blocks);
-
-
var pj_def2:b2PrismaticJointDef = new b2PrismaticJointDef;
-
-
pj_def2.Initialize(ground, lift2, lift2.GetPosition(), axis);
-
var joint2:b2Joint = this.m_b2_world.CreateJoint(pj_def2);
-
-
-
//歯車ジョイントで繋ぐ(直動ジョイントと直動ジョイント)
-
var gj_def:b2GearJointDef = new b2GearJointDef();
-
gj_def.body1 = lift1;
-
gj_def.body2 = lift2;
-
gj_def.joint1 = joint1;
-
gj_def.joint2 = joint2;
-
-
//運動量の比率
-
gj_def.ratio = 1.0; //同等に
-
-
this.m_b2_world.CreateJoint(gj_def);
-
}
-
-
-
//真ん中の崖2つ上のぐるぐる円盤きのこ
-
//:回転ジョイント+直動ジョイント
-
private function makeGuruguru1():void {
-
-
//表示用
-
var circle1_disp:Sprite = new kinoko_kurukuru_yellow_mc as Sprite; //ぐるぐる回る円盤1
-
circle1_disp.width = 50;
-
circle1_disp.height = 50;
-
-
var circle2_disp:Sprite = new kinoko_kurukuru_yellow_mc as Sprite; //ぐるぐる回る円盤2
-
circle2_disp.width = 50;
-
circle2_disp.height = 50;
-
-
var ground:b2Body = this.m_b2_world.GetGroundBody();
-
-
//回転ジョイント1(左側)
-
var circle1:b2Body = this.makeB2BodyCircle(50, 212, 50, 1, 0.5, 0.5, circle1_disp, this.m_display_blocks);
-
-
//衝突しないようにする
-
circle1.GetShapeList().m_filter.maskBits = 0;
-
-
var rj_def1:b2RevoluteJointDef = new b2RevoluteJointDef;
-
rj_def1.maxMotorTorque = 30000;
-
rj_def1.enableMotor = true;
-
rj_def1.motorSpeed = 1.0;
-
-
rj_def1.Initialize(ground, circle1, circle1.GetPosition());
-
-
var joint1:b2Joint = this.m_b2_world.CreateJoint(rj_def1);
-
-
//回転ジョイント2(右側)
-
var circle2:b2Body = this.makeB2BodyCircle(50, 565, 50, 1, 0.5, 0.5, circle2_disp, this.m_display_blocks);
-
-
//衝突しないようにする
-
circle2.GetShapeList().m_filter.maskBits = 0;
-
-
var rj_def2:b2RevoluteJointDef = new b2RevoluteJointDef;
-
-
rj_def2.Initialize(ground, circle2, circle2.GetPosition());
-
-
var joint2:b2Joint = this.m_b2_world.CreateJoint(rj_def2);
-
-
-
//歯車ジョイント(回転ジョイントと回転ジョイント)
-
var gj_def:b2GearJointDef = new b2GearJointDef();
-
gj_def.body1 = circle1;
-
gj_def.body2 = circle2;
-
gj_def.joint1 = joint1;
-
gj_def.joint2 = joint2;
-
-
gj_def.ratio = 0.1; //右側の方の運動量を大きく
-
-
this.m_b2_world.CreateJoint(gj_def);
-
}
-
-
-
//演算
-
private function update(e:Event):void{
-
-
//左リフトの上下移動制限
-
var lift_ud_mspeed:int = this.m_b2_lift_ud_joint.GetMotorSpeed();
-
var lift_ud_y:Number = this.m_b2_lift_ud_body.GetPosition().y * this.m_b2_physcale;
-
//上限・下限になったらモーターの方向を逆に
-
if (lift_ud_y>= 390) {
-
if (lift_ud_mspeed <0) {
-
this.m_b2_lift_ud_joint.SetMotorSpeed(lift_ud_mspeed * -1);
-
}
-
}
-
else if (lift_ud_y <= 160) {
-
if (lift_ud_mspeed> 0) {
-
this.m_b2_lift_ud_joint.SetMotorSpeed(lift_ud_mspeed * -1);
-
-
}
-
}
-
//寝てたら起こす
-
if (this.m_b2_lift_ud_body.IsSleeping()) {
-
this.m_b2_lift_ud_body.WakeUp();
-
}
-
-
//真ん中リフトの左右移動制限
-
var lift_lr_mspeed:int = this.m_b2_lift_lr_joint.GetMotorSpeed();
-
var lift_lr_x:Number = this.m_b2_lift_lr_body.GetPosition().x * this.m_b2_physcale;
-
if (lift_lr_x>= 515) {
-
if (lift_lr_mspeed> 0) {
-
this.m_b2_lift_lr_joint.SetMotorSpeed(lift_lr_mspeed * -1);
-
}
-
}
-
else if (lift_lr_x <= 265) {
-
if (lift_lr_mspeed <0) {
-
this.m_b2_lift_lr_joint.SetMotorSpeed(lift_lr_mspeed * -1);
-
}
-
}
-
//寝てたら起こす
-
if (this.m_b2_lift_lr_body.IsSleeping()) {
-
this.m_b2_lift_lr_body.WakeUp();
-
}
-
-
//B2Boxの時間進める
-
this.m_b2_world.Step(this.m_b2_timeStep, this.m_b2_iterations);
-
-
//各B2BoxのBodyの動きにあわせて中のSpriteを動かす
-
for (var bb:b2Body = this.m_b2_world.m_bodyList; bb; bb = bb.m_next){
-
-
var bb_x:Number = bb.GetPosition().x * m_b2_physcale;
-
var bb_y:Number = bb.GetPosition().y * m_b2_physcale;
-
-
//画面外に出て行ったきのこ削除
-
if (bb_x <-100 || bb_x> 700 || bb_y <-100 || bb_y> 600) {
-
this.m_b2_world.DestroyBody(bb);
-
if(bb.m_userData != null){
-
this.m_kinokoS.removeChild(bb.m_userData);
-
bb.m_userData = null;
-
}
-
}
-
-
//演算結果にあわせて表示用データ移動
-
if (bb.m_userData is Sprite){
-
//メートルからピクセル単位に変換
-
bb.m_userData.x = bb_x;
-
bb.m_userData.y = bb_y;
-
bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
-
}
-
}
-
}
-
-
//-----きのこを降らす(ここは、基本と同じもの使用)-----
-
-
//落ちてくるきのこ発生装置
-
private var m_kinokoL:Sprite;
-
private var m_kinokoS:Sprite;
-
-
//大きいきのこ作る
-
private function initKinokoL():void {
-
-
var self:StudyB2Joint2 = this;
-
-
//これはMC配置するだけ
-
var kinoko:kinoko_L_MC = new kinoko_L_MC;
-
kinoko.x = 385;
-
kinoko.y = 227;
-
kinoko.width = 84;
-
kinoko.height = 90;
-
-
kinoko.buttonMode = true;
-
-
kinoko.addEventListener(MouseEvent.MOUSE_OVER,
-
function(e:Event):void {
-
kinoko.gotoAndPlay("frm_hover");
-
});
-
-
kinoko.addEventListener(MouseEvent.MOUSE_UP,
-
function(e:Event):void {
-
kinoko.gotoAndPlay("frm_action");
-
self.makeKinokoS(Math.random() * 550 + 50, 0);
-
});
-
-
this.m_kinokoL = kinoko;
-
-
this.addChild(this.m_kinokoL);
-
-
}
-
-
-
//小さいきのこ入れるのを作って、小さいきのこ配置
-
private function initKinokoS():void {
-
-
//小さいきのこを入れる
-
this.m_kinokoS = new Sprite();
-
this.addChild(this.m_kinokoS);
-
-
//最初の小さいきのこ配置
-
-
//左の崖
-
this.makeKinokoS(50, 0);
-
this.makeKinokoS(100, 0);
-
-
//真ん中の崖のリフトの上に
-
this.makeKinokoS(240, 115);
-
-
this.makeKinokoS(500, 375);
-
/*
-
for (var i:int = 0; i <5 ;i++){
-
this.makeKinokoS(Math.random() * 550 + 50, 0);
-
}
-
*/
-
}
-
-
-
//小さいきのこ作成
-
private function makeKinokoS(x:Number, y:Number):void {
-
-
var kinoko:Sprite;
-
var land = Math.random();
-
-
if (land>= 0.6) {
-
//普通のきのこ
-
kinoko = new kinoko_S1_MC as Sprite;
-
}
-
else if(land>= 0.3){
-
//怪しいきのこ
-
kinoko = new kinoko_S2_MC as Sprite;
-
}
-
else {
-
//しめじ
-
kinoko = new kinoko_S3_MC as Sprite;
-
}
-
-
this.makeB2BodyCircle(30, x, y, 1.0, 0.5, 0.5, kinoko, this.m_kinokoS);
-
}
-
-
}



冷吟閑酔 2009-06-18 06:12:02 (ピンバック)
[...] DFlashAS3 ジョイント2(直動ジョイント・歯車ジョイント) http://hokori.net/2009/03/26/box2dflashas3_joint2/ [...]