【问题标题】:Cocos2d v3 & chipmunk collision detection issuesCocos2d v3 & 花栗鼠碰撞检测问题
【发布时间】:2014-03-18 23:18:59
【问题描述】:

第一次尝试花栗鼠。

问题是没有注册碰撞检测。

我的代码:

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

显然我在这里遗漏了一些关键的东西……

非常感谢任何帮助!

谢谢

【问题讨论】:

    标签: cocos2d-iphone chipmunk collision


    【解决方案1】:

    我发现很难看到您发布的所有内容的相关代码。

    我会给你一个例子 2CCSprite 对象碰撞检测。一个叫_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;
    }
    

    根据这些精灵的碰撞类型注意命名、箭头和障碍物。

    第三,您忘记做的是设置 delegate,这样您实际上就可以在您的 physicsNode 对象上调用这些方法

    _physics.collisionDelegate = self;
    

    并且self(通常只是您的场景)应该实现CCPhysicsCollisionDelegate 协议。

    【讨论】:

    • 我没有 [code] _physics.collisionDelegate = self; [/code] 这是问题所在。感谢您的帮助:)
    • 酷,如果你觉得我的回答有用,你能接受吗,谢谢!
    • 我实际上有 _physics.collisionDelegate = self; 但是,当我在 ccPhysicsCollisionBegin:typeA:typeB: 上设置断点时,它永远不会被调用。我想要做的是忽略某些类型,所以我可以return NO;,但我从来没有走那么远。 :(
    • 哇哦,我只是想通了。我将在答案中输入我的附加提示。
    【解决方案2】:

    Tibor 有正确的答案,但我错过了一条重要的线索,这让我发疯了。来自CCPhysicsCollisionDelegateCCPhysicsNode.h 部分中的 cmets:

    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;
    

    【讨论】:

    • 完美男人……你太清楚了。我真是个白痴,居然不看那条重要的评论。
    • 没有白痴——它隐藏得很好,而且不是一种非常标准的做事方式。一个很好的益智游戏! :)
    【解决方案3】:

    您正在设置碰撞类别,与碰撞掩码一起允许您丢弃某些碰撞。碰撞类型属性适用于委托方法。

    【讨论】:

    • 感谢您的回答!我刚试过: ... /// 重新定义碰撞类型而不是碰撞类别 headPhysicsBody.physicsBody.collisionType = @"Head"; bottomBody.physicsBody.collisionType = @"底部"; ... -(void)onCollisionEnter:(CCNode *)entity collisionPair:(CCPhysicsCollisionPair *)pair { CCLOG(@"onCollisionEnter"); if ([entity.physicsBody.collisionType isEqual:@"Bottom"]) { CCLOG(@"Hit bottomBody"); } } 仍然没有检测到碰撞。我放了一个 CCLog 只是为了看看是否曾经调用过 onCollisionEnter 而不是。有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多