iOS Xcode SpriteKit SKPhysics Collisions not Working

PrathmeshD

macrumors newbie
Original poster
Jun 18, 2011
4
0
When I run the code below I get a SIGABRT error, and I have looked everywhere and have tried everything to fix it to no avail. I am trying to use SKShapeNode and make it into a physics object with collisions.

Code:
static const uint32_t rockCategory            =  0x1 << 0;
static const uint32_t mineCartCategory        =  0x1 << 1;
static const uint32_t lineCategory            =  0x1 << 1;

@interface MyScene() <SKPhysicsContactDelegate, StartGameLayerDelegate, GameOverLayerDelegate>
{
    NSTimeInterval _dt;
    float bottomScrollerHeight;
    
    BOOL _gameStarted;
    BOOL _gameOver;
    
    CGMutablePathRef pathToDraw;
    SKShapeNode *lineNode;
    
    StartGameLayer* _startGameLayer;
    GameOverLayer* _gameOverLayer;
    
    int _score;
}

#pragma mark - Touches

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    
    pathToDraw = CGPathCreateMutable();
    CGPathMoveToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
    lineNode = [SKShapeNode node];
    lineNode.path = pathToDraw;
    lineNode.strokeColor = [SKColor redColor];
    lineNode.zPosition = 125;
    lineNode.physicsBody = [SKPhysicsBody bodyWithEdgeChainFromPath:lineNode.path];
    lineNode.physicsBody.categoryBitMask = lineCategory;
    lineNode.physicsBody.contactTestBitMask = mineCartCategory;
    lineNode.physicsBody.collisionBitMask = 0;
    lineNode.physicsBody.affectedByGravity = NO;
    [self addChild:lineNode];
}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
    UITouch* touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    CGPathAddLineToPoint(pathToDraw, NULL, positionInScene.x, positionInScene.y);
    lineNode.path = pathToDraw;
}

#pragma mark - Collisions

- (void)rock:(SKSpriteNode *)pillar didCollideWithCart:(SKSpriteNode *)cart
{
    [self showGameOverLayer];
    [lineNode removeFromParent];
    
}

- (void)line:(SKSpriteNode *) lines didCollideWithCart:(SKSpriteNode *) cart
{
    [self showGameOverLayer];
    [lineNode removeFromParent];
}

- (void)didBeginContact:(SKPhysicsContact *)contact
{
    SKPhysicsBody *firstBody, *secondBody;
    
    if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
    {
        firstBody = contact.bodyA;
        secondBody = contact.bodyB;
    }
    else
    {
        firstBody = contact.bodyB;
        secondBody = contact.bodyA;
    }
    
    if ((firstBody.categoryBitMask & rockCategory) != 0 &&
        (secondBody.categoryBitMask & mineCartCategory) != 0)
    {
        [self rock:(SKSpriteNode *) firstBody.node didCollideWithCart:(SKSpriteNode *) secondBody.node];
    }
    else if ((firstBody.categoryBitMask & lineCategory) != 0 &&
             (secondBody.categoryBitMask & mineCartCategory) != 0)
    {
        [self line:(SKSpriteNode *) firstBody.node didCollideWithCart:(SKSpriteNode *) secondBody.node];
    }
}
Look at my comment below. The line and the cart are set to collide and end game according to my code but none of this happens, and rather they completely ignore each other. Is there something wrong in my code?
 
Last edited:

MattInOz

macrumors 68030
Jan 19, 2006
2,755
0
Sydney
What does the log file say?
If you can't work out the problem from there post what it says then someone else may be able to help.
 

PrathmeshD

macrumors newbie
Original poster
Jun 18, 2011
4
0
Code Changed

I fixed the SIGABRT error by changing the physicsBody to

Code:
lineNode.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:lineNode.path];
But when I run the program the physics bodies I've set to collide don't even interact. They just ignore each other...is there a way to change that?
 

mds1256

macrumors regular
Apr 9, 2011
143
27
Think you have a problem with the category set up:

Code:
static const uint32_t rockCategory            =  0x1 << 0;
static const uint32_t mineCartCategory        =  0x1 << 1;
static const uint32_t lineCategory            =  0x1 << 1;
Should be:

Code:
static const uint32_t rockCategory            =  0x1 << 0;
static const uint32_t mineCartCategory        =  0x1 << 1;
static const uint32_t lineCategory            =  [B]0x1 << 2;[/B]
Two catagories had the same bitmask... Not sure if it will fix all your problems though...
 

PrathmeshD

macrumors newbie
Original poster
Jun 18, 2011
4
0
Still not working

Thanks I didn't notice that! I changed it and it still does not work.

Here are the lines that I have changed.

Code:
static const uint32_t rockCategory            =  0x1 << 0;
static const uint32_t mineCartCategory        =  0x1 << 1;
static const uint32_t lineCategory            =  0x1 << 2;

...

    _mineCart.physicsBody.collisionBitMask = rockCategory & lineCategory;

...

    lineNode.physicsBody.collisionBitMask = mineCartCategory;
 

AntoineLec

macrumors member
Jul 31, 2012
30
2
_mineCart.physicsBody.collisionBitMask = rockCategory & lineCategory;

means:

_mineCart.physicsBody.collisionBitMask = 0;

which means does not collide with anything.
Didn't you mean:
_mineCart.physicsBody.collisionBitMask = rockCategory | lineCategory; ?
 
Last edited: