Box2D无限循环(b2World :: SolveTOI)

时间:2013-09-09 23:03:39

标签: iphone ios cocos2d-iphone box2d objective-c++

我正在使用Box2D和Cocos2D for iOS。

游戏不时冻结,它是由b2World :: SolveTOI上的无限循环引起的。

for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)
    {
        // Invalidate TOI
        c->m_flags &= ~(b2Contact::e_toiFlag | b2Contact::e_islandFlag);
        c->m_toiCount = 0;
        c->m_toi = 1.0f;
    }

我有一个游戏,“英雄”必须收集硬币。硬币是主体,通过接触监听器,我在数组中添加主体,以便在数组满时(count = 2)后销毁它们。

以下是我如何向数组添加实体:

+ (void) addBodyToDestroy:(b2Body *)body {
[toDestroyArray addObject:[NSValue valueWithPointer:body]];
}

以下是我如何摧毁他们:

+ (void) destroyAllBodies {

b2World *world = [InGame getWorld];

for (NSValue *bodyValue in toDestroyArray)
{
    b2Body *body;
    body = (b2Body*)[bodyValue pointerValue];
    world->DestroyBody(body);
    body = NULL;
}

[toDestroyArray removeAllObjects];
}

我觉得非常奇怪的是,它不会每次都冻结,有时候,我无法知道阻止什么... ...

解决方案: 身体被多次添加到要被破坏的数组中,所以当数组已满时,它被多次破坏,导致无限循环。

2 个答案:

答案 0 :(得分:1)

  1. b2联系人管理器的联系人是链表数据。 所以,for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next) 表示从m_contactList开始并循环,直到c->next符合NULL

  2. 我不知道您的联系人听众是如何工作的,但您必须注意世界步骤,碰撞检查和销毁的时间。 因为,每当世界踩踏时有联系人,就会调用联系人监听器。因此,如果您的联系人侦听器旨在存储联系人数据,那么您必须处理world step和destroy之间的所有联系人数据。 (如果不这样做,联系人数据中可能会有被摧毁的身体的悬空指示)

  3. 如果要在填充数组时销毁硬币,最好检查数组是否有相同的对象。

答案 1 :(得分:0)

至少从我的经验来看,

for (b2Contact* c = m_contactManager.m_contactList; c; c = c->m_next)是一个非常不寻常的循环。我可以清楚地解释它的作用,也许这会对你有帮助。

这就是for循环的工作原理:

for( /*code called at beginning, usually to create a counting variable*/;/*code that is checked for a boolean value every loop.  True means loop again, false means stop.  Usually this is checking the value of the counting variable.*/;/*code that is called at the end of each loop.  Usually this is advancing the counting variable*/) {
//Code inside the loop that does stuff many times
}

所以对于这个循环:

  1. 循环开始。创建了一个名为b2Contact的新c指针,并将其指定为m_contactList的{​​{1}}属性的值。

  2. 循环检查m_contactManager的值,并确定ctrue的值。在这种情况下,由于false似乎是对象的实例,因此可能正在检查c是否为c

  3. 在每个循环结束时,nil设置为指向c的{​​{1}}成员。这很奇怪,因为m_next不再是c,而是由c包含的内容。然后,这可能是完全正常的。你应该知道你的代码做了什么。