2

我在 Sprite Kit 中使用碰撞检测。它正在工作并防止我的精灵穿过路径。但是,我在 didBeginContact: 中没有收到通知,而且我似乎无法控制发生碰撞时物理引擎的响应方式。

我有各种汽车(SKSpriteNodes)使用 SKAction followPath:asOffset:orientToPath:duration 在以下路径中移动:

以前,如果两辆车相交,它们都会像往常一样继续行驶,其中一辆驶过另一辆。为了实现碰撞检测,我进行了以下更改...

将此添加到我的@interface:

<SKPhysicsContactDelegate>

将此添加到我的@implementation:

static const uint32_t carCategory = 0x1 << 0;

在我的 init 方法中添加了这个:

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

我创建了我的蓝色汽车:

- (void)addBlueCar
{
    _blueCar = [SKSpriteNode spriteNodeWithImageNamed:@"Blue Car.png"];
    _blueCar.position = CGPointMake(818.0, -50.0);
    _blueCar.name = @"car";
    [self addChild:_blueCar];

    CGSize contactSize = CGSizeMake(_blueCar.size.width - 5.0, _blueCar.size.height - 5.0);
    _blueCar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize];
    _blueCar.physicsBody.categoryBitMask = carCategory;
    _blueCar.physicsBody.collisionBitMask = carCategory;
    _blueCar.physicsBody.contactTestBitMask = carCategory;
}

我还创造了一辆红色汽车:

- (void)addRedCar
{
    _redCar = [SKSpriteNode spriteNodeWithImageNamed:@"Red Car.png"];
    _redCar = CGPointMake(818.0, -50.0);
    _redCar = @"car";
    [self addChild: _redCar];

    CGSize contactSize = CGSizeMake(_blueCar.size.width - 5.0, _blueCar.size.height - 5.0);
    _redCar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize];
    _redCar.physicsBody.categoryBitMask = carCategory;
    _redCar.physicsBody.collisionBitMask = carCategory;
    _redCar.physicsBody.contactTestBitMask = carCategory;
}

还有其他汽车,但我只是在使用这两个,直到我弄清楚问题所在。我想收到任何两辆车之间发生碰撞的通知。这就是为什么我只使用一个类别,carCategory。

第一个问题是我没有收到任何通知。我有这个,但它从不将任何内容记录到控制台:

- (void)didBeginContact:(SKPhysicsContact *)contact
{
    NSLog(@"Contact");
}

第二个问题是,当两辆车相交时,它们会开始互相推开。这没关系,但我似乎无法管理如何处理碰撞的任何方面。奇怪的是,当我对我的两种汽车创建方法执行此操作时,没有任何变化:

- (void)addBlueCar
{
    _blueCar = [SKSpriteNode spriteNodeWithImageNamed:@"Blue Car.png"];
    _blueCar.position = CGPointMake(818.0, -50.0);
    _blueCar.name = @"car";
    [self addChild:_blueCar];

    CGSize contactSize = CGSizeMake(_blueCar.size.width - 5.0, _blueCar.size.height - 5.0);
    _blueCar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize];
//    _blueCar.physicsBody.categoryBitMask = carCategory;
//    _blueCar.physicsBody.collisionBitMask = carCategory;
//    _blueCar.physicsBody.contactTestBitMask = carCategory;
}

碰撞检测仍然与为两辆车注释掉的那三行相同。这对我来说似乎不正确。只有当我也注释掉这一行时,碰撞检测才会停止:

    _blueCar.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:contactSize];

所以我的主要问题是:为什么contactTest 没有报告任何内容?我的第二个问题是:当我没有为任何汽车分配 categoryBitMask、collisionBitMask 或 contactTestBitMask 时,为什么会发生碰撞检测?

4

3 回答 3

5

collisionBitMask的默认值为 0xFFFFFFFF(所有位设置)。physicBody因此该节点将与场景中的每个节点发生碰撞。

于 2013-11-29T14:11:44.357 回答
0

只是一个小小的观察,也许您应该设置您的节点并在场景的didMoveToView方法中设置联系委托。

如果这不能解决它,您是否有机会将一些工作代码发布到 github 进行调试?

于 2013-11-29T05:04:22.340 回答
0

对我有帮助的东西:碰撞和接触是不同的东西。

碰撞由物理引擎处理,设置collisionBitMask 将确定物理世界中哪些物体相互碰撞和相互作用。默认情况下,你所有的身体都会相互碰撞,这有点道理。

联系人是事件——当身体接触时,他们会创建一个通知,您可以在委托方法中使用它来做更多有趣的事情。如果您想用球拍击球,则希望它们至少发生碰撞。但是如果你有一个球在云中移动,你可能不希望它们在物理世界中发生碰撞,但你可能想要注册接触。

于 2015-10-01T21:47:07.150 回答