节点在不应该与其他节点冲突时

时间:2015-02-15 22:42:36

标签: objective-c sprite-kit collision-detection skphysicsbody skaction

我有一个节点,每隔几秒就产生一次,并从右侧移过屏幕。我希望每次玩家接触到这个节点时分数都会增加,但我希望玩家直接通过它而不是被它阻挡。现在,当玩家击中它并且它产生并正确移动但是它会阻止玩家移过它时,得分会上升。我尝试了多种解决方案,例如让得分线的collisionBitmask等于0,但我仍然是对Objective-c的新手,所以我不知道解决方案,所以任何帮助都会非常感激。

以下是“@implementation”

上面的所有代码
@interface GameScene ()

@property (nonatomic) SKSpriteNode *clouds;
@property (nonatomic) SKSpriteNode *player;
@property (nonatomic) SKTexture *pipeTexture1;
@property (nonatomic) SKTexture *pipeTexture2;
@property (nonatomic) SKAction *_moveAndRemovePipes;
@property (nonatomic) SKNode *moving;
@property (nonatomic) SKLabelNode *scoreLabelNode;
@property (nonatomic) int score;

@end

static const uint32_t playerCategory     = 1;       
static const uint32_t pipeCategory       = 2;       
static const uint32_t bottomEdgeCategory = 4;
static const uint32_t edgeCategory       = 8;
static const uint32_t scoreCategory      =16;

下面是与得分线有关的代码。请注意,我添加分数标签的代码是我的initWithSize方法。

-(void) addScore:(CGSize) size{

// Initialize label and create a label which holds the score
//    _score = 0;
//    _scoreLabelNode = [SKLabelNode labelNodeWithFontNamed:@"MarkerFelt-Wide"];
//    _scoreLabelNode.position = CGPointMake( CGRectGetMidX( self.frame ), 3 * self.frame.size.height / 4 );
//    _scoreLabelNode.zPosition = 100;
//    _scoreLabelNode.text = [NSString stringWithFormat:@"%d", _score];

//add score line
SKNode *contactNode = [SKNode node];
contactNode.position = CGPointMake( self.frame.size.width + _pipeTexture1.size.width - 10   , CGRectGetMidY( self.frame ) );
contactNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake( 5, self.frame.size.height )];
contactNode.physicsBody.dynamic = NO;
contactNode.physicsBody.categoryBitMask = scoreCategory;
//    contactNode.physicsBody.contactTestBitMask = playerCategory;

//move score line
CGFloat distanceToMove = self.frame.size.width + 2.4 * _pipeTexture1.size.width;
SKAction *movePipes = [SKAction moveByX:-distanceToMove y:0 duration:0.01 * distanceToMove];
SKAction *removePipes = [SKAction removeFromParent];
SKAction *moveNode = [SKAction sequence:@[movePipes, removePipes]];

[contactNode runAction:moveNode];
[_moving addChild:contactNode];
//    [self addChild:_scoreLabelNode];
}

以下是我的initWithSize方法,我已经取出了一些不重要的代码。

-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {

    //change gravity
    self.physicsWorld.gravity = CGVectorMake( 0.0, -5 );

    //add physics to world
    self.physicsWorld.contactDelegate = self;

    //add moving node to keep track of animations
    _moving = [SKNode node];
    [self addChild:_moving];

    // Initialize label and create a label which holds the score
    _score = 0;
    _scoreLabelNode = [SKLabelNode labelNodeWithFontNamed:@"MarkerFelt-Wide"];
    _scoreLabelNode.position = CGPointMake( CGRectGetMidX( self.frame ), 3 * self.frame.size.height / 4 );
    _scoreLabelNode.zPosition = 100;
    _scoreLabelNode.text = [NSString stringWithFormat:@"%d", _score];
    [self addChild:_scoreLabelNode];

    SKAction* spawnScore = [SKAction performSelector:@selector(addScore:) onTarget:self];
    SKAction* delayScore = [SKAction waitForDuration:2.0];
    SKAction* spawnThenDelayScore = [SKAction sequence:@[delayScore,spawnScore]];
    SKAction* spawnThenDelayForeverScore = [SKAction repeatActionForever:spawnThenDelayScore];
    [self runAction:spawnThenDelayForeverScore];

    [self addScore:size];    
}
return self;
}

1 个答案:

答案 0 :(得分:0)

如果您只想检测两个SKNode之间的联系并且不希望它们发生碰撞,请将contactTestBitMask设置为另一个的categoryBitMask,将collissionBitMask设置为零。

例如,在您的情况下

player.physicsBody.categoryBitMask = playerCategory
player.physicsBody.contactTestBitMask = scoreCategory | otherCategories
player.physicsBody.collisionBitMask = 0 // This can be categories other than score categories

scoreNode.physicsBody.categoryBitMask = scoreCategory
scoreNode.physicsBody.contactTestBitMask = playerCategory | otherCategories
scoreNode.physicsBody.collisionBitMask = 0