cocos2d之Box2D详解 删除物理世界对象

来源:互联网 发布:sma4软件下载 编辑:程序博客网 时间:2024/06/06 00:23

cocos2d之Box2D详解 删除物理世界对象

DionysosLai 2014-5-8

         物理世界对象,有创造,就有销毁。

         通常,我们在更新函数中会这样写到:

void HelloWorld::update(float dt)  {  /// 第一件事情就是调用world对象的step方法,这样它就可以进行物理仿真了。/// 这里的两个参数分别是“速度迭代次数”和“位置迭代次数”--你应该设置他们的范围在8-10之间。(译者:这里的数字越小,/// 精度越小,但是效率更高。数字越大,仿真越精确,但同时耗时更多。8一般是个折中,如果学过数值分析,应该知道迭代步数的具体作用)。world->Step(dt, 10, 10);/// 使我们的精灵匹配物理仿真。for (b2Body *b = world->GetBodyList(); b; b = b->GetNext()){/// 遍历world对象里面的所有body,然后看body的user data属性是否为空,如果不为空,就可以强制转换成精灵对象。接下来,就可以根据body的位置来更新精灵的位置了。if (b->GetUserData() != NULL){CCSprite* ballData = (CCSprite*)b->GetUserData();ballData->setPosition(ccp(b->GetPosition().x*PTM_RATIO, b->GetPosition().y*PTM_RATIO));/// 弧度值转化为角度值 cocos2d里面使用的是角度值,而box2d里面使用的是弧度值。单位不统一,所以需要转化。为什么前面*-1呢?/// 因为cocos2d的角度是顺时针,而box2d是逆时针。ballData->setRotation(-1*CC_RADIANS_TO_DEGREES(b->GetAngle()));}}}

 

在这里,我们做几件事,一是:遍历物理世界中的对象;将物理世界对象数据,转换成我们的数据对象,然后更新对象的位置和旋转度。

如果我们要销毁其中的某个物理世界对象。通常我们会赋予我们的对象一个属性,然后根据这个属性来判断是否要销毁该对象。

如下面代码所示:

m_world->Step(delta, 10, 10);/// 使我们的精灵匹配物理仿真。for (b2Body *b = m_world->GetBodyList(); b; ->GetNext()){if (b->GetUserData() != NULL){ boxSprite* ballData = (boxSprite*) b ->GetUserData();if (ballData->getDead()){m_world->DestroyBody(b);}else{ballData->setPosition(ccp(b ->GetPosition().x*PTM_RATIO, b ->GetPosition().y*PTM_RATIO));          ballData->setRotation(-1*CC_RADIANS_TO_DEGREES(b ->GetAngle()));}}}

Ps:ballData->getDead(),这里的getDead函数,就是我们对对象赋予的一个属性,来说判断我们是否要销毁对象。

        这段代码有个很严重的问题,就是当我们销毁对象时,这个对象的所有信息都将被消除,那么我们将会去不到去下一个节点信息,正确的做法就是要提前获取下一个节点,同时b->GetUserData() == NULL 情况下,我们也要获取下一个节点,修改代码如下:

m_world->Step(delta, 10, 10);/// 使我们的精灵匹配物理仿真。for (b2Body *b = m_world->GetBodyList(); b; ){if (b->GetUserData() != NULL){b2Body* b2node = b;b = b2node->GetNext(); boxSprite* ballData = (boxSprite*)b2node->GetUserData();if (ballData->getDead()){m_world->DestroyBody(b2node);}else{ballData->setPosition(ccp(b2node->GetPosition().x*PTM_RATIO, b2node->GetPosition().y*PTM_RATIO));ballData->setRotation(-1*CC_RADIANS_TO_DEGREES(b2node->GetAngle()));}}else{b = b->GetNext();}}

 

         当然这是一个方法,如果不考虑效率的话,我们通过不修正我们对象的位置信息,我们也可以看起来,就像是将对象销毁掉,即在删除这段代码即可:

ballData->setPosition(ccp(b2node->GetPosition().x*PTM_RATIO,b2node->GetPosition().y*PTM_RATIO));        ballData->setRotation(-1*CC_RADIANS_TO_DEGREES(b2node->GetAngle()));

         这是删除对象一个方法,还有一个方法就是,我们可以将要删除对象保存在一个临时容器中,等物体链表遍历完成之后,就可以删除临时容器中的物体了。



0 0
原创粉丝点击