碰撞时,我的玩家以外的物理实体不会调用 didBeginContact [英] Physics bodies other than my player won't call didBeginContact when colliding

查看:13
本文介绍了碰撞时,我的玩家以外的物理实体不会调用 didBeginContact的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的游戏中,我有 4 个位掩码,一切都已设置好,但 didBeginContact 仅在第一个位掩码(playerCategory)与某物碰撞时才被调用.如果 3 与 4 发生碰撞,则不会发生任何事情,即使我设置了 contactTestBitMask 让它们发生碰撞.

In my game I have 4 bitmasks and everything is setup, yet didBeginContact only gets called when the first bitmask (playerCategory) collides with something. if 3 collides with 4, nothing happens, even though I have the contactTestBitMask set for them to collide.

myscene.h

    self.physicsWorld.gravity = CGVectorMake(0.0, -2.45);
    self.physicsWorld.contactDelegate = self;

    self.player = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size: CGSizeMake(10.0, 20.0)];
    self.player.position = CGPointMake(20.0, self.frame.size.height);
    self.player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.player.size];
    self.player.physicsBody.affectedByGravity = YES;
    self.player.physicsBody.dynamic = YES;
    self.player.physicsBody.categoryBitMask = playerCategory;
    self.player.physicsBody.contactTestBitMask = enemyCategory;
    self.player.physicsBody.collisionBitMask = tileCategory;
    [self.gameNode addChild:self.player];

    [...]

- (void) swipeRightHandler:(UISwipeGestureRecognizer *) recognizer {
    NSLog(@"swipe right");
    SKSpriteNode *attackRect = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(40, 5)];
    attackRect.position = CGPointMake(self.player.position.x + 10, self.player.position.y);
    attackRect.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:attackRect.size];
    attackRect.physicsBody.categoryBitMask = attackCategory;
    attackRect.physicsBody.contactTestBitMask = 255;
    attackRect.physicsBody.collisionBitMask = enemyCategory;
    attackRect.physicsBody.affectedByGravity = NO;
    attackRect.physicsBody.dynamic = NO;
    [self.gameNode addChild:attackRect];
    [attackRect runAction:[SKAction moveBy:CGVectorMake(250, 0) duration:1.0] completion:^{
        [attackRect removeFromParent];
    }];
}

RandomLevelGenerator.m:

RandomLevelGenerator.m:

        SKSpriteNode *enemy = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(20, 20)];
        enemy.position = CGPointMake(visual_x, FLOOR_X + arc4random_uniform(MAX_Y - FLOOR_X));
        enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:enemy.size];
        enemy.physicsBody.categoryBitMask = enemyCategory;
        enemy.physicsBody.contactTestBitMask = playerCategory | attackCategory;
        enemy.physicsBody.collisionBitMask = attackCategory;
        enemy.physicsBody.affectedByGravity = NO;
        enemy.physicsBody.dynamic = NO;
        [self.scene.gameNode addChild:enemy];

LevelGenerator.h:

LevelGenerator.h:

static const uint32_t playerCategory    =   0x1 << 0;
static const uint32_t tileCategory      =   0x1 << 1;
static const uint32_t enemyCategory     =   0x1 << 2;
static const uint32_t attackCategory    =   0x1 << 3;

MyScene.m 再次:

MyScene.m again:

SKPhysicsBody *firstBody, *secondBody;

if(contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
    firstBody = contact.bodyA;
    secondBody = contact.bodyB;
} else {
    firstBody = contact.bodyB;
    secondBody = contact.bodyA;
}
NSLog(@"%d - %d", firstBody.categoryBitMask, secondBody.categoryBitMask);

最后一个 NSLog,只打印 1 - x,从不打印 3 - x.我也尝试过允许其他碰撞,但我无法让它们中的任何一个发生碰撞.

That last NSLog, only ever prints 1 - x, never 3 - x. I've also tried allowing other collisions and I can't get any of them to collide.

推荐答案

如果两个body 的categoryBitMask 为0,则不会产生接触事件.例如,这发生在 playerCategory (1) 和enemyCategory (4) 上: 1 &4 = 0 <== 玩家和敌人之间永远不会产生接触事件.在这种情况下,它甚至不会检查 contactBitMask 标志.

If the categoryBitMask for two bodies ANDed together is zero, they will not generate contact events. For instance this happens with playerCategory (1) and enemyCategory (4): 1 & 4 = 0 <== no contact events are generated, ever, between players and enemies. In that case it won't even get to check the contactBitMask flags.

如果您希望两个实体生成接触事件,它们都必须设置相同的类别位掩码标志.

categoryBitMask 的默认值为 0xFFFFFFFF,以便所有主体都可以相互联系.collisionBitMask 相同,因为通常您希望所有主体默认接触和碰撞.

The default for categoryBitMask is 0xFFFFFFFF so that all bodies can contact with each other. Same for collisionBitMask because generally you want all bodies to contact and collide by default.

在大多数情况下,您真正​​需要修改的唯一位掩码是 contactBitMask,其默认值为 0,表示默认不生成任何联系事件(以提高性能).

The only bit mask you really need to modify in most cases is the contactBitMask, whose default is 0, meaning no contact events are generated by default (to improve performance).

仅在单独更改 contactBitMask 不够用的情况下更改其他位掩码.

Only change the other bitmasks where changing contactBitMask alone does not suffice.

例如,当您想要接触事件,但没有碰撞反馈(= 碰撞物体接触时速度/位置的变化)时,请确保这些物体的 collisionBitMask 与一起为 0. 这允许身体产生接触事件,但相互传递.对创建触发器很有用,即当玩家进入某个区域时,您可以让他通过但也可以触发游戏事件.

For example when you want contact events, but no collision feedback (= change in velocity/position of colliding bodies when they come in contact), then make sure that those body's collisionBitMask ANDed together is 0. This allows bodies to generate contact events, but pass through each other. Useful to create triggers, ie when the player enters an area you can let him pass but also trigger a game event.

或者当您想对两个不同类别的实体使用相同的接触位掩码时,它们应该只与共享相同类别的其他实体发生碰撞/接触 - 即应该与其他所有物体具有相同接触行为的常规和幽灵"角色在游戏中,除非他们不应该与他们的实体(非幽灵)对手接触/碰撞.在这种情况下,对两个主体使用相同的 contactBitMaskcollisionBitMask.然后为所有其他类别设置 categoryBitMask 中的所有标志,但不要为代表实体和幽灵实体的两个类别设置标志.即如果实体类别为 2,幽灵类别为 8,则 categoryBitMask 应为:0xFFFFFFFF - 2 - 8 = 0xFFFFFFF5(低 8 位为:11110101)

Or when you want to use the same contact bitmasks for two different categories of bodies who should only collide/contact with other bodies sharing the same category - ie regular and "ghost" characters who should have the same contact behavior with everything else in the game, except they shouldn't contact/collide with their corporeal (non-ghost) counterparts. In that case, use the same contactBitMask and collisionBitMask for both bodies. Then set all flags in categoryBitMask for all other categories, but don't set the flags for the two categories representing the corporeal and ghost entities. Ie if corporeal category is 2 and ghost category is 8, the categoryBitMask should be: 0xFFFFFFFF - 2 - 8 = 0xFFFFFFF5 (lower 8 bits would be: 11110101)

长话短说:categoryBitMask 标志应从 0xFFFFFFFF 中清除(而不是设置为特定位),以便特定类别中的各个主体不会与每个主体联系其他但仍与所有其他机构接触.

Long story short: categoryBitMask flags should be cleared from 0xFFFFFFFF (rather than set to a specific bit) so that individual bodies in specific categories don't contact with each other but still contact with all other bodies.

这篇关于碰撞时,我的玩家以外的物理实体不会调用 didBeginContact的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆