2

我在 iOS 上使用 Box2D 和 Cocos2D。

有时,游戏会卡住,这是由 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;
    }

我有一个“英雄”必须收集硬币的游戏。硬币是物体,通过接触侦听器,我将物体添加到数组中,以便稍后在数组已满时销毁它们(计数 = 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];
}

我觉得很奇怪的是它不会每次都冻结,只是有时,而且我无法知道似乎阻塞了什么......

解决方法:body被多次添加到要销毁的数组中,所以当数组满的时候,多次被销毁,导致死循环。

4

2 回答 2

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. 如果要在硬币填满数组时销毁硬币,最好检查数组是否有相同的对象。

于 2013-09-10T06:20:25.743 回答
0

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

这是 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属性的值m_contactManager

  2. 循环检查 的值c并确定true或的值false。在这种情况下,由于c似乎是一个对象的实例,它可能正在检查是否c存在nil

  3. 在每个循环结束时,c设置为指向 的m_next成员c。这很奇怪,因为c它不再是m_contactList,而是包含在m_contactList. 再一次,这可能是完全正常的。你应该知道你的代码是做什么的。

于 2013-09-10T05:13:21.200 回答