码迷,mamicode.com
首页 > 其他好文 > 详细

瘸腿蛤蟆笔记39-cocos2d-x-3.2 Box2d物理引擎自由落体实现

时间:2014-09-07 13:37:45      阅读:353      评论:0      收藏:0      [点我收藏+]

标签:style   http   color   os   io   使用   ar   strong   文件   

瘸腿蛤蟆原创笔记,欢迎转载,转载请标明出处: 

上篇回顾

本篇名言:烦恼使我受着极大的影响……我一年多没有收到月俸,我和穷困挣扎;我在我的忧患中十分孤独,而且我的忧患是多么多,比艺术使我操心得更厉害! [米开朗基罗]

前段时间蛤蟆出差北京去了,好在中秋节前回来了哈哈。

上篇中,蛤蟆学习了Box2d物理引擎中的Ray-cast代码解释,接下去蛤蟆继续学习其他的Box2d引擎的使用。这次我们使用Box2d物理引擎来学习物理掉落的情况。

        

理论介绍

         本次的理论知识基本和上次RayCast一致,需要补充如下内容:

1.       Body定义变量

结构体b2BodyDef,这个结构体是在b2Body.h头文件中定义的,结构体具体定义如下,有些是带默认变量的。

         b2BodyDef()

         {

                   userData= NULL;

                   position.Set(0.0f,0.0f);

                   angle= 0.0f;

                   linearVelocity.Set(0.0f,0.0f);

                   angularVelocity= 0.0f;

                   linearDamping= 0.0f;

                   angularDamping= 0.0f;

                   allowSleep= true;

                   awake= true;

                   fixedRotation= false;

                   bullet= false;

                   type= b2_staticBody;

                   active= true;

                   gravityScale= 1.0f;

         }

该结构体的作用是,我们创建一个Body的是时候必须要有这个结构体当做参数,然后根据这个结构体的参数创建我们想要的Body。这次我们重点关注下其中的类型。

userData是用于存储应用程序自定义的数据的。

position.Set用于设置Body创建的初始位置。

Angle用于设置Body弧度。

linearVelocity.Set用于设置Body的线速度,默认为0.

angularVelocity用于设置角速度

linearDamping线性阻尼用于减少线性速度,这个值可以设置大于1,但是大于 1 会 导致 阻尼效果会对时间步比较敏感。

angularDamping角速度阻尼用于减少角速度,这个值也不能设置太大,太大会导致 阻尼效果对时间步敏感。

allowSleep 默认是TRUE的,标注Body是否可以睡眠,如果设置FALSE,那么会增加CPU使用率。

awake= true; 标注Body起始时候是否睡眠。

         fixedRotation= false; Body是否可以旋转,默认是FALSE,不能旋转。这个对角色比较有用。

         bullet= false; 这个用于标记是否是快速移动的Body。如果是快速移动的Body,则标记为    True,可以防止穿透其他移动的Body. 这个只能对运动的Body设置,不够会增加CPU处理时间。

                   type= b2_staticBody; type默认是 值是0,就是静态的Body,静态的BODY没有质量,也没有速度,只能通过手动移动。 值 1 ,则是运动的Body, 没有质量,但是有非零的速度(可以被程序员设置),通过解析器来实现移动。值 2 表示  动态的Body,有一个非负的质量,非零的速度(确定于外力),也通过解析器来实现运动。它是个枚举类型,如下表示。

enum b2BodyType

{

                                     b2_staticBody = 0,

                                     b2_kinematicBody,

                                     b2_dynamicBody

};

         active= true; 标记是否是active.

         gravityScale= 1.0f; Body的重力放大系数。

 

 

2.       Fixture定义

Fixture定义是用来创建Fixture的,定义如下:

         b2FixtureDef()

         {

                   shape= NULL;

                   userData= NULL;

                   friction= 0.2f;

                   restitution= 0.0f;

                   density= 0.0f;

                   isSensor= false;

b2Filter filter;

         }

         Shape必须被设置,这个shape会被复制,所以之前的shape变量可以被其他使用。

         userData用来存储应用程序的特定数据

         friction指定摩擦力,通常0到1

         restitution指定回复力。通常0到1

         Density 表示密度

         isSensor表示是否是传感器,如果是传感器,那么会收集信息但是不会对碰撞产生反应。

         Filter过滤接触的DATA

 

 

 

 

 

 

具体步骤

         我们接着使用上次学习的模板,大家可以在 http://download.csdn.net/detail/notbaron/7871237

 中下载这段代码。

1、修改RayCastNew的构造函数如下

RayCastNew()

         {

                   b2Vec2 gravity;

                   gravity.Set(0.0f,-10.0f);

                   m_world= new b2World(gravity);

                   b2Body** bodies = (b2Body**)b2Alloc(3 * sizeof(b2Body*));

                   {

                            b2BodyDef bd;

                            bd.type= b2BodyType(0);

                            bd.position.Set(2.587699890136719e-02f,5.515012264251709e+00f);

                            bd.angle= 0.000000000000000e+00f;

                            bd.linearVelocity.Set(0.000000000000000e+00f,0.000000000000000e+00f);

                            bd.angularVelocity= 0.000000000000000e+00f;

                            bd.linearDamping= 0.000000000000000e+00f;

                            bd.angularDamping= 0.000000000000000e+00f;

                            bd.allowSleep= bool(4);

                            bd.awake= bool(2);

                            bd.fixedRotation= bool(0);

                            bd.bullet= bool(0);

                            bd.active= bool(32);

                            bd.gravityScale= 1.000000000000000e+00f;

                            bodies[0]= m_world->CreateBody(&bd);

 

                            {

                                     b2FixtureDef fd;

                                     fd.friction= 2.000000029802322e-01f;

                                     fd.restitution= 0.000000000000000e+00f;

                                     fd.density= 1.000000000000000e+00f;

                                     fd.isSensor= bool(0);

                                     fd.filter.categoryBits= uint16(1);

                                     fd.filter.maskBits= uint16(65535);

                                     fd.filter.groupIndex= int16(0);

                                     b2PolygonShape shape;

                                     b2Vec2 vs[8];

                                     vs[0].Set(7.733039855957031e-01f,-1.497260034084320e-01f);

                                     vs[1].Set(-4.487270116806030e-01f,1.138330027461052e-01f);

                                     vs[2].Set(-1.880589962005615e+00f,-1.365900039672852e-01f);

                                     vs[3].Set(3.972740173339844e-01f,-3.897832870483398e+00f);

                                     shape.Set(vs,4);

                                     fd.shape= &shape;

                                     bodies[0]->CreateFixture(&fd);

                            }

                   }

                   {

                            b2BodyDef bd;

                            bd.type= b2BodyType(2);

                            bd.position.Set(-3.122138977050781e-02f,7.535382270812988e+00f);

                            bd.angle= -1.313644275069237e-02f;

                            bd.linearVelocity.Set(8.230687379837036e-01f,7.775862514972687e-02f);

                            bd.angularVelocity= 3.705333173274994e-02f;

                            bd.linearDamping= 0.000000000000000e+00f;

                            bd.angularDamping= 0.000000000000000e+00f;

                            bd.allowSleep= bool(4);

                            bd.awake= bool(2);

                            bd.fixedRotation= bool(0);

                            bd.bullet= bool(0);

                            bd.active= bool(32);

                            bd.gravityScale= 1.000000000000000e+00f;

                            bodies[1]= m_world->CreateBody(&bd);

 

                            {

                                     b2FixtureDef fd;

                                     fd.friction= 5.000000000000000e-01f;

                                     fd.restitution= 0.000000000000000e+00f;

                                     fd.density= 5.000000000000000e+00f;

                                     fd.isSensor= bool(0);

                                     fd.filter.categoryBits= uint16(1);

                                     fd.filter.maskBits= uint16(65535);

                                     fd.filter.groupIndex= int16(0);

                                     b2PolygonShape shape;

                                     b2Vec2 vs[8];

                                     vs[0].Set(3.473900079727173e+00f,-2.009889930486679e-01f);

                                     vs[1].Set(3.457079887390137e+00f,3.694039955735207e-02f);

                                     vs[2].Set(-3.116359949111938e+00f,2.348500071093440e-03f);

                                     vs[3].Set(-3.109960079193115e+00f,-3.581250011920929e-01f);

                                     vs[4].Set(-2.590820074081421e+00f,-5.472509860992432e-01f);

                                     vs[5].Set(2.819370031356812e+00f,-5.402340292930603e-01f);

                                     shape.Set(vs,6);

                                     fd.shape= &shape;

                                     bodies[1]->CreateFixture(&fd);

                            }

                   }

                   {

                            b2BodyDef bd;

                            bd.type= b2BodyType(2);

                            bd.position.Set(-7.438077926635742e-01f,6.626811981201172e+00f);

                            bd.angle= -1.884713363647461e+01f;

                            bd.linearVelocity.Set(1.785794943571091e-01f,3.799796104431152e-07f);

                            bd.angularVelocity= -5.908820639888290e-06f;

                            bd.linearDamping= 0.000000000000000e+00f;

                            bd.angularDamping= 0.000000000000000e+00f;

                            bd.allowSleep= bool(4);

                            bd.awake= bool(2);

                            bd.fixedRotation= bool(0);

                            bd.bullet= bool(0);

                            bd.active= bool(32);

                            bd.gravityScale= 1.000000000000000e+00f;

                            bodies[2]= m_world->CreateBody(&bd);

 

                            {

                                     b2FixtureDef fd;

                                     fd.friction= 9.499999880790710e-01f;

                                     fd.restitution= 0.000000000000000e+00f;

                                     fd.density= 1.000000000000000e+01f;

                                     fd.isSensor= bool(0);

                                     fd.filter.categoryBits= uint16(1);

                                     fd.filter.maskBits= uint16(65535);

                                     fd.filter.groupIndex= int16(-3);

                                     b2PolygonShape shape;

                                     b2Vec2 vs[8];

                                     vs[0].Set(1.639146506786346e-01f,4.428443685173988e-02f);

                                     vs[1].Set(-1.639146655797958e-01f,4.428443685173988e-02f);

                                     vs[2].Set(-1.639146655797958e-01f,-4.428443312644958e-02f);

                                     vs[3].Set(1.639146357774734e-01f,-4.428444057703018e-02f);

                                     shape.Set(vs,4);

                                     fd.shape= &shape;

                                     bodies[2]->CreateFixture(&fd);

                            }

                   }

                   GLESDebugDraw * _debugDraw =new GLESDebugDraw(1.5);                  m_world->SetDebugDraw(_debugDraw);

                   uint32 flags = 0;

                   flags+=b2Draw::e_shapeBit;

                   _debugDraw->SetFlags(flags);

                   m_world->DrawDebugData();

                   b2Free(bodies);

                   bodies= NULL;

         }

 

2、修改Step函数如下

void Step(Settings* settings )

         {

                   float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz: float32(0.0f);       

                   m_world->Step(timeStep,settings->velocityIterations, settings->positionIterations);

                   m_world->DrawDebugData(); 

         }

编译运行如下:

代码解释

         这里蛤蟆主要解释两个主要函数,也是主要区别于Ray-Cast的地方,一个是RayCastNew()

 构造函数,一个是Step函数。代码总体上不是很复杂,就是在RayCastNew() 函数中构造了3个Body,然后Step函数会被每帧调用。让我们来具体看下这两个函数吧。

RayCastNew()

         {

                   b2Vec2 gravity;  //定义一个重力向量

                   gravity.Set(0.0f,-10.0f); //设置重力向量为 Y轴 负方向

                   m_world= new b2World(gravity); //通过重力向量创建一个物理世界

                   b2Body** bodies = (b2Body**)b2Alloc(3 * sizeof(b2Body*));//定义BODY数组,这里定义的比较有技巧,大家会照搬能看懂就可以

 

                   {

                            b2BodyDef bd; //定义第一个Body的定义变量

                            bd.type= b2BodyType(0); //定义Body类型为静态Body

                            bd.position.Set(2.587699890136719e-02f,5.515012264251709e+00f); //定义第一个Body的位置

                            bd.angle= 0.000000000000000e+00f; //设置第一个Body角度

                            bd.linearVelocity.Set(0.000000000000000e+00f,0.000000000000000e+00f); //设置第一个Body线速度

                            bd.angularVelocity= 0.000000000000000e+00f; //设置第一个Body线角度

                            bd.linearDamping= 0.000000000000000e+00f; //设置第一个Body线性阻尼

                            bd.angularDamping= 0.000000000000000e+00f; //设置第一个Body角速度阻尼

 

                            bd.allowSleep= bool(4); //设置第一个Body允许睡眠

                            bd.awake= bool(2); //设置第一个Body会激活状态

                            bd.fixedRotation= bool(0); //设置第一个Body不可转动

                            bd.bullet= bool(0); //设置第一个Body不是快速移动Body

                            bd.active= bool(32); //设置第一个Body启动激活

                            bd.gravityScale= 1.000000000000000e+00f; //设置第一个Body的重力放大系数

                            bodies[0]= m_world->CreateBody(&bd); //通过这个Body定义创建第一个Body

 

                            {

                                     b2FixtureDef fd; //定义第一个Body的 Fixture 变量

                                     fd.friction= 2.000000029802322e-01f; //定义第一个Body的摩擦力

                                     fd.restitution= 0.000000000000000e+00f; //定义第一个Body的回复力

                                     fd.density= 1.000000000000000e+00f; //定义第一个Body的密度

                                     fd.isSensor= bool(0); //设置第一个Body不是传感器。

                                     fd.filter.categoryBits= uint16(1);//碰撞目录位,通常设置一位

                                     fd.filter.maskBits= uint16(65535); //

                                     fd.filter.groupIndex= int16(0);// 这三个过滤蛤蟆试了下好像没什么作用

                                     b2PolygonShape shape; //定义变量shape

                                     b2Vec2 vs[8]; //定义坐标数组

                                     vs[0].Set(7.733039855957031e-01f,-1.497260034084320e-01f); //第一个点

                                     vs[1].Set(-4.487270116806030e-01f,1.138330027461052e-01f); //第二个点

                                     vs[2].Set(-1.880589962005615e+00f,-1.365900039672852e-01f); //第三个点

                                     vs[3].Set(3.972740173339844e-01f,-3.897832870483398e+00f); //第四个点

                                     shape.Set(vs,4); //根据4个点,设置shape

                                     fd.shape= &shape; //shape复制给fixture.

                                     bodies[0]->CreateFixture(&fd); //将Fixture绑定到Body[0].

                            }

                   }

                   {

                            b2BodyDef bd; ////定义第二个Body的定义变量

                            bd.type= b2BodyType(2); //定义Body类型为动态Body

                            bd.position.Set(-3.122138977050781e-02f,7.535382270812988e+00f); //设置第二个Body的位置

                            bd.angle= -1.313644275069237e-02f; //设置第二个Body角度

                            bd.linearVelocity.Set(8.230687379837036e-01f,7.775862514972687e-02f); //设置第二个Body线角度

                            bd.angularVelocity= 3.705333173274994e-02f; //设置第二个Body线角度

                            bd.linearDamping= 0.000000000000000e+00f; //设置第二个Body线性阻尼

                            bd.angularDamping= 0.000000000000000e+00f; //设置第二个Body角速度阻尼

 

                            bd.allowSleep= bool(4); //设置第二个Body允许睡眠

                            bd.awake= bool(2); //设置第二个Body会激活状态

                            bd.fixedRotation= bool(0); //设置第二个Body不可转动

                            bd.bullet= bool(0); //设置第二个Body不是快速移动Body

                            bd.active= bool(32); //设置第二个Body启动激活

                            bd.gravityScale= 1.000000000000000e+00f; //设置第二个Body的重力放大系数

                            bodies[1]= m_world->CreateBody(&bd); //通过这个Body定义创建第二个Body

 

                            {

                                     b2FixtureDef fd; //定义第二个Body的 Fixture 变量

                                     fd.friction= 5.000000000000000e-01f; //定义第二个Body的摩擦力

                                     fd.restitution= 0.000000000000000e+00f; //定义第二个Body的回复力

                                     fd.density= 5.000000000000000e+00f; //定义第二个Body的密度

                                     fd.isSensor= bool(0); //设置第二个Body不是传感器。

                                     fd.filter.categoryBits= uint16(1);//碰撞目录位,通常设置一位

                                     fd.filter.maskBits= uint16(65535); //

                                     fd.filter.groupIndex= int16(0);//

                                     b2PolygonShape shape; //定义变量shape

                                     b2Vec2 vs[8]; //定义坐标数组

                                     vs[0].Set(3.473900079727173e+00f,-2.009889930486679e-01f); //

                                     vs[1].Set(3.457079887390137e+00f,3.694039955735207e-02f); //

                                     vs[2].Set(-3.116359949111938e+00f,2.348500071093440e-03f); //

                                     vs[3].Set(-3.109960079193115e+00f,-3.581250011920929e-01f); //

                                     vs[4].Set(-2.590820074081421e+00f,-5.472509860992432e-01f); //

                                     vs[5].Set(2.819370031356812e+00f,-5.402340292930603e-01f); //

                                     shape.Set(vs,6); //根据6个点,设置shape

                                     fd.shape= &shape; ////shape复制给fixture.

                                     bodies[1]->CreateFixture(&fd); //将Fixture绑定到Body[1].

                            }

                   }

                   {

                            b2BodyDef bd; //定义第三个Body的定义变量

                            bd.type= b2BodyType(2); //定义Body类型为动态Body

                            bd.position.Set(-7.438077926635742e-01f,6.626811981201172e+00f); //设置第三个Body的位置

                            bd.angle= -1.884713363647461e+01f; //设置第三个Body角度

                            bd.linearVelocity.Set(1.785794943571091e-01f,3.799796104431152e-07f); //设置第三个Body线角度

                            bd.angularVelocity= -5.908820639888290e-06f; //设置第三个Body线角度

                            bd.linearDamping= 0.000000000000000e+00f; //设置第三个Body线性阻尼

                            bd.angularDamping= 0.000000000000000e+00f; //设置第三个Body角速度阻尼

                            bd.allowSleep= bool(4); //设置第三个Body允许睡眠

                            bd.awake= bool(2); //设置第三个Body会激活状态

                            bd.fixedRotation= bool(0); //设置第三个Body不可转动

                            bd.bullet= bool(0); //设置第三个Body不是快速移动Body

                            bd.active= bool(32); //设置第三个Body启动激活

                            bd.gravityScale= 1.000000000000000e+00f; //设置第三个Body的重力放大系数

                            bodies[2]= m_world->CreateBody(&bd); //通过这个Body定义创建第三个Body

 

                            {

                                     b2FixtureDef fd; //定义第三个Body的 Fixture 变量

                                     fd.friction= 9.499999880790710e-01f; //定义第三个Body的摩擦力

                                     fd.restitution= 0.000000000000000e+00f; //定义第三个Body的回复力

                                     fd.density= 1.000000000000000e+01f; //定义第三个Body的密度

                                     fd.isSensor= bool(0); //设置第三个Body不是传感器。

                                     fd.filter.categoryBits= uint16(1);//碰撞目录位,通常设置一位

                                     fd.filter.maskBits= uint16(65535); //碰撞掩码位,默认是0xFFFF(16进制位)

                                     fd.filter.groupIndex= int16(-3);//设置碰撞组,如果是负数就不会碰撞,如果是正数就会碰撞。如果为0,表示不是会发生碰撞的组。非零组优先级要高于碰撞掩码位。

                                     b2PolygonShape shape; //定义变量shape

                                     b2Vec2 vs[8]; //定义坐标数组

                                     vs[0].Set(1.639146506786346e-01f,4.428443685173988e-02f); //

                                     vs[1].Set(-1.639146655797958e-01f,4.428443685173988e-02f); //

                                     vs[2].Set(-1.639146655797958e-01f,-4.428443312644958e-02f); //

                                     vs[3].Set(1.639146357774734e-01f,-4.428444057703018e-02f); //

                                     shape.Set(vs,4); //根据4个点,设置shape

                                     fd.shape= &shape; //shape复制给fixture.

                                     bodies[2]->CreateFixture(&fd); //将Fixture绑定到Body[2].

                            }

                   }

                   GLESDebugDraw * _debugDraw =new GLESDebugDraw(1.5); //定义一个GLESDebugDraw

                   m_world->SetDebugDraw(_debugDraw); //注册GLESDebugDraw类负责画

                   uint32 flags = 0; //定义变量flags

                   flags+=b2Draw::e_shapeBit; //设置变量flasg,画shape.

                   _debugDraw->SetFlags(flags);//设置需要画的flags.

                   m_world->DrawDebugData();//画这3个Body

                   b2Free(bodies); //释放变量

                   bodies= NULL; //赋值NULL

         }

void Step(Settings* settings )

         {

                   float32 timeStep = settings->hz > 0.0f ? 1.0f / settings->hz: float32(0.0f); //定义一个帧频率变量

                   m_world->Step(timeStep,settings->velocityIterations, settings->positionIterations); //调用Box2d源码中的Step函数。

                   m_world->DrawDebugData();//调用b2Draw类来画物理世界

         }

瘸腿蛤蟆笔记39-cocos2d-x-3.2 Box2d物理引擎自由落体实现

标签:style   http   color   os   io   使用   ar   strong   文件   

原文地址:http://blog.csdn.net/notbaron/article/details/39106099

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!