ios - 防止与 b2ContactListener 发生一次碰撞而产生多个回调?

标签 ios collision-detection box2d contacts

我从本教程中下载了 Ray Wenderlich 的简单接触监听器:http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone

目前我正在使用下面的代码,它几乎是我的 CCLayer 中 Ray 的自定义 b2ContactListener 的实现。但问题是,一次碰撞有多个回调

有人可以告诉我如何制作,以便碰撞只会触发一次,直到两个物体未接触然后再次修饰吗?

这是我当前使用的代码:

std::vector<b2Body *>toDestroy; 
std::vector<MyContact>::iterator pos;
for(pos = _contactListener->_contacts.begin(); pos != _contactListener->_contacts.end(); ++pos) {
    MyContact contact = *pos;

    // Get the box2d bodies for each object
    b2Body *bodyA = contact.fixtureA->GetBody();
    b2Body *bodyB = contact.fixtureB->GetBody();
    if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
        CCSprite *spriteA = (CCSprite *) bodyA->GetUserData();
        CCSprite *spriteB = (CCSprite *) bodyB->GetUserData();

        if ((spriteA.tag == 1 && spriteB.tag == 2) || (spriteA.tag == 2 && spriteB.tag == 1)) {
             NSLog(@"tag 1 hit tag 2");
        } 

谢谢!

编辑1:

if ((hasDetectedCollision == NO) && ( (spriteA.tag == 1 && spriteB.tag == 2) || (spriteA.tag == 2 && spriteB.tag == 1) ) ) {
                hasDetectedCollision = YES;
                NSLog(@"tag 1 hit tag 2");
                [self doSomethingWhenCollisionHappens];
            }

- (void)doSomethingWhenCollisionHappens {
    //here you might want to remove an object because of a collision
    //or maybe change the color of the objects that collided
    //I can't provide more details of what you might want
    //to do without seeing more of your code
    //but when you are ready to start receiving collision updates again
    //set hasDetectedCollision to NO again
    [yesLabel setString:[NSString stringWithFormat:@"Yes: %d", yesNumber++]];
    hasDetectedCollision = NO;
}

然后在我的 init 方法中:

hasDetectedCollision = NO;

新编辑:

if (!hasDetectedCollision && ((spriteA.tag == 1 && spriteB.tag == 4) || (spriteA.tag == 4 && spriteB.tag == 1))) {
            hasDetectedCollision = YES;
            [yesLabel setString:[NSString stringWithFormat:@"Yes:%d", yesInt++]];
            NSLog(@"tag 1 hit tag 4");
        } 

最佳答案

我不熟悉 Box2d,但是根据您在问题中所描述的内容,这应该可以帮助您:

在你的.h中:

@interface foo : FooBar {
    BOOL hasDetectedCollision;
}

在你的.m中:

- (void)viewDidLoad {
    hasDetectedCollision = NO;
}

然后简单地替换

if ((spriteA.tag == 1 && spriteB.tag == 2) || (spriteA.tag == 2 && spriteB.tag == 1)) {
    NSLog(@"tag 1 hit tag 2");
} 

if ((hasDetectedCollision == NO) && ( (spriteA.tag == 1 && spriteB.tag == 2) || (spriteA.tag == 2 && spriteB.tag == 1) ) ) {
    hasDetectedCollision = YES;
    NSLog(@"tag 1 hit tag 2");
    [self doSomethingWhenCollisionHappens];
} 

然后:

- (void)doSomethingWhenCollisionHappens {
    //here you might want to remove an object because of a collision
    //or maybe change the color of the objects that collided
    //I can't provide more details of what you might want
    //to do without seeing more of your code
    //but when you are ready to start receiving collision updates again
    //set hasDetectedCollision to NO again
    hasDetectedCollision = NO;
}

然后,每当您完成检测到碰撞时想做的任何事情时,将 hasDetectedCollision 设置回 no,然后就可以重新开始。

编辑:

std::vector<b2Body *>toDestroy; 
std::vector<MyContact>::iterator pos;
for(pos = _contactListener->_contacts.begin(); pos != _contactListener->_contacts.end(); ++pos) {
MyContact contact = *pos;

// Get the box2d bodies for each object
b2Body *bodyA = contact.fixtureA->GetBody();
b2Body *bodyB = contact.fixtureB->GetBody();
if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
    CCSprite *spriteA = (CCSprite *) bodyA->GetUserData();
    CCSprite *spriteB = (CCSprite *) bodyB->GetUserData();

    if(hasDetectedCollision == NO)
        NSLog(@"hasDetectedCollision == NO");

    if ((spriteA.tag == 1 && spriteB.tag == 2) || (spriteA.tag == 2 && spriteB.tag == 1)) {
         NSLog(@"tag 1 hit tag 2");
    } 

如果检查 hasDetectedCollision 状态的 if 语句被执行,那么问题不在于 bool 值,而在于碰撞检测。

关于ios - 防止与 b2ContactListener 发生一次碰撞而产生多个回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8275038/

相关文章:

ios - 更改 Box2D anchor ?

c++ - Box2D:程序在破坏 b2Body 时崩溃

ios - 自动布局 : Relative scaling of views

ios - 如何在iOS的OpenGL ES上下文中绘制轮廓文本?

ios - iTunesConnect应用程序的主要语言更改无法传播

Javascript 正确碰撞后重置函数

c++ - box2d 联系监听器中的语义问题

java - libgdx - 实现移动运动学体

ios - 运行 ionic ios build --prod --release 时出错

javascript - 检测一个物体与多少个物体碰撞/否定多个物体