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

Objective C - SpriteKit - Unable to detect contact between ball and paddle node

我正在尝试检测球节点与任一桨节点之间的碰撞,但确认碰撞的消息未被触发。

有人可以帮助我了解我哪里出错了吗?

//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

Add these (change size of physics body if needed)

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

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