I am trying to detect the collision between the ball node and either one of the paddle nodes but the message to confirm the collision is not being fired.
Could somebody help me understand where I am going wrong?
//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
Your paddleOne
and paddleTwo
does not have SKPhysicsBody
.
Add these (change size of physics body if needed)
paddleOne.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: paddleOne.size];
paddleTwo.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: paddleTwo.size];