cocos2dx物理引擎和碰撞检测(二)

这篇文章来讲如何创建物理世界。下面来看:

创建和摧毁物理世界:

//物理世界的重力

b2Vec2 gravity;

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

//创建物理世界

world = new b2World(gravity);

//设置是否允许物体进入休眠状态

world->SetAllowSleeping(true);

//设置是否使用连续物理检测

world->setContinuousPhysics(true);

//摧毁物理世界

delete world;

world = NULL;

上述代码中使用两个函数来设置世界的运转状态:

(1)函数SetAllowSleeping(true)的作用是允许静止的物体进入休眠状态。在休眠状态下的物体将不会再参与物理运算。这是一种提升引擎运算性能的方法。

(2)函数setContinuousPhysics(true)的作用是设置引擎中的物理模拟是否使用连续检测的方式。连续检测的方式将会在更短的时间内进行物理模拟。这意味物理模拟的精度将会提高,同时会降低引擎的运行性能。

让世界运转起来:

物理世界类中用于驱动模拟的函数为Step,调用它时,需要指定一个时间步和一个速度及位置的迭代次数。例如下面代码所示:

//时间步,频率

float32 timeStep = 1.0f/60.0f;

//速度迭代

int32 velocityIterations = 10;

//位置迭代次数

int32 positionIterations = 8;

//驱动函数

myWorld->Step(timeStep,velocityIterations,positionIterations);

 

上述代码只是驱动物理世界执行一个时间步,开发者要将此段代码放在一个能够循环调用的函数当中。在时间步完成之后,我们就能获得物体和关节经过物理模拟后的信息。最常见的情况就是,游戏中的绘制引擎将会得到物体的位置和速度。这样才能更新游戏画面中的角色并渲染它们。但要注意的一点是:虽然驱动物理世界可以在游戏循环的任何地方,但应注意事情发展的先后顺序。另外,在物理引擎执行了一次时间步之后,最好是清除任何施加到物体之上的力。可以使用b2World::ClearForces去掉力的持续作用效果。

搜索世界(遍历世界):
经过前面的两步,我们已经创建了一个物理世界,然后使用驱动函数使它运转。游戏当中的物理世界就呈现在大家面前了。不过一个空无一物的世界对开发者来说没有意义。因为我们还没有创建物理世界中的对象。创建对象以后再讲,下面介绍的是如何搜索世界中的对象。

物理世界相当于一个容器,它会容纳工厂创建出来的所有对象。开发者可以通过遍历的方式来获取世界中的所有物体、框架和关节。下面这段代码会唤醒世界中的额所有物体:

//遍历物理世界中的物体

for(b2Body* b = myWorld->GetBodyList();b;b = b->GetNext())

{

      //唤醒物体

      b->WakeUp();

}

遍历销毁物体:

b2Body* node = myWorld->GetBodyList();

//遍历物理世界中的物体

while(node)

{

   //获得物体

   b2Body *b = node;

   //获得下一个物体

   node = node->GetNext();

   //获得物体所代表精灵对象

   CCSprite* myActor = (CCSprite*)b->GetUserData();

   //判断精灵对象是否死亡

   if(myActor->IsDead())

   {

   //销毁物体

    myWorld->DestroyBody(b);

    }

}

删除多个物体:

b2Body* node = myWorld->GetBodyList();

while(node)

{

   //获得物体

   b2Body *b = node;

   //获得下一个物体

   node = node->GetNext();

   //获得物体所代表精灵对象

   CCSprite* myActor = (CCSprite*)b->GetUserData();

   //判断精灵对象是否死亡

   if(myActor->IsDead())

   {

   //销毁多个物体

    bool otherBodiesDestroyed = GameCrazyBodyDestroyer(b);

   //重新获得物体指针

       if(otherBodiesDestroyed)

       {

          node = myWorld->GetBodyList();

       }

    }

}


 

这里新增一个函数GameCrazyBodyDestroyer。它将会删除多个物理引擎中的物体。在删除操作之后,代码又重新调用了函数GetBodyList,这样就会重新获得物体链表的开始指针,因此就算删除多个物体,链表依旧没有被打断。还有另一种方法是将需要删除的物体暂存在一个临时容器当中,等物体链表遍历完成之后,就可以删除临时容器中的物体了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值