Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if player is on top of another node?

I'm trying to allow my player to jump. However I cannot let him jump in mid-air so I need to check if it's standing on top of another node before applying an impulse.

How do other sprite-kit games normally do this?


Right now I'm trying two approaches, the first one is this one. It's great however I don't know how to tell if the node the player is touching is really below or to the side of the player.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    var allowJump = false
    let bodies = player.physicsBody.allContactedBodies()
    for body : AnyObject in bodies {
        if let node = body.node {
            allowJump = true // Player is touching another node but we don't know where (the bottom of the player or it's sides)
        }
    }
}

This is the other approach, it's effective to tell if a contact started and also whether the contact is really with the ground (below the player) and not a wall or such. However I don't know how to tell when the player stops being on top of any nodes, because even if a contact ends he might still be contacting another node.

func didBeginContact(contact: SKPhysicsContact!){
    if(contact.bodyA.node.position.y < contact.contactPoint.y) {
        println("BodyA is on top of another node")
    }

    if(contact.bodyB.node.position.y < contact.contactPoint.y) {
        println("BodyB is on top of another node")
    }
}

func didEndContact(contact: SKPhysicsContact!){
     if(contact.bodyA.node.position.y < contact.contactPoint.y) {
        println("BodyA is on no longer on top of BodyB")
    }

    if(contact.bodyB.node.position.y < contact.contactPoint.y) {
        println("BodyB is no longer on top of BodyA")
    }
}
like image 680
lisovaccaro Avatar asked Jul 18 '14 17:07

lisovaccaro


2 Answers

This is what I'm doing now however it doesn't let me know if the node it's touching is below/left/right. I could simply compare its position to my node however some nodes are hollow like edgeLoopFromPath or have different shapes.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    var allowJump = false
    let bodies = player.physicsBody.allContactedBodies()
    for body : AnyObject in bodies {
        if let node = body.node { // Additionally check contactBitMask
            allowJump = true
        }
    }
}
like image 189
lisovaccaro Avatar answered Oct 10 '22 06:10

lisovaccaro


typedef  NS_OPTIONS(uint32_t, CNPhysicsCategory)
{
    CNPhysicsCategoryChick = 1,
    CNPhysicsCategoryEdge = 2,
    CNPhysicsCategoryStrawberry = 3,
};

@interface MyScene() <SKPhysicsContactDelegate>

@end


@implementation MyScene
{
    SKSpriteNode *strawberry;
    SKSpriteNode *chick;

}

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

        self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
        self.physicsBody.categoryBitMask = CNPhysicsCategoryEdge;
        self.physicsWorld.contactDelegate = self;
        self.physicsBody.restitution = 0.0;

        chick = [SKSpriteNode spriteNodeWithImageNamed:@"chick"];
        [chick setScale:0.3];
        chick.position = CGPointMake(self.size.width/2, chick.size.height/2);
        chick.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:chick.size];
        chick.physicsBody.categoryBitMask = CNPhysicsCategoryChick;
        chick.physicsBody.collisionBitMask = CNPhysicsCategoryEdge;
        chick.physicsBody.restitution = 0.0;
        [self addChild:chick];


        strawberry = [SKSpriteNode spriteNodeWithImageNamed:@"strawberry"];
        strawberry.position = CGPointMake(chick.position.x, chick.position.y - chick.size.height/2 + strawberry.size.height/2);

        //You should make this hidden
        //strawberry.hidden = YES;

        strawberry.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: CGSizeMake(strawberry.size.width, strawberry.size.height)];
        strawberry.physicsBody.categoryBitMask = CNPhysicsCategoryStrawberry;
        strawberry.physicsBody.collisionBitMask = kNilOptions;
        strawberry.physicsBody.contactTestBitMask = CNPhysicsCategoryEdge;
        strawberry.physicsBody.density = 0.001;
        strawberry.physicsBody.restitution = 0.0;
        [self addChild:strawberry];

        SKPhysicsJointFixed *point = [SKPhysicsJointFixed jointWithBodyA:strawberry.physicsBody bodyB:chick.physicsBody anchor:CGPointZero];
        [self.physicsWorld addJoint:point];
    }
    return self;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    [chick.physicsBody applyImpulse:CGVectorMake(0, 60)];
}

-(void)didBeginContact:(SKPhysicsContact *)contact
{
    uint32_t collision = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);

    if (collision == (CNPhysicsCategoryEdge | CNPhysicsCategoryStrawberry)) {
        NSLog(@"In Contact");
    }
}

-(void)didEndContact:(SKPhysicsContact *)contact
{
    uint32_t collision = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask);

    if (collision == (CNPhysicsCategoryEdge | CNPhysicsCategoryStrawberry)) {
        NSLog(@"Contact Is Lost");
    }
}


@end

enter image description hereenter image description here

like image 2
Ahmet Hayrullahoglu Avatar answered Oct 10 '22 06:10

Ahmet Hayrullahoglu