Box2D关节-距离关节

Box2D joints: Distance Jointby Emanuele Feronato

Box2D中的关节有6种类型:

  • 1.距离关节

距离关节是最简单的关节之一,它描述了两个物体上的两个点之间的距离应该是常量。当你指定一个距离关节时,两个物体必须已在应有的位置上。随后,你指定两个世界坐标中的锚点。第一个锚点连接到物体 1,第二个锚点连接到物体 2。这些点隐含了距离约束的长度。

var jointDef:b2DistanceJointDef = new b2DistanceJointDef();
jointDef.Initialize(bA:b2Body, bB:b2Body, anchorA:b2Vec2, anchorB:b2Vec2);
jointDef.collideConnected = true;


  • 2.旋转关节

  • 3.移动关节

  • 4.滑轮关节

  • 5.齿轮关节

  • 6.鼠标关节

    这节研究学习下距离关节。我们可以把距离关节看成是一个无质量的刚性棒。

    package
    {
        import Box2D.Collision.b2AABB;
        import Box2D.Collision.Shapes.b2CircleShape;
        import Box2D.Collision.Shapes.b2PolygonShape;
        import Box2D.Common.Math.b2Vec2;
        import Box2D.Collision.Shapes.b2Shape;
        import Box2D.Dynamics.b2DebugDraw;
        import Box2D.Dynamics.b2World;
        import Box2D.Dynamics.b2Body;
        import Box2D.Dynamics.b2BodyDef;
        import Box2D.Dynamics.b2FixtureDef;
        import Box2D.Dynamics.b2Fixture;
        import Box2D.Dynamics.Joints.b2DistanceJoint;
        import Box2D.Dynamics.Joints.b2DistanceJointDef;
        import Box2D.Dynamics.Joints.b2MouseJoint;
        import Box2D.Dynamics.Joints.b2MouseJointDef;
        import flash.display.Sprite;
        import flash.events.Event;
        import flash.events.MouseEvent;
                                                                                                                      
        /**
         * ...
         * @author  Childhood
         */
        public class Main extends Sprite 
        {
            private var world:b2World;
            private var worldScale:uint = 30;
            private var mouseJoint:b2MouseJoint;
            private var mousePVec2:b2Vec2 = new b2Vec2();
            private var mouseXWorldPhys:Number; //鼠标在物理世界中的x坐标
            private var mouseYWorldPhys:Number; //鼠标在物理世界中的y坐标
                                                                                                                          
            public function Main():void
            {
                if (stage) init();
                else addEventListener(Event.ADDED_TO_STAGE, init);
            }
                                                                                                                          
            private function init(e:Event = null):void
            {
                removeEventListener(Event.ADDED_TO_STAGE, init);
                getStarted();
            }
                                                                                                                          
            private function getStarted():void
            {
                //world setup
                world = new b2World(new b2Vec2(0, 10), true);
                //debugDraw
                debugDraw();
                //addStuff
                addStuff();
                                                                                                                              
                addEventListener(Event.ENTER_FRAME, update, false, 0, true);
                stage.addEventListener(MouseEvent.MOUSE_DOWN, creatMouseJoint);
                stage.addEventListener(MouseEvent.MOUSE_UP, destroyMouseJoint);
            }
                                                                                                                          
            private function creatMouseJoint(e:MouseEvent):void
            {
                var body:b2Body = GetBodyAtMouse();
                if (body) {
                    var mouseJointDef:b2MouseJointDef = new b2MouseJointDef();
                    mouseJointDef.bodyA = world.GetGroundBody();
                    mouseJointDef.bodyB = body;
                    mouseJointDef.target.Set(mouseXWorldPhys, mouseYWorldPhys);
                    mouseJointDef.maxForce = 100 * body.GetMass();
                    mouseJointDef.collideConnected = true;
                    mouseJoint = world.CreateJoint(mouseJointDef) as b2MouseJoint;
                }
            }
                                                                                                                          
            private function GetBodyAtMouse(includeStatic:Boolean = false):b2Body 
            {
                mousePVec2.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);
                var body:b2Body;
                function getBodyCallback(fixture:b2Fixture):Boolean
                {
                    var shape:b2Shape = fixture.GetShape();
                    if (fixture.GetBody().GetType() != b2Body.b2_staticBody||includeStatic)
                    {
                        var inside:Boolean = shape.TestPoint(fixture.GetBody().GetTransform(), mousePVec2);
                        if (inside)
                        {
                            body = fixture.GetBody();
                            return false; 
                        }
                    }
                    return true; 
                }
                world.QueryAABB(getBodyCallback, aabb);
                return body;
            }
                                                                                                                          
            private function destroyMouseJoint(e:MouseEvent):void
            {
                if (mouseJoint) {
                    world.DestroyJoint(mouseJoint);
                    mouseJoint = null;
                }
            }
                                                                                                                          
            private function addStuff():void
            {
                //创建地板
                var groundBodyDef:b2BodyDef = new b2BodyDef();
                groundBodyDef.type = b2Body.b2_staticBody;
                groundBodyDef.position.Set(0, (stage.stageHeight-10)/ worldScale);
                var groundBody:b2Body = world.CreateBody(groundBodyDef);
                var groundShape:b2PolygonShape = new b2PolygonShape();
                groundShape.SetAsBox(stage.stageWidth/worldScale, 10/worldScale);
                var groundFixtureDef:b2FixtureDef = new b2FixtureDef();
                groundFixtureDef.shape = groundShape;
                var groundFixture:b2Fixture = new b2Fixture();
                groundFixture = groundBody.CreateFixture(groundFixtureDef);
                                                                                                                              
                //创建矩形
                var squareBodyDef:b2BodyDef = new b2BodyDef();
                squareBodyDef.type = b2Body.b2_dynamicBody;
                squareBodyDef.position.Set(100 / worldScale, 100 / worldScale);
                var squareBody:b2Body = world.CreateBody(squareBodyDef);
                var squareShape:b2PolygonShape = new b2PolygonShape();
                squareShape.SetAsBox(50 / worldScale, 50 / worldScale);
                var squareFixtureDef:b2FixtureDef = new b2FixtureDef();
                squareFixtureDef.shape = squareShape;
                squareFixtureDef.density = 1;
                squareFixtureDef.friction = 0.4;
                squareFixtureDef.restitution = 0.1;
                var squareFixture:b2Fixture = squareBody.CreateFixture(squareFixtureDef);
                                                                                                                              
                //创建圆形
                var circleBodyDef:b2BodyDef = new b2BodyDef();
                circleBodyDef.type = b2Body.b2_dynamicBody;
                circleBodyDef.position.Set(210 / worldScale, 100 / worldScale);
                var circleBody:b2Body = world.CreateBody(circleBodyDef);
                var circleShape:b2CircleShape = new b2CircleShape(30 / worldScale);
                var circleFixtureDef:b2FixtureDef = new b2FixtureDef();
                circleFixtureDef.shape = circleShape;
                circleFixtureDef.density = 1;
                circleFixtureDef.friction = 0.4;
                circleFixtureDef.restitution = 0.8;
                var circleFixture:b2Fixture = circleBody.CreateFixture(circleFixtureDef);
                                                                                                                              
                //创建距离关节
                var distanceJointDef:b2DistanceJointDef = new b2DistanceJointDef();
                distanceJointDef.Initialize(circleBody, squareBody, new b2Vec2(210 / worldScale,100 / worldScale), new b2Vec2(100 / worldScale,100 / worldScale));
                distanceJointDef.collideConnected = true;
                var distanceJoint:b2DistanceJoint = world.CreateJoint(distanceJointDef) as b2DistanceJoint;
            }
                                                                                                                          
            private function update(e:Event):void
            {
                world.Step(1 / 30, 10, 10);
                world.DrawDebugData();
                world.ClearForces();
                updateMouseWorldPhy();     //更新鼠标在物理世界中的位置信息
                if (mouseJoint) {
                    var p2:b2Vec2 = new b2Vec2(mouseXWorldPhys, mouseYWorldPhys);
                    mouseJoint.SetTarget(p2);
                }
            }
                                                                                                                          
            private function updateMouseWorldPhy():void
            {
                mouseXWorldPhys = mouseX / worldScale;
                mouseYWorldPhys = mouseY / worldScale;
            }
                                                                                                                          
            private function debugDraw():void
            {
                var debugDraw:b2DebugDraw = new b2DebugDraw();
                var debugSprite:Sprite = new Sprite();
                addChild(debugSprite);
                debugDraw.SetSprite(debugSprite);
                debugDraw.SetLineThickness(1.0);
                debugDraw.SetDrawScale(worldScale);
                debugDraw.SetFillAlpha(0.8);
                debugDraw.SetFlags(b2DebugDraw.e_jointBit | b2DebugDraw.e_shapeBit);
                world.SetDebugDraw(debugDraw);
            }
                                                                                                                          
        }
                                                                                                                      
    }

    其实这篇代码中,也用到了鼠标关节。而距离关节的建立非常简单,集中在代码149-153行中。

你可能感兴趣的:(box2D,关节)