Reputation: 121
I am working on PhysicsBody and get some troubles. First I don't really now if this is with PhysicsBody possible or only with pixel check.
The problem is: Contact check works pretty well but if a node is inside a PhysicsBody it won't be able to see if it collides. in the Pictures it is pretty well explained.
Some ideas how it works? Maybe PhysicsBody(Green Line) fill with the SKNode?
Here some Code: (Some explain: if Human moves inside Object and Touched is false nothing happened and it is okay but if Human is moved inside Object and Touched will be True nothing happened too and this is my problem.)
enum myContacts: UInt32 {
case None = 0
case All = 0xFFFFFFFF
case Object = 0b001
case Human = 0b010
}
class whatever...{
let Object = SKSpriteNode(imageNamed: "xyz")
Object.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
Object.physicsBody = SKPhysicsBody(circleOfRadius: Object.size.width/2)
Object.physicsBody?.dynamic = true
Object.physicsBody?.categoryBitMask = myContacts. Object.rawValue
Object.physicsBody?.contactTestBitMask = myContacts.Human.rawValue
Object.physicsBody?.collisionBitMask = 0
Object.physicsBody?.usesPreciseCollisionDetection = true
addChild(Object)
let Human = SKSpriteNode(imageNamed: "zyx")
Human.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
Human.physicsBody = SKPhysicsBody(circleOfRadius: Human.size.width/2)
Human.physicsBody?.dynamic = true
Human.physicsBody?.categoryBitMask = myContacts. Human.rawValue
Human.physicsBody?.contactTestBitMask = myContacts.Object.rawValue
Human.physicsBody?.collisionBitMask = 0
Human.physicsBody?.usesPreciseCollisionDetection = true
addChild(Human)
}
func didBeginContact(contact: SKPhysicsContact) {
if touched {
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
case myContacts.Object.rawValue | myContacts.Human.rawValue:
print("Human touched")
default:
break
}
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
touched = true
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
touched = false
}
Upvotes: 1
Views: 824
Reputation: 13675
Not sure if I completely understand what you are asking, but if you just want to detect a contact when node is spawned inside the space "taken" by another node, this code will work:
#import "GameScene.h"
static const uint32_t playerCategory = 0x1 << 0;
static const uint32_t obstacleCategory = 0x1 << 1;
@interface GameScene()<SKPhysicsContactDelegate>
@property (nonatomic, strong) SKSpriteNode *player;
@property (nonatomic, strong) SKSpriteNode *obstacle;
@end
@implementation GameScene
-(void)didMoveToView:(SKView *)view {
/* Setup your scene here */
self.physicsWorld.contactDelegate = self;
[self initializeNodes];
}
-(void)initializeNodes{
self.player = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(50,50)];
self.player.name = @"player";
self.player.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
self.player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.player.size];
self.player.physicsBody.collisionBitMask = 0;
self.player.physicsBody.categoryBitMask = playerCategory;
self.player.physicsBody.affectedByGravity = NO;
self.player.physicsBody.contactTestBitMask = obstacleCategory;
self.player.zPosition = 10;
[self addChild:self.player];
self.obstacle = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:CGSizeMake(100,100)];
self.obstacle.name = @"obstacle";
self.obstacle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
self.obstacle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.obstacle.size];
self.obstacle.physicsBody.collisionBitMask = 0;
self.obstacle.physicsBody.categoryBitMask = obstacleCategory;
self.obstacle.physicsBody.affectedByGravity = NO;
self.obstacle.physicsBody.contactTestBitMask = playerCategory;
self.obstacle.zPosition = 8;
[self addChild:self.obstacle];
}
-(void)didBeginContact:(SKPhysicsContact *)contact{
NSLog(@"Contact detected!");
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
@end
Here, everything is pretty much straight forward:
If you copy & paste this code and run it, what you are going to see in the console is the message which says : "Contact detected".
I guess that is the same situation from the second picture (where you are saying that contact is not detected).
Also, if you continue to move the player (while a player is inside of an obstacle's bounds), the further contacts will not be detected. Player have to leave the bounds of an obstacle first. But still, you can check the return value of allContactBodies method which returns an array of SKPhysicsBody objects that current body (player's physics body) is in contact with.
Upvotes: 1