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")
}
}
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
}
}
}
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With