Cocos2d v3 и проблемы с обнаружением столкновений бурундуков

Сначала попробуйте Бурундука.

Проблема заключается в отсутствии регистрации обнаружения столкновений.

Мой код:

@implementation MainPlayScene
{
    CCPhysicsNode *_physics;
    CCNode *MyPhysicsBody;
    CCNode *bottomBody;

}

+ (instancetype)scene
{
    return [[self alloc] init];
}

- (instancetype)init
 {
 // Apple recommend assigning self with      supers return value, and handling self not created
    self = [super init];
    if (!self) return(nil);

    _physics = [CCPhysicsNode node];
    _physics.debugDraw = YES;
    [self addChild:_physics z:1];

 /// BOTTOM
    CGRect bottomRect = CGRectMake(0, 0,      [CCDirector sharedDirector].viewSize.width, 10);
    bottomBody = [CCNode node];
    bottomBody.physicsBody = [CCPhysicsBody bodyWithPolylineFromRect:bottomRect     cornerRadius:0];
    bottomBody.physicsBody.collisionCategories = @[@"Bottom"];
   bottomBody.physicsBody.type =     CCPhysicsBodyTypeStatic;
    [_physics addChild:bottomBody];

  /// MyBody to bounce around
    MyPhysicsBody = [CCSprite spriteWithImageNamed:@"MyBody-64x64-24.png"];
    MyPhysicsBody.position = ccp((self.contentSize.width/2),(self.contentSize.height/2));
    MyPhysicsBody = [CCNode node];
    MyPhysicsBody.physicsBody = [CCPhysicsBody bodyWithRect:(CGRect){CGPointZero,  MyPhysicsBody.contentSize.height,MyPhysicsBody.contentSize.width} cornerRadius:0];
      MyPhysicsBody.physicsBody.collisionCategories = @[@"MyBody"];
    [_physics addChild:MyPhysicsBody z:150];

    self.userInteractionEnabled = YES;
    return self;
}

Обнаружение событий касания и приложение силы к физическому телу, чтобы оно подпрыгивало вверх и вниз по нижней части тела

 - (void)touchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{   
    CCLOG(@"Touch Detected");
    [MyPhysicsBody.physicsBody applyImpulse:ccp(0, 300.f)];
}

Теперь я пытаюсь обнаружить столкновение на «Снизу», но ничего не регистрируется, хотя я вижу, что строки отладки касаются двух объектов.

/// try onCollisionEnter first ... nothing 
-(void)onCollisionEnter:(CCNode *)entity collisionPair:(CCPhysicsCollisionPair *)pair
{
    if ([entity.physicsBody.collisionCategories  isEqual: @"Bottom"]) {
        CCLOG(@"Hit bottomBody");
    }

}

/// try ccPhysicsCollisionBegin pair ... nothing
-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair MyBody:(CCNode *) MyBody Botton:(CCNode *)Bottom
{
     CCLOG(@"Hit bottomBody");
     return TRUE;
}

Очевидно, я упускаю здесь что-то важное ...

Любая помощь ОЧЕНЬ ценится!

Спасибо


person J C    schedule 18.03.2014    source источник


Ответы (3)


Мне трудно увидеть соответствующий код со всеми вещами, которые вы разместили.

Я приведу вам пример обнаружения столкновения 2 CCSprite объектов. Один называется _arrow, а другой _obstacle.

Первый шаг - определить следующие типы столкновений:

_arrow.physicsBody.collisionType = @"arrow";
_obstacle.physicsBody.collisionType = @"obstacle";

Второй шаг - определить обратный вызов

-(BOOL)ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair arrow:(CCNode *)arrow obstacle:(CCNode *)obstacle
{
    // Do some cool stuff
    return TRUE;
}

Обратите внимание на название, стрелку и препятствие в соответствии с типом столкновения этих спрайтов.

И в-третьих, вы забыли установить делегат, чтобы эти методы вызывались в вашем объекте PhysicsNode.

_physics.collisionDelegate = self;

И self (обычно это просто ваша сцена) должен реализовывать протокол CCPhysicsCollisionDelegate.

person Tibor Udvari    schedule 19.03.2014
comment
У меня не было [кода] _physics.collisionDelegate = self; [/ code], в чем была проблема. Спасибо за помощь :) - person J C; 20.03.2014
comment
Круто, не могли бы вы принять мой ответ, если он был вам полезен, спасибо! - person Tibor Udvari; 20.03.2014
comment
У меня действительно есть _physics.collisionDelegate = self;, но когда я устанавливаю точку останова на ccPhysicsCollisionBegin:typeA:typeB:, он просто никогда не вызывается. Что я хочу сделать, так это игнорировать определенные типы, поэтому я могу return NO;, но я просто никогда не захожу так далеко. :( - person Olie; 26.09.2014
comment
Ого, я ПРОСТО понял это. Я введу в ответ свою дополнительную подсказку. - person Olie; 26.09.2014

У Тибора есть правильный ответ, но я упустил важный ключ, который сводил меня с ума. Из комментариев в разделе CCPhysicsNode.h на CCPhysicsCollisionDelegate:

The final two parameter names (typeA/typeB) should be replaced
with names used with CCPhysicsBody.collisionType or
CCPhysicsShape.collisionType.
If both final parameter names are "default" then the collision
method is called when a more specific method isn't found.

Итак, я неправильно пытался реализовать что-то вроде этого:

-(BOOL) ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair typeA:(CCNode *)nodeA typeB:(CCNode *)nodeB
{
    // Compare if we're ignored collisions
    if (([nodeA.physicsBody.collisionType isEqualToString: @"foo"])
    ||  ([nodeB.physicsBody.collisionType isEqualToString: @"foo"]) )
    {
        return NO;
    }

    return YES;
}

Но это НЕПРАВИЛЬНО !!! Я хотел реализовать следующее:

-(BOOL) ccPhysicsCollisionBegin:(CCPhysicsCollisionPair *)pair foo:(CCNode *)nodeA foo:(CCNode *)nodeB
{
    return NO;
}

Обратите внимание на то, что игнорируемый тип столкновения является частью сигнатуры метода.

Ух!

РЕДАКТИРОВАТЬ:

Для полноты картины не забудьте сделать:

_physics.collisionDelegate = self;
person Olie    schedule 25.09.2014
comment
идеальный мужчина ... ты такой ясный. Я такой идиот, что не прочитал этот важный комментарий. - person Paresh Thakor; 12.10.2014
comment
Здесь нет идиотизма - это очень хорошо спрятано, и это не очень стандартный способ делать что-то. Хорошая головоломка! :) - person Olie; 12.10.2014

Вы устанавливаете категории столкновений, которые вместе с маской столкновений позволяют отбросить определенные столкновения. Свойство типа столкновения - это то, что работает с методами делегата.

person slembcke    schedule 19.03.2014
comment
Спасибо за ответ! Я только что попробовал: ... /// переопределить collisionType, а не collisionCategory headPhysicsBody.physicsBody.collisionType = @Head; bottomBody.physicsBody.collisionType = @Bottom; ... - (void) onCollisionEnter: (CCNode *) entity collisionPair: (CCPhysicsCollisionPair *) пара {CCLOG (@onCollisionEnter); если ([entity.physicsBody.collisionType isEqual: @Bottom]) {CCLOG (@Hit bottomBody); }} И все равно столкновения не обнаружено. Я помещаю CCLog, чтобы увидеть, вызывается ли когда-нибудь onCollisionEnter, а это не так. Любые идеи? - person J C; 19.03.2014