在sprite工具包中检测数组中对象之间的冲突

时间:2014-04-02 06:20:52

标签: objective-c xcode5 collision-detection sprite-kit collision

我试图制作一个游戏,障碍物从屏幕顶部落下,玩家必须尽量避开它们,但是didBeginContact方法没有被调用,它让我疯狂。这是我的代码中与节点冲突相关的部分...

//myScene.h
@interface MyScene : SKScene <SKPhysicsContactDelegate>

//myScene.m
@implementation MyScene

static const uint32_t playerCategory = 0x1 << 0;
static const uint32_t obstacleCategory = 0x1 << 1;

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        //setup scene
        self.backgroundColor = [SKColor whiteColor];
        self.physicsWorld.gravity = CGVectorMake(0, 0);
        self.physicsWorld.contactDelegate = self;
        obstacles = [NSMutableArray array];

        //add player node
        player = [SKNode node];
        SKSpriteNode *spritePlayer = [SKSpriteNode spriteNodeWithImageNamed:@"black.png"];
        spritePlayer.size = CGSizeMake(50, 50);
        spritePlayer.position = CGPointMake(self.frame.size.width/2, 100);
        player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.frame.size];
        player.physicsBody.dynamic = NO;
        player.physicsBody.mass = 0.02;
        [player addChild:spritePlayer];

        player.physicsBody.categoryBitMask = playerCategory;
        player.physicsBody.contactTestBitMask = obstacleCategory;
        player.physicsBody.collisionBitMask = 0;
        player.physicsBody.usesPreciseCollisionDetection = YES;

        [self addChild:player];
        [self spawnNewObstacles];

    }
    return self;
}

- (void)spawnNewObstacles
{
    //spawn obstacles
    obstacle = [SKSpriteNode spriteNodeWithImageNamed:@"black.png"];

    obstacle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:obstacle.frame.size];
    obstacle.physicsBody.dynamic = YES;

    obstacle.physicsBody.categoryBitMask = obstacleCategory;
    obstacle.physicsBody.contactTestBitMask = playerCategory;
    obstacle.physicsBody.collisionBitMask = 0;
    obstacle.physicsBody.usesPreciseCollisionDetection = YES;
}

-(void)didBeginContact:(SKPhysicsContact *)contact
{
    NSLog(@"didBeginContact Called!");

}

didBeginContact方法没有被调用,我无法找到我的代码有什么问题 所有的帮助表示赞赏...

1 个答案:

答案 0 :(得分:2)

sknode大小没有正确设置,因为没有图像引用,如果你记录它的大小,如果应该是inf,当我测试你的代码时,我返回了一个异常。

修复此错误会更改以下行

player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.frame.size]; change that to 

以下,它应该工作

player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spritePlayer.size];

正如我在下面所说的那样,只是放弃玩家的sknode,除非有充分的理由使用它,否则它只是多余的。 ///////以前的回答

我无法提醒您注意到您没有将障碍节点添加到任何父节点,即场景,就像您使用此线路对播放器节点所做的那样

[self addChild:player];

你需要对障碍节点做同样的事情

[self addChild:obstacle];

,我很惊讶您没有提到屏幕上没有看到这些节点,除非您将它们添加到您未包含的代码的不同部分,然后此时我建议您记录位置两个节点都可以了解屏幕上的内容。

至于你赢得的阵列,你需要做的就是给每个障碍节点命名,比如@&#34;障碍物&#34;,然后你可以使用以下方法访问所有具有该名称的节点

obstacle.name = @"obstacle";

/////later when you want to check for node removal

[self enumerateChildNodesWithName:@"obstacle" usingBlock:^(SKNode *node, BOOL *stop) {
    SKSpriteNode *child = (SKSpriteNode*)node;
    if (child.position.y <0){ //or any arbitrary condition
         [child removeFromParent];
    }
}];

最后,我无法看到使用播放器作为sknode,然后添加skspritenode,除非我遗漏了一些东西! :)。您可以简单地将播放器sknode放在一起,只需使用spritePlayer节点即可。 希望这会有所帮助。