Box2D試作:間接Drag 範囲内にあるものをジョイントしてドラッグするテスト o_healer forked:1favorite:16lines:244license : MIT License modified : 2011-02-10 21:19:15 Embed Tweet package { import flash.display.*; import flash.events.*; import flash.filters.*; import flash.geom.*; import flash.net.*; import flash.system.*; import flash.text.*; //Box2D import Box2D.Dynamics.*; import Box2D.Collision.*; import Box2D.Collision.Shapes.*; import Box2D.Common.*; import Box2D.Common.Math.*; import Box2D.Dynamics.Joints.*; [SWF(width="465", height="465", frameRate="30", backgroundColor="0x000000")] public class GameMain extends Sprite { //==Const== //画面サイズ static public const VIEW_W:int = 465; static public const VIEW_H:int = 465; //重力 static public const GRAVITY:Number = 0.0; //Box2Dと実際の表示の比率(Box2Dに大きすぎる値を入れると上手く動かなかったりする) static public const PHYS_SCALE:Number = 10; static public function PHYS_to_IMAGE(in_Val:Number):Number{return in_Val * PHYS_SCALE;} static public function IMAGE_to_PHYS(in_Val:Number):Number{return in_Val / PHYS_SCALE;} //Box2Dの画面外の余白 static public const BOX2D_RANGE_OFFSET:int = 100; //効果範囲 static public const EFFECT_RANGE:Number = VIEW_W/8; //==Var== //Box2D public var m_Box2D_World:b2World; //マウスで動かせる球 public var m_MouseBallBody:b2Body; public var m_MouseJoint:b2MouseJoint; //エフェクト用Graphics public var m_EffectGraphics:Graphics; //マウス用フラグ public var m_MouseDown_Now:Boolean = false; public var m_MouseDown_Old:Boolean = false; //==Function== //Init public function GameMain(){ //Box2D { //考慮する領域 var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(IMAGE_to_PHYS(-BOX2D_RANGE_OFFSET), IMAGE_to_PHYS(-BOX2D_RANGE_OFFSET)); worldAABB.upperBound.Set(IMAGE_to_PHYS(VIEW_W+BOX2D_RANGE_OFFSET), IMAGE_to_PHYS(VIEW_H+BOX2D_RANGE_OFFSET)); //重力ベクトル var gravity:b2Vec2 = new b2Vec2(0.0, GRAVITY); //Sleep var useSleep:Boolean = true; //物理world m_Box2D_World = new b2World(worldAABB, gravity, useSleep); } //Effect { var eff_sprite:Sprite = new Sprite(); m_EffectGraphics = eff_sprite.graphics; addChild(eff_sprite); } //Mouse { CreateCollision_MouseSphere( 10 ); } //周囲 { //D CreateCollision_Box( VIEW_W/2,//X VIEW_H - 5,//Y VIEW_W,//W 10,//H 0,//Rot true//IsFix ); //U CreateCollision_Box( VIEW_W/2,//X 5,//Y VIEW_W,//W 10,//H 0,//Rot true//IsFix ); //L CreateCollision_Box( 5,//X VIEW_H/2,//Y 10,//W VIEW_H,//H 0,//Rot true//IsFix ); //R CreateCollision_Box( VIEW_W - 5,//X VIEW_H/2,//Y 10,//W VIEW_H,//H 0,//Rot true//IsFix ); } //ブロック { for(var x:int = 1; x < 8; x++){ for(var y:int = 1; y < 8; y++){ CreateCollision_Box( VIEW_W*x/8,//X VIEW_H*y/8,//Y VIEW_W/16,//W VIEW_W/16//H ); } } } //Update { addEventListener(Event.ENTER_FRAME, Update); } //Mouse { stage.addEventListener(MouseEvent.MOUSE_DOWN, function(e:Event):void{m_MouseDown_Now = true;}); stage.addEventListener(MouseEvent.MOUSE_UP, function(e:Event):void{m_MouseDown_Now = false;}); } } //Create : Collision : Box public function CreateCollision_Box(in_X:int, in_Y:int, in_W:int, in_H:int, in_Rot:Number = 0, in_FixFlag:Boolean = false):void{ //Image var sprite:Sprite; { sprite = new Sprite(); sprite.graphics.beginFill(0xDDDDDD); sprite.graphics.drawRect(-in_W/2, -in_H/2, in_W, in_H); sprite.graphics.endFill(); addChild(sprite); } //Shape Def var shapeDef:b2PolygonDef; { shapeDef = new b2PolygonDef(); shapeDef.SetAsBox(IMAGE_to_PHYS(in_W/2), IMAGE_to_PHYS(in_H/2)); if(in_FixFlag){ shapeDef.density = 0;//Fix }else{ shapeDef.density = 0.01;//tekitou } } //Body Def var bodyDef:b2BodyDef; { bodyDef = new b2BodyDef(); bodyDef.position.Set(IMAGE_to_PHYS(in_X), IMAGE_to_PHYS(in_Y)); bodyDef.angle = in_Rot; } //Body var body:b2Body; { body = m_Box2D_World.CreateBody(bodyDef); body.CreateShape(shapeDef); body.SetMassFromShapes(); body.m_userData = sprite; } } //Create : Collision : Sphere for Mouse public function CreateCollision_MouseSphere(in_R:int):void{ //Image var sprite:Sprite; { sprite = new Sprite(); sprite.graphics.beginFill(0xDDDDDD); sprite.graphics.drawCircle(0,0, in_R); sprite.graphics.endFill(); addChild(sprite); } //Shape Def var shapeDef:b2CircleDef; { shapeDef = new b2CircleDef(); shapeDef.radius = IMAGE_to_PHYS(in_R); shapeDef.density = 1;//tekitou } //Body Def var bodyDef:b2BodyDef; { bodyDef = new b2BodyDef(); bodyDef.position.Set(IMAGE_to_PHYS(VIEW_W/2), IMAGE_to_PHYS(VIEW_H/2)); } //Body var body:b2Body; { body = m_Box2D_World.CreateBody(bodyDef); body.CreateShape(shapeDef); body.SetMassFromShapes(); body.m_userData = sprite; } //Joint { var mjd:b2MouseJointDef = new b2MouseJointDef(); mjd.body1 = m_Box2D_World.GetGroundBody(); mjd.body2 = body; //mjd.target.Set(IMAGE_to_PHYS(mouseX), IMAGE_to_PHYS(mouseY)); mjd.target.Set(bodyDef.position.x, bodyDef.position.y); mjd.maxForce = 300.0 * body.GetMass(); mjd.timeStep = 1.0/30.0; m_MouseJoint = m_Box2D_World.CreateJoint(mjd) as b2MouseJoint; } m_MouseBallBody = body; } //Update public function Update(e:Event=null):void{ //今回進める時間 var DeltaTime:Number = 1.0/30.0; //物理まわりの更新 Update_Phys(DeltaTime); //リンクまわりの更新 Update_Link(); } //物理まわりの更新 public function Update_Phys(in_DeltaTime:Number):void{ //マウスのところに移動 m_MouseJoint.SetTarget(new b2Vec2(IMAGE_to_PHYS(mouseX), IMAGE_to_PHYS(mouseY))); //物理エンジンをDeltaTimeだけ進める m_Box2D_World.Step(in_DeltaTime, 10); // for(var b:b2Body = m_Box2D_World.m_bodyList; b; b = b.m_next){ //画像との同期 if(b.m_userData != null){ var sprite:Sprite = b.m_userData as Sprite; sprite.x = PHYS_to_IMAGE(b.GetPosition().x); sprite.y = PHYS_to_IMAGE(b.GetPosition().y); //b.m_userData.m_VX = PHYS_to_IMAGE(b.m_linearVelocity.x); //b.m_userData.m_VY = PHYS_to_IMAGE(b.m_linearVelocity.y); sprite.rotation = b.GetAngle() * 180/Math.PI; } //擬似摩擦 { const Ratio:Number = 0.95;//本当はDeltaTime依存の値にした方が良い b.GetLinearVelocity().x *= Ratio; b.GetLinearVelocity().y *= Ratio; b.SetAngularVelocity(b.GetAngularVelocity() * Ratio); } } } //リンクわりの更新 public function Update_Link():void{ var j:b2Joint; var BallX:Number = PHYS_to_IMAGE(m_MouseBallBody.GetPosition().x); var BallY:Number = PHYS_to_IMAGE(m_MouseBallBody.GetPosition().y); if(m_MouseDown_Now){ //まだリンクしていなければリンク処理 if(m_MouseDown_Old != m_MouseDown_Now){ for(var b:b2Body = m_Box2D_World.m_bodyList; b; b = b.m_next){ if(b == m_MouseBallBody){continue;}//自分自身はリンクしない if(b.IsStatic()){continue;}//固定されているものはリンクしない var GapX:Number = PHYS_to_IMAGE(b.GetPosition().x - m_MouseBallBody.GetPosition().x); var GapY:Number = PHYS_to_IMAGE(b.GetPosition().y - m_MouseBallBody.GetPosition().y); var Len:Number = Math.sqrt(GapX*GapX + GapY*GapY); if(Len <= EFFECT_RANGE){ var jointDef:b2DistanceJointDef = new b2DistanceJointDef(); jointDef.Initialize(b, m_MouseBallBody, b.GetWorldCenter() , m_MouseBallBody.GetWorldCenter()); m_Box2D_World.CreateJoint(jointDef); } } } //リンクの可視化 { m_EffectGraphics.clear(); m_EffectGraphics.lineStyle(3, 0x00FFFF, 1.0); for(j = m_Box2D_World.GetJointList(); j; j = j.m_next){ if(j == m_MouseJoint){continue;}//マウスとの接続は可視化しない m_EffectGraphics.moveTo(PHYS_to_IMAGE(j.GetAnchor1().x), PHYS_to_IMAGE(j.GetAnchor1().y)); m_EffectGraphics.lineTo(PHYS_to_IMAGE(j.GetAnchor2().x), PHYS_to_IMAGE(j.GetAnchor2().y)); } } }else{ //以前にリンクしていたなら切断 if(m_MouseDown_Old != m_MouseDown_Now){ for(j = m_Box2D_World.GetJointList(); j; ){ if(j == m_MouseJoint){j = j.m_next; continue;} var jj:b2Joint = j.m_next; m_Box2D_World.DestroyJoint(j); j = jj; } } //効果範囲の可視化 { m_EffectGraphics.clear(); m_EffectGraphics.lineStyle(3, 0x00FFFF, 1.0); m_EffectGraphics.drawCircle(BallX,BallY, EFFECT_RANGE); } } m_MouseDown_Old = m_MouseDown_Now; } } } Code Fullscreen Preview Fullscreen BunBunBun Albert s.aszmann civet Indyaner2 kacchan6 bradsedito hacker_xdv5g.. xor djankey zendenmushi matacat andrewexex88.. qwertyui : CODE zmaxlin : Box2d onur : box2d Box2d CODE GetPosition b2Body GetJointList b2BodyDef GetLinearVelocity GetAnchor1 GetAnchor2 density b2Joint m_next m_userData b2DistanceJointDef m_bodyList b2MouseJoint b2MouseJointDef SetMassFromShapes CreateShape b2CircleDef GetAngularVelocity CreateJoint sort new page view favorite forked pv320 forked from: Box2D試作:間接Drag tepe forked:0 favorite:2lines:244 (diff:2)