距離ジョイントを繋げて離す 距離ジョイントを繋げて離す クリックでジョイントが外れる はずれた玉はクリックで飛び跳ねる hokori forked:2favorite:12lines:220license : MIT License modified : 2009-05-13 22:13:33 Embed Tweet //距離ジョイントを繋げて離す //クリックでジョイントが外れる //はずれた玉はクリックで飛び跳ねる package { import Box2D.Collision.b2Bound; import Box2D.Dynamics.b2World; import Box2D.Dynamics.b2Body; import Box2D.Dynamics.b2BodyDef import Box2D.Dynamics.Joints.b2Joint; import Box2D.Dynamics.Joints.b2DistanceJoint; import Box2D.Dynamics.Joints.b2DistanceJointDef; import Box2D.Dynamics.Joints.b2JointEdge; import Box2D.Dynamics.Joints.b2RevoluteJointDef; import Box2D.Collision.b2AABB; import Box2D.Collision.Shapes.b2Shape; import Box2D.Collision.Shapes.b2CircleDef; import Box2D.Collision.Shapes.b2PolygonDef; import Box2D.Common.Math.b2Vec2; import flash.events.MouseEvent; import flash.events.Event; import flash.display.Sprite; import flash.display.Graphics; public class Sample05 extends Sprite { private var m_disp_grp:Sprite; private var m_color:int; public function Sample05() { //Box2D初期設定 this.B2Base(); m_disp_grp = new Sprite(); this.addChild(m_disp_grp); m_color = Math.random() * 0x00FFFF; this.createNoren(50, 0, 1, 15); this.createNoren(250, 0, 1, 10); this.createNoren(450, 0, 1, 15); this.createWalls(); this.addEventListener(Event.ENTER_FRAME, update, false, 0, true); this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true); } //壁と棚作成 private function createWalls():void { //壁作成 this.makeB2BodyBox(500, 10, 250, 0, 0, 0, 0.5, 0.5); this.makeB2BodyBox(500, 10, 250, 500, 0, 0, 0.5, 0.5); this.makeB2BodyBox(10, 500, 0, 250, 0, 0, 0.5, 0.5); this.makeB2BodyBox(10, 500, 500, 250, 0, 0, 0.5, 0.5); //棚作成 var self:Sample05 = this; var make_tana:Function = function(x:int, y:int, w:int, h:int):void { var disp:Sprite = new Sprite(); disp.graphics.beginFill(self.m_color, 0.5); disp.graphics.drawRect( - w / 2, - h / 2, w, h); disp.graphics.endFill(); self.makeB2BodyBox(w, h, x, y, 0, 0 , 0.5, 0.5, disp, self.m_disp_grp); } make_tana(250, 300, 200, 10); make_tana(250, 400, 360, 10); } //距離ジョイントで繋げたものを揺らす private function createNoren(x:int, y:int, set_to:int, num: int):void { var bodies:Array = new Array(); var density:int = 0; for (var i:int = 0; i < num; i++) { var size:int = Math.random() * 10 + 10; var disp:Sprite = new Sprite(); disp.graphics.beginFill(m_color, 1); disp.graphics.drawCircle(0, 0, size); disp.buttonMode = true; disp.addEventListener(MouseEvent.MOUSE_OVER, function(e:MouseEvent):void { e.target.alpha = 0.5; }); disp.addEventListener(MouseEvent.MOUSE_OUT, function(e:MouseEvent):void { e.target.alpha = 1.0; }); var body:b2Body = this.makeB2BodyCircle(size * 2, x, y, density, 0.5, 0.5, disp , m_disp_grp); bodies[i] = body; y += (size + 15) * set_to; density = 1; } //距離ジョイントで繋ぐ for (var j:int = 0; j < num - 1; j++){ var d_joint_def:b2DistanceJointDef = new b2DistanceJointDef(); d_joint_def.collideConnected = true; d_joint_def.Initialize(bodies[j], bodies[j + 1], bodies[j].GetPosition(), bodies[j + 1].GetPosition()); this.m_b2_world.CreateJoint(d_joint_def); } //ちょっと力を加えて動かす bodies[num -1].ApplyForce(new b2Vec2(1000, 0), bodies[num - 1].GetPosition()); } private function onMouseDown(e:MouseEvent):void { var m_x:Number = this.mouseX / this.m_b2_physcale; var m_y:Number = this.mouseY / this.m_b2_physcale; //マウスの下の物体取得 var body:b2Body = this.GetBodyAtMouse(m_x, m_y); if (body is b2Body) { if(body.GetJointList() is b2JointEdge){ //ジョイント繋がってたら、、ジョイントをはずすよ if(body.GetJointList().joint is b2Joint){ this.m_b2_world.DestroyJoint(body.GetJointList().joint); } } else { //ジョイント繋がってなかったら、上に力加える body.ApplyForce(new b2Vec2(0, -5000), body.GetPosition()); } } } //マウスの下の物体取得 //Box2DのTestBedのコピペ private var mousePVec:b2Vec2 = new b2Vec2(); public function GetBodyAtMouse(mouseXWorldPhys:Number, mouseYWorldPhys:Number, includeStatic:Boolean=false):b2Body{ // Make a small box. mousePVec.Set(mouseXWorldPhys, mouseYWorldPhys); var aabb:b2AABB = new b2AABB(); aabb.lowerBound.Set(mouseXWorldPhys - 0.001, mouseYWorldPhys - 0.001); aabb.upperBound.Set(mouseXWorldPhys + 0.001, mouseYWorldPhys + 0.001); // Query the world for overlapping shapes. var k_maxCount:int = 10; var shapes:Array = new Array(); var count:int = m_b2_world.Query(aabb, shapes, k_maxCount); var body:b2Body = null; for (var i:int = 0; i < count; ++i) { if (shapes[i].GetBody().IsStatic() == false || includeStatic) { var tShape:b2Shape = shapes[i] as b2Shape; var inside:Boolean = tShape.TestPoint(tShape.GetBody().GetXForm(), mousePVec); if (inside) { body = tShape.GetBody(); break; } } } return body; } private function update(e:Event):void{ var self:Sample05 = this; this.m_b2_world.Step(this.m_b2_timeStep, this.m_b2_iterations); var disp_gra:Graphics = this.m_disp_grp.graphics; disp_gra.clear(); disp_gra.lineStyle(1, m_color); for (var bb:b2Body = this.m_b2_world.m_bodyList; bb; bb = bb.m_next){ if (bb.m_userData is Sprite){ bb.m_userData.x = bb.GetPosition().x * m_b2_physcale; bb.m_userData.y = bb.GetPosition().y * m_b2_physcale; bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI); } //ジョイントの線 if (bb.m_jointList is b2JointEdge) { for (var joint:b2Joint = bb.m_jointList.joint; joint; joint=joint.m_next){ var anc1:b2Vec2 = joint.GetAnchor1(); var anc2:b2Vec2 = joint.GetAnchor2(); disp_gra.moveTo(anc1.x * this.m_b2_physcale, anc1.y * this.m_b2_physcale); disp_gra.lineTo(anc2.x * this.m_b2_physcale, anc2.y * this.m_b2_physcale); } } } } //----------------------------------------------------------------------------------- //Box2D用まとめ //wonderfl上でクラスを複数置く方法がわからない...。 //----------------------------------------------------------------------------------- protected var m_b2_world:b2World; protected var m_b2_physcale:Number = 10; protected var m_b2_iterations:int = 10; protected var m_b2_timeStep:Number = 24.0; public function B2Base(fps:int = 24, physcale:Number = 10, gravity:Number = 10):void{ this.m_b2_timeStep = 1.0 / fps; this.m_b2_physcale = physcale; this.createB2World(gravity); } private function createB2World(gravity:Number):void { var worldAABB:b2AABB = new b2AABB(); worldAABB.lowerBound.Set(-1000, -1000); worldAABB.upperBound.Set(1000, 1000); var vec_gravity:b2Vec2 = new b2Vec2(0.0, 10.0); var doSleep:Boolean = true; this.m_b2_world = new b2World(worldAABB, vec_gravity, doSleep); } protected function makeB2BodyBox(w:int, h:int, x:Number, y:Number, angle:Number, density:Number, friction:Number, restitution:Number, viewdata:Sprite = null, viewgroup:Sprite = null) :b2Body { var b2_boxdef:b2PolygonDef = this.createB2BoxDef(w, h, density, friction, restitution); var b2_bodydef:b2BodyDef = this.createB2BodyDef(x, y, angle, viewdata, viewgroup); var b2_body:b2Body = this.m_b2_world.CreateBody(b2_bodydef); b2_body.CreateShape(b2_boxdef); b2_body.SetMassFromShapes(); return b2_body; } protected function makeB2BodyCircle(radius:int, x:Number, y:Number, density:Number, friction:Number, restitution:Number, viewdata:Sprite = null, viewgroup:Sprite = null) :b2Body { var b2_boxdef:b2CircleDef = this.createB2CircleDef(radius, density, friction, restitution); var b2_bodydef:b2BodyDef = this.createB2BodyDef(x, y, 0, viewdata, viewgroup); var b2_body:b2Body = this.m_b2_world.CreateBody(b2_bodydef); b2_body.CreateShape(b2_boxdef); b2_body.SetMassFromShapes(); return b2_body; } private function createB2BoxDef(width:int, height:int, density:Number, friction:Number, restitution:Number):b2PolygonDef { var boxdef:b2PolygonDef = new b2PolygonDef(); boxdef.SetAsBox(width / 2 / this.m_b2_physcale, height/ 2 / this.m_b2_physcale); boxdef.density = density; boxdef.friction = friction; boxdef.restitution = restitution; return boxdef; } private function createB2CircleDef(diameter:int, density:Number, friction:Number, restitution:Number):b2CircleDef { var cdef:b2CircleDef = new b2CircleDef(); cdef.radius = diameter / 2 / this.m_b2_physcale; cdef.density = density; cdef.friction = friction; cdef.restitution = restitution; return cdef; } private function createB2BodyDef(x:Number, y:Number, angle:Number, viewdata:Sprite = null, viewgroup:Sprite = null):b2BodyDef { var bodydef:b2BodyDef = new b2BodyDef(); bodydef.position.Set(x / this.m_b2_physcale, y / this.m_b2_physcale); bodydef.angle = (angle / 180) * Math.PI; bodydef.allowSleep = true; if(viewdata != null){ bodydef.userData = viewdata; bodydef.userData.width = viewdata.width; bodydef.userData.height = viewdata.height; if(viewgroup != null){ viewgroup.addChild(bodydef.userData); } } return bodydef; } protected function createB2Vec(x:Number, y:Number):b2Vec2 { var vec:b2Vec2 = new b2Vec2(x / this.m_b2_physcale, y / this.m_b2_physcale); return vec; } } } Code Fullscreen Preview Fullscreen ryogo316 hatiya ongaeshi FlashFit ngtn enoeno dizgid assen_nissen.. abebetaro : Box2D bitrocker : box2d fokhei : box2d darman : Box2Dintractive Box2D Joint intractive density friction b2Vec2 angle b2BodyDef b2PolygonDef userData allowSleep collideConnected Initialize restitution Set SetAsBox beginFill Boolean clear drawRect drawCircle Math.PI endFill sort new page view favorite forked pv250 forked from: 距離ジョイントを繋げて離す amane forked:0 favorite:0lines:220 (diff:1) pv280 forked from: 距離ジョイントを繋げて離す taka_milk forked:0 favorite:0lines:220 (diff:1)