ปัญหาการตรวจจับการชนกันของ Cocos2d v3 และกระแต

ลองครั้งแรกที่ Chipmunk

การไม่ได้รับการลงทะเบียนการตรวจจับการชนกันคือปัญหา

รหัสของฉัน:

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

ตอนนี้ฉันพยายามตรวจจับการชนกันที่ "ด้านล่าง" แต่ไม่มีการบันทึกอะไรเลย แม้ว่าฉันจะเห็นว่าบรรทัดการแก้ไขข้อบกพร่องของวัตถุ 2 ชิ้นสัมผัสกันก็ตาม

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

Tibor มีคำตอบที่ถูกต้อง แต่มีเบาะแสสำคัญที่ฉันพลาดไปซึ่งทำให้ฉันแทบบ้า จากความคิดเห็นในส่วน 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; lowerBody.physicsBody.collisionType = @Bottom; ... -(เป็นโมฆะ) onCollisionEnter:(CCNode *) เอนทิตี collisionPair: (CCPhysicsCollisionPair *) คู่ { CCLOG(@onCollisionEnter); ถ้า ([entity.physicsBody.collisionType เท่ากับ: @Bottom]) { CCLOG(@Hit BottomBody); } } และยังตรวจไม่พบการชนกัน ฉันใส่ CCLog เพื่อดูว่าเคยมีการเรียก onCollisionEnter หรือไม่ มีความคิดอะไรบ้าง? - person J C; 19.03.2014