物理エンジンライブラリ Box2DFlashAS3 ジョイント1(回転ジョイント・距離ジョイント)
ジョイントは、物体と物体を繋げて動かしたりもできる機能。
回転・距離・直動・滑車・歯車・マウスの6種類があります。
ここでは、回転ジョイントと距離ジョイントについてのメモ。
回転ジョイント(RevoluteJoint)
- 物体と物体をピンで繋げるようなジョイント。
- ピンを中心にくるくる回る。
- モーターを使って回すことができる。
- 回る角度の制限もできる。
使い方
- 繋げる2つの物体(b2Body)を指定
- 繋げる場所(座標)(b2Vec2)を1ヶ所指定
- ジョイントの性質(b2RevoluteJointDef)を設定(モーター使用・角度制限等)/li>
- ジョイントの初期化→ジョイント登録
距離ジョイント(DistanceJoint)
- 物体と物体をロープで繋げるようなジョイント。
- ロープに引っ張られながらそれぞれ勝手に動く。
- 繋ぐ場所が2箇所あるのが、回転ジョイントと違う。
使い方
- 繋げる2つの物体(b2Body)を指定
- 繋げる場所(座標)(b2Vec2)を2ヶ所指定
- ジョイントの性質(b2DistanceJointDef)を設定(振動数?均衡等??ここの設定はわからないです...。)/li>
- ジョイントの初期化→ジョイント登録
サンプルコード
※Box2Dのまとめたクラス(Box2DBase)を作って、基本クラスで使ってます。ソースは物理エンジンライブラリ Box2DFlashAS3(基本)にあります。
Actionscript:
-
public class StudyB2Joint1 extends B2Base
-
{
-
private var m_screen_width:int = 600;
-
private var m_screen_height:int = 500;
-
-
//ぐるぐるきのこ
-
private var m_b2_guru_kinoko1:b2Body;
-
private var m_b2_guru_kinoko2:b2Body;
-
private var m_b2_guru_kinoko3:b2Body;
-
private var m_b2_guru_kinoko4:b2Body;
-
-
//ゆらゆら棒
-
private var m_b2_yura_bar:b2Body;
-
private var m_b2_yura_kinoko1:b2Body;
-
private var m_b2_yura_kinoko2:b2Body;
-
-
//表示用のMCを入れる
-
private var m_display_blocks:Sprite;
-
-
//落ちてくるきのこ発生装置
-
private var m_kinokoL:Sprite;
-
private var m_kinokoS:Sprite;
-
-
public function StudyB2Joint1() : void{
-
-
super(24, 10, 10);
-
-
//表示用設定
-
this.m_display_blocks = new Sprite;
-
this.addChild(m_display_blocks);
-
-
this.makeGake(); //ガケ作成
-
-
//橋(距離ジョイント)
-
this.makeBridge();
-
-
//ぐるぐるきのこ(回転ジョイント+距離ジョイント)
-
this.makeGuruguruKinoko();
-
-
//ゆらゆら棒(回転ジョイント+距離ジョイント)
-
this.makeYurayuraBar();
-
-
this.initKinokoS(); //小さいきのこ
-
this.initKinokoL(); //大きいきのこ
-
-
//this.setDebugDraw();
-
-
this.addEventListener(Event.ENTER_FRAME, this.update, false, 0, true);
-
}
-
-
//ガケ作成
-
private function makeGake():void {
-
-
this.makeB2BodyBox(120, 120, 60, 440, 0, 0, 0.5, 0.5);
-
this.makeB2BodyBox(120, 120, 540, 440, 0, 0, 0.5, 0.5);
-
-
}
-
-
//橋(真ん中のやつ)作成
-
//:距離Joint
-
private function makeBridge():void {
-
-
var x:Number;
-
var y:Number = 390;
-
var i:int; //カウンタ
-
-
var rack:b2Body = this.m_b2_world.GetGroundBody(); //橋の岸
-
-
var boards:Array = new Array();
-
-
//橋の板
-
for (i = 0; i <= 5; i++){
-
x = i * 60 + 150; //配置場所X
-
var borad_display:Sprite = new board_60_mc as Sprite; //橋板(表示用)
-
var board:b2Body = this.makeB2BodyBox(60, 10, x, y, 0, 1, 1.5, 0.5, borad_display, m_display_blocks);
-
boards[i] = board;
-
}
-
-
//Joint
-
var body1:b2Body; //距離Joint 繋ぐ物体1つ目
-
var body2:b2Body; //距離Joint 繋ぐ物体2つ目
-
var anc1:b2Vec2; //距離Joint 繋ぎ場所1つ目
-
var anc2:b2Vec2; //距離Joint 繋ぎ場所2つ目
-
-
var dj_def:b2DistanceJointDef; //距離Joint
-
-
-
//左岸と板
-
x = 120; //繋げる場所
-
-
body1 = rack;
-
body2 = boards[0];
-
anc1 = this.createB2Vec(x - 5, y);
-
anc2 = this.createB2Vec(x + 5, y);
-
dj_def = new b2DistanceJointDef();
-
//dj_def.length = 0;
-
dj_def.Initialize(body1, body2, anc1, anc2);
-
-
this.m_b2_world.CreateJoint(dj_def);
-
-
//板と板
-
for (i = 0; i <= 4; i++){
-
-
//板の左側を繋げる
-
x = (i * 60) + 210; //繋げる場所
-
-
body1 = boards[i];
-
body2 = boards[i + 1];
-
anc1 = this.createB2Vec(x - 5, y);
-
anc2 = this.createB2Vec(x + 5, y);
-
dj_def = new b2DistanceJointDef();
-
dj_def.Initialize(body1, body2, anc1, anc2);
-
-
this.m_b2_world.CreateJoint(dj_def);
-
}
-
-
//板と右岸
-
//板の右側を繋げる
-
x = 510; //繋げる場所
-
-
body1 = boards[5];
-
body2 = rack;
-
anc1 = this.createB2Vec(x - 5, y);
-
anc2 = this.createB2Vec(x + 5, y);
-
dj_def = new b2DistanceJointDef();
-
dj_def.Initialize(body1, body2, anc1, anc2);
-
-
this.m_b2_world.CreateJoint(dj_def);
-
}
-
-
-
//ぐるぐるきのこ(左側のポールに繋がってる回ってる円盤)作成
-
//:回転ジョイント+距離ジョイント
-
private function makeGuruguruKinoko():void {
-
-
//表示用
-
var kinoko1_display:kinoko_kurukuru_green_mc = new kinoko_kurukuru_green_mc;
-
var kinoko2_display:kinoko_kurukuru_red_mc = new kinoko_kurukuru_red_mc;
-
var kinoko3_display:kinoko_kurukuru_yellow_mc = new kinoko_kurukuru_yellow_mc;
-
var kinoko4_display:kinoko_kurukuru_green_mc = new kinoko_kurukuru_green_mc;
-
kinoko2_display.width = 30;
-
kinoko2_display.height = 30;
-
kinoko4_display.width = 30;
-
kinoko4_display.height = 30;
-
-
//位置
-
var bura_x:int = 150;
-
var bura_y:int = 100;
-
-
var kinoko1:b2Body = this.makeB2BodyCircle(60, bura_x, bura_y, 1, 0.5, 0.5, kinoko1_display, this.m_display_blocks);
-
var kinoko2:b2Body = this.makeB2BodyCircle(30, bura_x, bura_y + 90, 1, 0.5, 0.5, kinoko2_display, this.m_display_blocks);
-
var kinoko3:b2Body = this.makeB2BodyCircle(30, bura_x, bura_y + 180, 1, 0.5, 0.5, kinoko3_display, this.m_display_blocks);
-
var kinoko4:b2Body = this.makeB2BodyCircle(30, bura_x, bura_y + 270, 1, 0.5, 0.5, kinoko4_display, this.m_display_blocks);
-
-
-
//回転ジョイント
-
-
//きのこ1はぐるぐる回る
-
var rj_def:b2RevoluteJointDef = new b2RevoluteJointDef;
-
rj_def.enableMotor = true;
-
rj_def.motorSpeed = 2.0;
-
rj_def.maxMotorTorque = 300000;
-
-
rj_def.Initialize(this.m_b2_world.GetGroundBody(), kinoko1, kinoko1.GetPosition());
-
this.m_b2_world.CreateJoint(rj_def);
-
-
//距離ジョイント
-
-
//きのこ1と2(回るきのこ1の中心からずれた位置ときのこ2の中心を繋ぐ)
-
var anc1:b2Vec2 = this.createB2Vec(bura_x + 20, bura_y); //
-
-
var dj_def1:b2DistanceJointDef = new b2DistanceJointDef;
-
dj_def1.Initialize(kinoko1, kinoko2, anc1, kinoko2.GetPosition());
-
this.m_b2_world.CreateJoint(dj_def1);
-
-
//きのこ2と3(中心同士で繋ぐ)
-
var dj_def2:b2DistanceJointDef = new b2DistanceJointDef;
-
dj_def2.Initialize(kinoko2, kinoko3, kinoko2.GetPosition(), kinoko3.GetPosition());
-
this.m_b2_world.CreateJoint(dj_def2);
-
-
//きのこ3と4(中心同士で繋ぐ)
-
var dj_def3:b2DistanceJointDef = new b2DistanceJointDef;
-
dj_def2.Initialize(kinoko3, kinoko4, kinoko3.GetPosition(), kinoko4.GetPosition());
-
this.m_b2_world.CreateJoint(dj_def2);
-
-
//後から使えるように
-
this.m_b2_guru_kinoko1 = kinoko1;
-
this.m_b2_guru_kinoko2 = kinoko2;
-
this.m_b2_guru_kinoko3 = kinoko3;
-
this.m_b2_guru_kinoko4 = kinoko4;
-
}
-
-
-
//ゆらゆら棒(右側のポールに繋がってるモビールっぽいやつ)作成:回転ジョイント+距離ジョイント
-
private function makeYurayuraBar():void {
-
-
//表示用
-
var bar_display:board_100_mc = new board_100_mc;
-
var kinoko1_display:kinoko_kurukuru_yellow_mc = new kinoko_kurukuru_yellow_mc;
-
var kinoko2_display:kinoko_kurukuru_red_mc = new kinoko_kurukuru_red_mc;
-
kinoko1_display.width = 40;
-
kinoko1_display.height = 40;
-
kinoko2_display.width = 40;
-
kinoko2_display.height = 40;
-
-
var yura_x:int = 450;
-
var yura_y:int = 100;
-
-
var bar:b2Body = this.makeB2BodyBox(100, 10, yura_x, yura_y, 0, 1, 0.5, 0.5, bar_display, this.m_display_blocks); //棒
-
var kinoko1:b2Body = this.makeB2BodyCircle(40, yura_x + 100, yura_y + 150, 1, 0.5, 0.5, kinoko1_display, this.m_display_blocks); //きのこ1
-
var kinoko2:b2Body = this.makeB2BodyCircle(40, yura_x - 100, yura_y + 150, 1, 0.5, 0.5, kinoko2_display, this.m_display_blocks); //きのこ2
-
-
//回転ジョイント ゆれる棒
-
var rj_def:b2RevoluteJointDef = new b2RevoluteJointDef;
-
rj_def.enableLimit = true; //角度制限付ける
-
rj_def.lowerAngle = -30 * Math.PI / 180;
-
rj_def.upperAngle = 30 * Math.PI / 180;
-
-
rj_def.Initialize(this.m_b2_world.GetGroundBody(), bar, bar.GetPosition());
-
this.m_b2_world.CreateJoint(rj_def);
-
-
-
//距離ジョイント ゆれる棒ときのこ繋ぐ
-
-
//きのこ1
-
var anc1:b2Vec2 = this.createB2Vec(yura_x + 50, yura_y);
-
-
var dj_def1:b2DistanceJointDef = new b2DistanceJointDef;
-
dj_def1.Initialize(bar, kinoko1, anc1, kinoko1.GetPosition());
-
this.m_b2_world.CreateJoint(dj_def1);
-
-
//きのこ2
-
var anc2:b2Vec2 = this.createB2Vec(yura_x - 50, yura_y);
-
-
var dj_def2:b2DistanceJointDef = new b2DistanceJointDef;
-
dj_def2.Initialize(bar, kinoko2, anc2, kinoko2.GetPosition());
-
this.m_b2_world.CreateJoint(dj_def2);
-
-
//後から使えるように
-
this.m_b2_yura_bar = bar;
-
this.m_b2_yura_kinoko1 = kinoko1;
-
this.m_b2_yura_kinoko2 = kinoko2;
-
}
-
-
-
//演算
-
private function update(e:Event):void{
-
-
var self:StudyB2Joint1 = this;
-
-
//距離ジョイントで繋げてる紐を描く
-
-
//Body位置から描画位置移動する関数
-
var moveTo_Pos:Function = function(graphics:Graphics, body:b2Body, offset_x:Number = 0, offset_y:Number = 0):void {
-
-
var x:Number = body.GetPosition().x * self.m_b2_physcale + offset_x;
-
var y:Number = body.GetPosition().y * self.m_b2_physcale + offset_y;
-
-
graphics.moveTo(x, y);
-
}
-
-
-
//Body位置へ線を引く関数
-
var lineTo_Pos:Function = function(graphics:Graphics, body:b2Body):void {
-
-
var x:Number = body.GetPosition().x * self.m_b2_physcale;
-
var y:Number = body.GetPosition().y * self.m_b2_physcale;
-
-
graphics.lineTo(x, y);
-
}
-
-
this.m_display_blocks.graphics.clear();
-
this.m_display_blocks.graphics.lineStyle(1, 0x9FD06F);
-
-
//ぐるぐるぐきのこ
-
moveTo_Pos(this.m_display_blocks.graphics, this.m_b2_guru_kinoko1);
-
lineTo_Pos(this.m_display_blocks.graphics, this.m_b2_guru_kinoko2);
-
lineTo_Pos(this.m_display_blocks.graphics, this.m_b2_guru_kinoko3);
-
lineTo_Pos(this.m_display_blocks.graphics, this.m_b2_guru_kinoko4);
-
-
-
//ゆらゆら棒
-
//棒は斜めになるので、角度から繋ぐ位置取得
-
var angle:Number = this.m_b2_yura_bar.GetAngle();
-
var offset_x:Number = Math.cos(angle) * 50;
-
var offset_y:Number = Math.sin(angle) * 50;
-
moveTo_Pos(this.m_display_blocks.graphics, this.m_b2_yura_bar, offset_x, offset_y);
-
lineTo_Pos(this.m_display_blocks.graphics, this.m_b2_yura_kinoko1);
-
moveTo_Pos(this.m_display_blocks.graphics, this.m_b2_yura_bar, -offset_x, -offset_y);
-
lineTo_Pos(this.m_display_blocks.graphics, this.m_b2_yura_kinoko2);
-
-
//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 function initKinokoL():void {
-
-
var self:StudyB2Joint1 = this;
-
-
//これはMC配置するだけ
-
var kinoko:kinoko_L_MC = new kinoko_L_MC;
-
kinoko.x = 555;
-
kinoko.y = 350;
-
kinoko.width = 60;
-
kinoko.height = 65;
-
-
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);
-
-
//最初の小さいきのこ配置
-
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:57 (ピンバック)
[...] DFlashAS3 ジョイント1(回転ジョイント・距離ジョイント) http://hokori.net/2009/03/05/box2dflashas3_joint1/ [...]