文档章节

Box2D关节-距离关节

童年伊梦
 童年伊梦
发布于 2012/09/25 12:51
字数 767
阅读 580
收藏 0

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行中。

© 著作权归作者所有

童年伊梦
粉丝 1
博文 29
码字总数 21736
作品 0
浦东
私信 提问
实例介绍Cocos2d-x中Box2D物理引擎:使用关节

下面我们将使用Box2D物理引擎技术进行重构。使得关节能够掌握如何在Box2D使用关节约束。 HelloWorldScene.cpp中与使用关节的相关代码如下: [html] view plaincopy void HelloWorld::addNewS...

智捷课堂
2014/10/09
0
0
box2d-jquery的b2RevoluteJointDef

学了一天jquery的box2d,demo里的例子基本都还看得懂,可是自己搞了一天都没弄好b2RevoluteJointDef这个关节 网上关于jquery版的又很少,求大神写个小demo参考参考...

L3ve
2013/07/28
599
1
开源的物理引擎

物理引擎 是一种仿真程序,可用来创建一种虚拟环境,在其中集成来自物理世界的规律。在这个虚拟的环境中包括的物体,除了物体之间的相互作用(比如碰撞)外,还包括施加到它们身上的力(比如...

小卒过河
2011/09/07
2.1K
0
Visual Studio 2012下Box2D开发环境设置

Cocos2d-x 3.x默认情况下采用的物理引擎是Chipmunk,如果我们要使用Box2D引擎,需要进行一些设置和调整,而且不同的开发平台下这些设置也有所不同。由于本书在此之前介绍的都是基于微软的Vis...

智捷课堂
2014/10/07
0
0
【iOS-Cocos2d游戏开发之十一】使用Box2d物理系统以及在cocos2d框架添加Box2d物理系统lib包的方法

上一节讲述了粒子的相关问题,当然啦,不示弱,今天继续将物理系统给大家进行简单的介绍和讲述; 首先先介绍,如何在cocos2d中加入box2d开发lib包,因为一般使用cocos2d引擎进行开发游戏时,...

junwong
2012/03/02
1K
0

没有更多内容

加载失败,请刷新页面

加载更多

中奖名单 | “赠书活动”中奖名单公布

在上周的赠书活动中, 小伙伴们踊跃参与! 京小云也很认真地进行了统计, 非常感谢大家的参与和支持! 下面公布中奖的名单~ 请中奖的小伙伴于5个工作日内 在微信公众号后台留下你的联系地址 ...

京东云技术新知
14分钟前
1
0
云原生生态周报 Vol. 11 | K8s 1.16 早知道

业界要闻 Pivotal 发布了完全基于 Kubernetes 的 Pivotal Application Service(PAS)预览版 这意味着 Pivotal 公司一直以来在持续运作的老牌 PaaS 项目 Cloud Foundry (CF)终于得以正式拥...

阿里巴巴云原生
14分钟前
0
0
低版本xcode真机调试iOS 12.3.1

老款mac pro已经升级不了系统了,导致最新版的xcode10.2及以上也安装不了,最新版的ios12.3.1也联机调试不了,apple是要逼着大家升级硬件啊,软件即服务,就是这样来的,大部分计算机软件公司...

swingcoder
14分钟前
4
0
浅谈堆排序

一:定义 堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆排序是一种树形选择排序,在排序过程中可以把元素看成是一颗完全二叉树,每个节点都大(小)于它的两个子...

无名氏的程序员
16分钟前
2
0
Alibaba Cloud Linux 2 开源后又有什么新动作?

阿里妹导读:2019 年 4 月,Alibaba Cloud Linux 2 (Aliyun Linux 2) 正式开源。时至今日,已经走过三个月的里程。在这段时间内,这个刚诞生不久的为阿里云 ECS 环境定制优化的 Linux 操作系...

阿里云官方博客
17分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部