Sprite Kit中的碰撞检测

时间:2013-11-28 20:40:29

标签: ios objective-c sprite-kit skspritenode skphysicsbody

我在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时,为什么会发生碰撞检测?

3 个答案:

答案 0 :(得分:5)

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

帮助我解决这个问题:碰撞和接触是不同的事情。

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

联系人是事件 - 当机构联系时,他们是否会创建一个通知,您可以在委托方法中使用该通知来执行更多有趣的事情。如果你有一个球,你想用桨击球,你希望它们至少碰撞。但是如果你有一个球穿过云,你可能不希望它们在物理世界中发生碰撞,但你可能想要注册联系人。