Masalah deteksi tabrakan Cocos2d v3 & chipmunk

Percobaan pertama di Chipmunk.

Tidak mendaftarkan deteksi tabrakan adalah masalahnya.

Kode saya:

@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;
}

Mendeteksi peristiwa sentuhan dan menerapkan gaya pada benda fisika agar memantul ke atas dan ke bawah ke badan bagian bawah

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

Sekarang saya mencoba mendeteksi tabrakan di "Bawah" tetapi tidak ada yang terdaftar meskipun saya melihat garis debug dari 2 objek bersentuhan.

/// 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;
}

Jelas saya melewatkan sesuatu yang penting di siniā€¦

Apapun bantuannya sangat dihargai!

Terima kasih


person J C    schedule 18.03.2014    source sumber


Jawaban (3)


Saya merasa sulit untuk melihat kode yang relevan dengan semua hal yang Anda posting.

Saya akan memberikan contoh deteksi tabrakan 2 CCSprite objek. Yang satu disebut _arrowdan yang lainnya disebut _obstacle.

Langkah pertama adalah mendefinisikan tipe tabrakan seperti:

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

Langkah kedua adalah mendefinisikan panggilan balik

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

Perhatikan penamaan, panah, dan rintangan sesuai dengan tipe tabrakan sprite ini.

Dan ketiga, hal yang lupa Anda lakukan adalah mengatur delegate sehingga Anda benar-benar memanggil metode ini pada objek physicsNode Anda

_physics.collisionDelegate = self;

Dan self (yang biasanya hanya adegan Anda) harus mengimplementasikan protokol CCPhysicsCollisionDelegate.

person Tibor Udvari    schedule 19.03.2014
comment
Saya tidak memiliki [kode] _physics.collisionDelegate = self; [/code] yang merupakan masalahnya. Terima kasih atas bantuannya :) - person J C; 20.03.2014
comment
Keren, bisakah Anda menerima jawaban saya jika dirasa bermanfaat, terima kasih! - person Tibor Udvari; 20.03.2014
comment
Saya sebenarnya punya _physics.collisionDelegate = self; tetapi, ketika saya memasang breakpoint pada ccPhysicsCollisionBegin:typeA:typeB:, itu tidak pernah dipanggil. Yang ingin saya lakukan adalah mengabaikan tipe tertentu, jadi saya bisa return NO;, tapi saya tidak pernah sampai sejauh itu. :( - person Olie; 26.09.2014
comment
Oh wow, saya BARU menemukan jawabannya. Saya akan memasukkan petunjuk tambahan saya dalam sebuah jawaban. - person Olie; 26.09.2014

Tibor memiliki jawaban yang benar, tetapi ada petunjuk penting yang saya lewatkan yang membuat saya gila. Dari komentar di bagian CCPhysicsNode.h di 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.

Jadi saya salah mencoba menerapkan sesuatu seperti ini:

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

Tapi itu SALAH!!! Hal benar yang ingin saya terapkan adalah ini:

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

Perhatikan bagaimana tipe tabrakan yang diabaikan adalah bagian dari tanda tangan metode.

Wah!

EDIT:

Untuk kelengkapannya jangan lupa lakukan:

_physics.collisionDelegate = self;
person Olie    schedule 25.09.2014
comment
pria sempurna... kamu sangat jelas. Saya sangat bodoh karena tidak membaca komentar penting itu. - person Paresh Thakor; 12.10.2014
comment
Tidak ada kebodohan dalam hal ini -- hal ini sangat tersembunyi, dan bukan cara standar dalam melakukan sesuatu. Pembuat teka-teki yang bagus! :) - person Olie; 12.10.2014

Anda mengatur kategori tabrakan yang bersama dengan masker tabrakan memungkinkan Anda membuang tabrakan tertentu. Properti tipe tabrakan adalah properti yang berfungsi dengan metode delegasi.

person slembcke    schedule 19.03.2014
comment
Terimakasih telah menjawab! Saya baru saja mencoba: ... /// mendefinisikan ulang CollisionType bukan CollisionCategory headPhysicsBody.physicsBody.collisionType = @Head; bottomBody.physicsBody.collisionType = @Bawah; ... -(void)onCollisionEnter:(CCNode *)entitas collisionPair:(CCPhysicsCollisionPair *)pair { CCLOG(@onCollisionEnter); if ([entity.physicsBody.collisionType isEqual: @Bottom]) { CCLOG(@Hit bottomBody); } } Dan masih belum mendeteksi tabrakan. Saya memasang CCLog hanya untuk melihat apakah onCollisionEnter pernah dipanggil dan ternyata tidak. Ada ide? - person J C; 19.03.2014