我在 SKSpriteNode 中使用碰撞检测时遇到问题

Posted

技术标签:

【中文标题】我在 SKSpriteNode 中使用碰撞检测时遇到问题【英文标题】:I have an issue using collision detection in SKSpriteNode 【发布时间】:2014-07-20 18:36:19 【问题描述】:

您好,我在使用碰撞检测时遇到问题。发生的事情是当弹丸(子弹)击中外星人时会产生粒子火花。问题是有时我认为这个函数会混淆弹丸和怪物,所以有时它会在子弹被摧毁的地方产生火花。

问。是什么决定了哪个精灵命中哪个。

谁能给点建议?

- (void)projectile:(SKSpriteNode *)projectile didCollideWithMonster:(SKSpriteNode *)monster 


    [projectile removeFromParent];
    canfire = true;

    NSString *path = [[NSBundle mainBundle]pathForResource:@"spark" ofType:@"sks"];
    SKEmitterNode *spark = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
    spark.position = monster.position;
    SKAction *pause = [SKAction waitForDuration:1.0];
    SKAction *remove = [SKAction removeFromParent];
    [spark runAction:[SKAction sequence:@[pause,remove]]];

    spark.position = monster.position;
    [monster addChild:spark];
    [monster removeFromParent];

是的,肯定会把弹丸和怪物混为一谈:

2014-07-20 19:56:35.279 Space Warz[9420:60b] First Body name = bullet
2014-07-20 19:56:35.280 Space Warz[9420:60b] Hit
2014-07-20 19:56:35.281 Space Warz[9420:60b] Monster Name: crystalship
2014-07-20 19:56:40.878 Space Warz[9420:60b] Contact
2014-07-20 19:56:40.879 Space Warz[9420:60b] First Body name = crystalship
2014-07-20 19:56:40.880 Space Warz[9420:60b] Hit
2014-07-20 19:56:40.881 Space Warz[9420:60b] Monster Name: bullet
2014-07-20 19:56:43.845 Space Warz[9420:60b] Contact
2014-07-20 19:56:43.846 Space Warz[9420:60b] First Body name = bullet
2014-07-20 19:56:43.847 Space Warz[9420:60b] Hit
2014-07-20 19:56:43.848 Space Warz[9420:60b] Monster Name: crystalship
2014-07-20 19:56:43.855 Space Warz[9420:60b] Contact
2014-07-20 19:56:43.856 Space Warz[9420:60b] First Body name = bullet
2014-07-20 19:56:43.857 Space Warz[9420:60b] Hit
2014-07-20 19:56:43.858 Space Warz[9420:60b] Monster Name: crystalship

【问题讨论】:

#LearnCocos2D 你编辑了什么? 听起来射弹和怪物参数并不总是你“期望”的那样。该方法在哪里被调用?发布该代码。您拥有的方法没有确定哪个是哪个,它假设您正在传递正确的对象以匹配参数,对吗? 如何调用 didCollideWithMonster 方法? 【参考方案1】:

在我看来,您没有对在 -didBeginContact 方法中作为参数接收的主体进行排序。

每次调用联系人委托时,contact 对象的 bodyAbodyB 属性不一定包含相同类型的主体。在您的情况下,contact.bodyAcontact.bodyB 都可以包含射弹或怪物节点。

您可以按如下方式对正文进行排序:

-(void)didBeginContact:(SKPhysicsContact *)contact`


    NSLog(@"contact detected");

    SKPhysicsBody *firstBody;
    SKPhysicsBody *secondBody;

    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
    
        firstBody = contact.bodyA;
        secondBody = contact.bodyB;
    
    else
    
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
    

    //Implement relevant code here.


在上面的代码中,您可以通过传递 firstBody 和 secondBody 来调用-didCollideWithMonster。在涉及的两个位掩码类别中,值较低的将是 firstBody,值较高的将是 secondBody。

也请看看这个answer。

【讨论】:

以上是关于我在 SKSpriteNode 中使用碰撞检测时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

SKSpriteNode 无法检测到与两个 bodyWithEdgeLoopF​​romPath 主体的碰撞

碰撞检测导致颜色检测? [复制]

如何加入两个碰撞的 SKSpriteNode

SKPhysicsContact未检测到categoryBitMask碰撞

未检测到 SkSpriteNode 冲突

如何检测精灵套件中的碰撞?