Xcode SpriteKit SKPhysics Collisions not Working

Discussion in 'iOS Programming' started by PrathmeshD, Apr 13, 2014.

  1. PrathmeshD, Apr 13, 2014
    Last edited: Apr 13, 2014

    PrathmeshD macrumors newbie

    Joined:
    Jun 18, 2011
    #1
    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?
     
  2. MattInOz macrumors 68030

    MattInOz

    Joined:
    Jan 19, 2006
    Location:
    Sydney
    #2
    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.
     
  3. PrathmeshD thread starter macrumors newbie

    Joined:
    Jun 18, 2011
    #3
    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?
     
  4. mds1256 macrumors regular

    Joined:
    Apr 9, 2011
    #4
    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...
     
  5. PrathmeshD thread starter macrumors newbie

    Joined:
    Jun 18, 2011
    #5
    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;
    
    
     
  6. AntoineLec, Apr 18, 2014
    Last edited: Apr 18, 2014

    AntoineLec macrumors newbie

    Joined:
    Jul 31, 2012
    #6
    _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; ?
     

Share This Page