2

i'm trying to make a game where obstacles fall from the top of the screen and the player has to try to avoid them, but the didBeginContact method is not getting called and its driving me crazy. here are the parts of my code relevant to the node collisions...

//myScene.h
@interface MyScene : SKScene <SKPhysicsContactDelegate>

//myScene.m
@implementation MyScene

static const uint32_t playerCategory = 0x1 << 0;
static const uint32_t obstacleCategory = 0x1 << 1;

-(id)initWithSize:(CGSize)size
{
    if (self = [super initWithSize:size])
    {
        //setup scene
        self.backgroundColor = [SKColor whiteColor];
        self.physicsWorld.gravity = CGVectorMake(0, 0);
        self.physicsWorld.contactDelegate = self;
        obstacles = [NSMutableArray array];

        //add player node
        player = [SKNode node];
        SKSpriteNode *spritePlayer = [SKSpriteNode spriteNodeWithImageNamed:@"black.png"];
        spritePlayer.size = CGSizeMake(50, 50);
        spritePlayer.position = CGPointMake(self.frame.size.width/2, 100);
        player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.frame.size];
        player.physicsBody.dynamic = NO;
        player.physicsBody.mass = 0.02;
        [player addChild:spritePlayer];

        player.physicsBody.categoryBitMask = playerCategory;
        player.physicsBody.contactTestBitMask = obstacleCategory;
        player.physicsBody.collisionBitMask = 0;
        player.physicsBody.usesPreciseCollisionDetection = YES;

        [self addChild:player];
        [self spawnNewObstacles];

    }
    return self;
}

- (void)spawnNewObstacles
{
    //spawn obstacles
    obstacle = [SKSpriteNode spriteNodeWithImageNamed:@"black.png"];

    obstacle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:obstacle.frame.size];
    obstacle.physicsBody.dynamic = YES;

    obstacle.physicsBody.categoryBitMask = obstacleCategory;
    obstacle.physicsBody.contactTestBitMask = playerCategory;
    obstacle.physicsBody.collisionBitMask = 0;
    obstacle.physicsBody.usesPreciseCollisionDetection = YES;
}

-(void)didBeginContact:(SKPhysicsContact *)contact
{
    NSLog(@"didBeginContact Called!");

}

the didBeginContact method is not getting called and i can't find what wrong with my code all help is appreciated...

  • are you able to detect collisions with this code? and what is the exact problem you are facing with this code? what help do you need? – Harsh Apr 02 '14 at 07:08
  • no i can't detect any collision (i checked with NSLogs) and the didBeginContact method is not being called, plc help –  Apr 02 '14 at 07:20
  • may it will help :http://stackoverflow.com/questions/20572309/detecting-collisions-in-sprite-kit?rq=1 – Dhaval Bhadania Apr 02 '14 at 07:24
  • don't set the category bitmask unnecessarily like in your case, see: http://stackoverflow.com/a/22804376/201863 – CodeSmile Apr 02 '14 at 07:44
  • Ok it makes some sense, so ur suggesting I just get rid of the category bit mask lines? @LearnCocos2D –  Apr 02 '14 at 07:47
  • What is the purpose of adding the obstacle nodes to an array? Do you want to be able to access them further in the game? If so, for what? – ZeMoon Apr 02 '14 at 08:03
  • @akashg i need to add them to the array in order to remove them from the parent when they fall through the bottom of the screen. –  Apr 02 '14 at 08:24
  • Yes, don't change the category bitmask unless you have to change it, and know exactly why. – CodeSmile Apr 02 '14 at 08:45

1 Answers1

2

sknode size isn't set correctly because there is no image reference, and if you log its size if should be inf, and when I tested your code I returned an exception.

to fix this error change the following line

player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.frame.size]; change that to 

to the following and it should work

player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spritePlayer.size];

as I said below just ditch the player sknode, it is simply redundant unless there is a strong reason to use it. ///////previous answer

I couldn't help but to notice that you didn't add the obstacle node to any parent node, namely the scene, like what you did with the player node using this line

[self addChild:player];

you need to do the same thing with the obstacle node

[self addChild:obstacle];

, I am surprised that you didn't mention not seeing those nodes on the screen, unless you added them in a different section of your code that you did not include, then at this point I suggest you log the positions of both nodes to give an idea of how things are located on the screen.

as for the array you won't need it all you have to do is give a name for every obstacle node like @"obstacle", then you can use the following method to access all the nodes that has that name

obstacle.name = @"obstacle";

/////later when you want to check for node removal

[self enumerateChildNodesWithName:@"obstacle" usingBlock:^(SKNode *node, BOOL *stop) {
    SKSpriteNode *child = (SKSpriteNode*)node;
    if (child.position.y <0){ //or any arbitrary condition
         [child removeFromParent];
    }
}];

Lastly, I can't see the point from using the player as a sknode and then adding an skspritenode to it, unless I am missing something !!! :) . You can simply ditch the player sknode all together and simply use the spritePlayer node instead. Hope this helps.

rockstarr
  • 296
  • 1
  • 4
  • no i did have that line i just thought it was obvious that i had it and i had a bunch of other code not relevant to the collisions so i left it out of the post. my bad. –  Apr 02 '14 at 13:53
  • Do you scale the nodes or manipulate the physics bodies in any way in your code? – rockstarr Apr 02 '14 at 14:01
  • nope i don't, do u see anything wrong with the part assigning bitMasks? –  Apr 02 '14 at 14:03
  • I think I found the problem first there is nothing wrong with the bit assignment second I copied and pasted your code and the problem is in the following line player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.frame.size]; change that to line to the following and it should work player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:spritePlayer.size]; – rockstarr Apr 02 '14 at 14:12
  • whats wrong with it? BTW thanks for going through the trouble to do that. –  Apr 02 '14 at 14:13
  • please check the edited answer and the comments, I hope this fixes it. You are welcome, I struggle a lot with SK myself, I know how frustrating it could get, so I try to help when possible :D. – rockstarr Apr 02 '14 at 14:19
  • thnx this was starting to get on my nerves. this worked –  Apr 02 '14 at 14:24