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

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()));

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值