gpt4 book ai didi

objective-c - 除了我的玩家以外的物理实体在碰撞时不会调用 didBeginContact

转载 作者:搜寻专家 更新时间:2023-10-30 19:45:56 24 4
gpt4 key购买 nike

在我的游戏中,我有 4 个位掩码,一切都已设置,但 didBeginContact 仅在第一个位掩码 (playerCategory) 与某物发生碰撞时才会被调用。如果 3 与 4 发生碰撞,则什么也不会发生,即使我为它们设置了 contactTestBitMask 以进行碰撞。

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:

        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:

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 再次:

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。我也试过允许其他碰撞,但我无法让它们发生碰撞。

最佳答案

如果两个主体的 categoryBitMask 为零,它们将不会生成接触事件。例如,这发生在 playerCategory (1) 和 enemyCategory (4) 中:1 & 4 = 0 <== 玩家和敌人之间永远不会产生任何接触事件。在那种情况下,它甚至不会检查 contactBitMask 标志。

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

categoryBitMask 的默认值是 0xFFFFFFFF 以便所有主体都可以相互联系。 collisionBitMask 也是如此,因为通常您希望默认情况下所有物体都接触和碰撞。

在大多数情况下,您真正​​需要修改的唯一位掩码是 contactBitMask,其默认值为 0,这意味着默认情况下不生成接触事件(以提高性能).

仅更改单独更改 contactBitMask 不够的其他位掩码。

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

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

长话短说:categoryBitMask 标志应该从 0xFFFFFFFF 中清除(而不是设置为特定位),这样特定类别中的个体就不会与每个个体接触其他但仍与所有其他机构接触。

关于objective-c - 除了我的玩家以外的物理实体在碰撞时不会调用 didBeginContact,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22799213/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com