节点不应该与其他节点发生碰撞

Node colliding with other node when it shouldn't

我有一个节点,每隔几秒生成一次,并从右侧穿过屏幕。我希望玩家每次接触该节点时分数都会增加,但我希望玩家直接穿过它而不是被它阻挡。现在,当玩家击中它时得分会上升,它会正确生成并移动,但会阻止玩家越过它。我已经尝试了多种解决方案,例如使得分线的 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;
}

如果您只想检测两个 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