改め Objective Technician

はぐれ技術者のやりたい放題

AS3物理エンジンBox2DのMouseJointで引力/斥力っぽい実装

2009-10-07 20:53:45 | プログラミング


前期にやってた物理シミュレーションの実装バイトが教授に気に入られて後期もやることになったので、これで大手を振って Flash 作りに興じられるようになった。

もっと、Papervision3D とか Tweener とか Box2D とか使い倒してみたい。


Flash で遊ぶ大義名分が立ったところで、物理エンジン Box2D のジョイントまわりをいじってみた。



物体どうしを結びつけるジョイントには、一定距離を保つ、ピン止め回転、ピストン、プーリー、ギア、マウス関連、の6種類が用意されている。





ところで、Box2D が剛体の物理演算ライブラリを名乗るからには、離れて働く力も簡単に扱えるのかと当初は期待してたけど、引力/斥力の類は自分でベクトル計算して b2Body に ApplyForce するしかないらしい。



それなら、代わりに伸び縮みするジョイントがあっても良いような気がするけど、これもない。


ただマウスジョイントというものが、マウスポインタと b2Body とを力で結びつける機能を持っている。


b2MouseJoint は本来 b2Body どうしを結ぶものではないけど、これをむりやり b2Body 同士の双方向に張って互いに引き合うようにするには、こんな↓雰囲気でやればいい。(一方向に張るだけだと張った側に反作用が働かない。)

	private function setJoint():void {
		joint = b2MouseJoint(world.CreateJoint(getMouseJointDef(target)));
		joint2 = b2MouseJoint(world.CreateJoint(getMouseJointDef(body)));
	}
		
	private function getMouseJointDef(obj:b2Body):b2MouseJointDef {

		var mouseJointDef:b2MouseJointDef = new b2MouseJointDef(); 

		mouseJointDef.body1 = world.GetGroundBody();
		mouseJointDef.body2 = obj;
		mouseJointDef.target = obj.GetWorldCenter();             
		mouseJointDef.maxForce = force;			
		mouseJointDef.timeStep = timeStep; 			

		return mouseJointDef;
	}


	private function onEnterFrame(event:Event):void {
		joint.SetTarget(body.GetPosition());
		joint2.SetTarget(target.GetPosition());
	}




試しにこれで適当に作ってみたところ、見た目にはそれっぽい動きをしている。

画像クリックで動きます↓


AS3ソースはこちら


Box2D 側の実装を詳しく見てないからわからないけど、たぶんこれは距離に関係なく一定の力がかかってるから、万有引力とか静電気力とかを表現するとなるとあと少し工夫が必要なはず。



あと、作ってみて気がついたけど、b2Body どうしが密集したときになんか集団がバネらしき動きをしてるので、これを使って弾性体っぽいものが表現できるかもしれない。

最新の画像もっと見る

コメントを投稿