Question

Hi.

I'm having this weird problem in Sprite Kit. I'm using nodeAtPoint and categoryBitMask to detect whether the player is touching the ground when calling a jump method.

Everything's working as it should. But then — in order to reveal some optional buttons in a drawer — when I move the parent node with SKAction moveTo:CGPoint (I have both the ground and player as children of an SKNode), the player don't jump. I NSLog the pointBelowPlayer, and it is the same as before, but the blockNode.physicsBody is null! Might this be a bug in Sprite Kit, or am I missing something basic about inheritance and position?

The method for jumping:

-(void)playerJump {

    // Player jump if on ground
    CGPoint pointBelowPlayer = CGPointMake(_player.position.x, _player.position.y-_player.size.height);
    SKNode *blockNode = [self nodeAtPoint:pointBelowPlayer];

    if (blockNode.physicsBody.categoryBitMask == groundCategory){
        [_player.physicsBody applyImpulse:CGVectorMake(0, 120.0f)];
    }
}

The method for moving the parent node:

-(void)toggleDrawer {
    if (bDrawerVisible) {
        [_actionLayer runAction:[SKAction moveTo:CGPointMake(0, 0) duration:1]];
        bDrawerVisible = false;
    } else {
        [_actionLayer runAction:[SKAction moveTo:CGPointMake(0, 200) duration:1]];
        bDrawerVisible = true;
    }
}

Creation of the SpriteNodes:

-(id)initWithSize:(CGSize)size {
    if (self = [super initWithSize:size]) {

        _actionLayer = [SKNode new];

        _player = [self createPlayer];
        [_actionLayer addChild:_player];

        _ground = [self createGround];
        [_actionLayer addChild:_ground];
}

-(SKSpriteNode *)createPlayer {

    SKSpriteNode *player = [SKSpriteNode spriteNodeWithImageNamed:@"redSquare.png"];
    player.name = @"player";
    player.scale = 0.5;
    player.position = CGPointMake(screenWidth/3, player.size.height*2);
    player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.size];
    player.physicsBody.categoryBitMask = playerCategory;
    player.physicsBody.collisionBitMask = groundCategory;
    player.physicsBody.contactTestBitMask = noteCategory;

    return player;
}

-(SKSpriteNode *)createGround {

    SKSpriteNode *ground = [SKSpriteNode spriteNodeWithImageNamed:@"ground.png"];
    ground.name = @"ground";
    ground.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ground.size];
    ground.physicsBody.dynamic = NO;
    ground.physicsBody.categoryBitMask = groundCategory;
    ground.physicsBody.collisionBitMask = playerCategory;
    ground.xScale = screenWidth/ground.size.width;;
    ground.position = CGPointMake(self.size.width/2, 0);

    return ground;
}
Was it helpful?

Solution

Ok i solve the problem... if you have more then one Node, on the position you tap, you will get null if the deepest node have no name, or the name of the deepest Node.

So use this to go through all nodes are found:

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
NSArray *buttonNodes = [self nodesAtPoint:location];
for (SKNode *node in buttonNodes)
{
    NSLog(@"%@", node.name);
}

Additional you can use NSLog(@"%f", node.zPosition); to get the zPosition to see witch one is on top.

OTHER TIPS

Node at point might be another node (maybe your background?).
Use node.name to name the nodes and you may check if node if the same by comparing names with equalToString: method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top