Search code examples
sprite-kitcollision

Ball makes contact with player but they are not even closer


What am I missing here? Log says "Ball hits player" every time it collides with frame border or even floor objects if added.

(I´m very new to Sprite Kit and it is my first time working with collisions. This is making me crazy :D)

#import "MyScene.h"

static const int starHitCategory = 1;
static const int playerHitCategory = 2;
static const int ballHitCategory = 3;

@interface MyScene ()

@end

@implementation MyScene{

    SKSpriteNode *player;
    SKSpriteNode *redball;
    SKSpriteNode *star;
}

-(id)initWithSize:(CGSize)size {    
    if (self = [super initWithSize:size]) {
        /* Setup your scene here */
        self.physicsWorld.contactDelegate = self;

        self.physicsWorld.gravity = CGVectorMake(0.0f, -3.0f);
        SKPhysicsBody* borderBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
        self.physicsBody = borderBody;
        self.physicsBody.friction = 0.0f;

        //initalizing player node
        player = [SKSpriteNode spriteNodeWithImageNamed:@"player.png"];

        player.physicsBody.categoryBitMask = playerHitCategory;
        player.physicsBody.contactTestBitMask = playerHitCategory;
        player.physicsBody.collisionBitMask =  playerHitCategory;

        player.position = CGPointMake(75,101);
        player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.size];
        player.physicsBody.friction = 0.0f;
        player.physicsBody.linearDamping = 0.5f;
        player.physicsBody.mass = 10;
        player.physicsBody.dynamic = YES;
        player.physicsBody.usesPreciseCollisionDetection = YES;
        player.physicsBody.allowsRotation = NO;
        player.name = @"player";
        [self addChild:player];

        //initalizing Redball node
        redball = [SKSpriteNode spriteNodeWithImageNamed:@"redbdall.png"];
        redball.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:redball.frame.size.width/2];
        redball.position = CGPointMake(290,200);
        redball.physicsBody.usesPreciseCollisionDetection = YES;
        redball.physicsBody.categoryBitMask = ballHitCategory;
        redball.physicsBody.contactTestBitMask = ballHitCategory;
        redball.physicsBody.collisionBitMask =  ballHitCategory;
        redball.physicsBody.friction = 2.0f;
        redball.physicsBody.restitution = 1.0f;
        redball.physicsBody.linearDamping = 0.0f;
        redball.physicsBody.allowsRotation = NO;
        [self addChild:redball];

    //initalizing Star node
    star = [SKSpriteNode spriteNodeWithImageNamed:@"star.png"];
    star.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:star.size];
    star.physicsBody.categoryBitMask = starHitCategory;
    star.physicsBody.contactTestBitMask = starHitCategory;
    star.physicsBody.collisionBitMask =  starHitCategory;
    star.position = CGPointMake(205,125);
    [self addChild:star];

    }
    return self;
}


-(void)didBeginContact:(SKPhysicsContact *)contact
{
    SKPhysicsBody *firstBody, *secondBody;

    firstBody = contact.bodyA;
    secondBody = contact.bodyB;


    if(firstBody.categoryBitMask == playerHitCategory || secondBody.categoryBitMask == ballHitCategory)
    {
        NSLog(@"ball hits player");
    }
}

@end

Thanks in advance


Solution

  • Your if statement will be satisfied if the player/ball object will collide with whatever object it can collide with since you are not also checking that the other object is of the required category.

    You should change you if statement to be more strict since you also do not know which object of the two is the ball or the player or the floor:

        if((firstBody.categoryBitMask == playerHitCategory && secondBody.categoryBitMask == ballHitCategory) || 
           (firstBody.categoryBitMask == ballHitCategory && secondBody.categoryBitMask == playerHitCategory))
            {
                NSLog(@"ball hits player");
            }
    

    This way you can seperate the collision between the objects. Do the same for other object you desire to detect collision with.

    Note that you are also setting the bit masks wrong for each physics body object. Read here look for the section : "Collision and Contact Example: Rockets in Space"

    It is very important to understand what each mask property is used for collisions to be detected correctly. (otherwise you indeed can go nuts about it;))