目标C - SpriteKit -无法检测球和桨节点之间的接触



我正在尝试检测球节点和桨节点之间的碰撞,但确认碰撞的消息没有被触发。

有人能帮我理解我错在哪里吗?

//categories for detecting contacts between nodes
static const uint32_t ballCategory = 0x1 << 0;
static const uint32_t paddleCategory = 0x1 << 1;

@interface GameScene ()
@property BOOL contentCreated;
@property(nonatomic) UITouch *playerOnePaddleControlTouch;
@property(nonatomic, weak) UITouch *paddleTouch;
@property(nonatomic) SKSpriteNode *paddleOneNode;
@property(nonatomic) SKSpriteNode *paddleTwoNode;
@property(nonatomic) SKSpriteNode *ballNode;
@property(nonatomic) SKLabelNode *playerOneScoreNode;
@property(nonatomic) SKLabelNode *playerTwoScoreNode;
@property(nonatomic) NSInteger playerOneScore;
@property(nonatomic) NSInteger playerTwoScore;
@end
@implementation GameScene
- (void)didMoveToView:(SKView *)view
{
    if (!self.contentCreated)
    {
        [self createSceneContents];
        self.contentCreated = YES;
    }
}
- (void) createSceneContents
{
    self.backgroundColor = [SKColor blackColor];
    self.scaleMode = SKSceneScaleModeAspectFit;
    [self addChild: [self newGameNode]];
    self.physicsWorld.gravity = CGVectorMake(0, 0);
    self.physicsWorld.contactDelegate = self;
    // Create border around screen
    SKPhysicsBody* borderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
    self.physicsBody = borderBody;
    self.physicsBody.friction = 0;
    // Create Paddle One
    SKSpriteNode *paddleOne = [self newPaddle];
    paddleOne.position = CGPointMake(CGRectGetMidX(self.frame)/8, CGRectGetMidY(self.frame));
    paddleOne.name = @"paddleOne";
    paddleOne.physicsBody.categoryBitMask = paddleCategory;
    paddleOne.physicsBody.contactTestBitMask = ballCategory;
    [self addChild:paddleOne];
    // Create Paddle Two
    SKSpriteNode *paddleTwo = [self newPaddle];
    paddleTwo.position = CGPointMake((CGRectGetMaxX(self.frame) - CGRectGetMidX(self.frame) / 8), CGRectGetMidY(self.frame));
    paddleTwo.name = @"paddleTwo";
    paddleTwo.physicsBody.categoryBitMask = paddleCategory;
    paddleTwo.physicsBody.contactTestBitMask = ballCategory;
    [self addChild:paddleTwo];
    // Create ball
    SKSpriteNode *ball = [self newBall];
    ball.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    [self addChild:ball];
    ball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ball.frame.size.width/2];
    ball.physicsBody.friction = 1.0f; //normally 1.0f
    ball.physicsBody.restitution = 1.0f; //normally 1.0f
    ball.physicsBody.linearDamping = 0.0f; //normally 0.0f
    ball.physicsBody.allowsRotation = NO;
    ball.physicsBody.categoryBitMask = ballCategory;
    ball.physicsBody.contactTestBitMask = paddleCategory;
    [ball.physicsBody applyImpulse:CGVectorMake(1.0f, -1.0f)];
    // Create score labels
    self.playerOneScoreNode = [SKLabelNode labelNodeWithFontNamed:@"Helvetica"];
    self.playerTwoScoreNode = [SKLabelNode labelNodeWithFontNamed:@"Helvetica"];
    self.playerOneScoreNode.fontColor = self.playerOneScoreNode.fontColor = [SKColor whiteColor];
    self.playerOneScoreNode.fontSize = self.playerTwoScoreNode.fontSize = 90;
    self.playerOneScoreNode.position = CGPointMake((CGRectGetWidth(self.frame))* 0.25, (CGRectGetHeight(self.frame)) - 80);
    self.playerTwoScoreNode.position = CGPointMake((CGRectGetWidth(self.frame)) * 0.75, (CGRectGetHeight(self.frame)) - 80);
    [self addChild:self.playerOneScoreNode];
    [self addChild:self.playerTwoScoreNode];
    // Set Scores to 0
    self.playerOneScore = 7;
    self.playerTwoScore = 0;
    self.playerOneScoreNode.text = [NSString stringWithFormat:@"%ld",self.playerOneScore];
    self.playerTwoScoreNode.text = [NSString stringWithFormat:@"%ld",self.playerTwoScore];
}

- (SKSpriteNode *)newPaddle
{
    SKSpriteNode *paddle = [[SKSpriteNode alloc]initWithColor:[SKColor whiteColor] size:CGSizeMake(16,64)];
    return paddle;
}
- (SKSpriteNode *)newBall
{
    SKSpriteNode *ball = [[SKSpriteNode alloc]initWithColor:[SKColor redColor] size:CGSizeMake(16, 16)];
    return ball;
}

- (SKLabelNode *) newGameNode
{
    SKLabelNode *gameNode = [SKLabelNode labelNodeWithFontNamed:@"Chalkduster"];
    gameNode.text = @" Pong";
    gameNode.fontSize = 50;
    gameNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
    gameNode.fontColor = [SKColor blueColor];
    return gameNode;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    self.paddleTouch = [touches anyObject];
    UITouch *touch = [touches anyObject];
    CGPoint touchPoint = [touch locationInNode:self];
    SKNode *paddleOne = [self childNodeWithName:@"paddleOne"];
    SKNode *paddleTwo = [self childNodeWithName:@"paddleTwo"];
    if (touchPoint.x < CGRectGetMidX(self.frame)) {
    paddleOne.position = CGPointMake(paddleOne.position.x, touchPoint.y);
    }
    else
    {
            paddleTwo.position = CGPointMake(paddleTwo.position.x, touchPoint.y);
        }

}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    if (self.paddleTouch) {
        UITouch *touch = [touches anyObject];
        CGPoint touchPoint = [touch locationInNode:self];
        CGPoint previousPoint = [touch previousLocationInNode:self];
        SKSpriteNode *paddleOne = (SKSpriteNode*)[self childNodeWithName:@"paddleOne"];
        SKSpriteNode *paddleTwo = (SKSpriteNode*)[self childNodeWithName:@"paddleTwo"];
        int paddleOneY = paddleOne.position.y + (touchPoint.y - previousPoint.y);
        int paddleTwoY = paddleTwo.position.y + (touchPoint.y - previousPoint.y);
        if (touchPoint.x < CGRectGetMidX(self.frame)) {
        paddleOne.position = CGPointMake(paddleOne.position.x, paddleOneY);
        }
        else
        {
        paddleTwo.position = CGPointMake(paddleTwo.position.x, paddleTwoY);
        }
    }
}
// React to collision's between nodes/bodies
// Currently not working....need to understand this set of code.
-(void)didBeginContact:(SKPhysicsContact *)contact
{
    SKPhysicsBody *firstBody;
    SKPhysicsBody *secondBody;
    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
    {
        firstBody = contact.bodyA;
        secondBody = contact.bodyB;
    }
    else
    {
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
    }
    if (firstBody.categoryBitMask == ballCategory && secondBody.categoryBitMask == paddleCategory)
    {
        NSLog(@"Ball has touched Paddle");
    }
}
@end

您的paddleOnepaddleTwo没有SKPhysicsBody

添加这些(如果需要改变物理体的大小)

paddleOne.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: paddleOne.size];
paddleTwo.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: paddleTwo.size];

最新更新