I'm making a drag and drop game, and attempting to use physicsBodies to detect contacts between 1 static object and the object being dragged by the user.
I've searched on here for hours, and watched tutorials online, but all I keep seeing is contact detection working with dynamic nodes (such as projectiles). I don't need collisions because nothing happens to any of the nodes when they intersect, I just need contact detection to implement game logic.
I originally had a working solution using CGRectContainsPoint and CGRectContainsRect, but it's super buggy and after doing some research I realized that it's not the correct way to implement contact/collisions in SK.
I've got my bitMask setup like so:
//contact bit masks
typedef NS_OPTIONS(uint32_t, ContactCategory) {
ContactCategoryTile = 1 << 0, //0000
ContactCategoryKey = 1 << 1, //0010
ContactCategoryRotor = 1 << 2, //0100
};
My selected node setup like so:
#import "TileNode.h"
#import "Utilities.h"
@interface TileNode ()
@end
@implementation TileNode
+(instancetype)tileNodeAtPosition:(CGPoint)position
tileComboScore:(NSInteger)comboScore
tileArray:(NSArray*)array
randomNumber:(int)randomNumber
initialCombo:(NSInteger)initCombo
{
//custom node properties
TileNode *tileNode = [array objectAtIndex:randomNumber];
tileNode.position = position;
tileNode.size = CGSizeMake(23, 63);
//using label property from .h file and parenting to generated tileNode
tileNode.comboLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
tileNode.comboLabel.fontColor = [UIColor whiteColor];
tileNode.comboLabel.text = [NSString stringWithFormat: @"%d",initCombo];
tileNode.comboLabel.fontSize = 12;
tileNode.comboLabel.position = CGPointMake(13, 45);
[tileNode setupPhysicsBody];
[tileNode addChild:tileNode.comboLabel];
return tileNode;
}
-(void)setupPhysicsBody
{
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.frame.size];
NSLog(@"tileframe %@", NSStringFromCGRect(self.frame));
self.physicsBody.dynamic = NO;
self.physicsBody.categoryBitMask = ContactCategoryTile;
self.physicsBody.contactTestBitMask = ContactCategoryTile | ContactCategoryRotor | ContactCategoryKey;
self.physicsBody.collisionBitMask = 0;
}
My destination node type setup up like so:
#import "KeyNode.h"
#import "Utilities.h"
@implementation KeyNode
+(instancetype)keyNodeAtPosition:(CGPoint)position
{
//custom class properties for generic yellow nodes in UI
KeyNode *keyTile = [KeyNode spriteNodeWithImageNamed:@"key"];
keyTile.position = position;
keyTile.size = CGSizeMake(25, 65);
keyTile.anchorPoint = CGPointMake(0.5, 0.5);
keyTile.name = @"keyNode";
[keyTile setupPhysicsBody];
return keyTile;
}
-(void)setupPhysicsBody
{
self.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.frame.size];
NSLog(@"keyframe %@", NSStringFromCGRect(self.frame));
self.physicsBody.dynamic = NO;
self.physicsBody.categoryBitMask = ContactCategoryKey;
self.physicsBody.contactTestBitMask = ContactCategoryTile;
self.physicsBody.collisionBitMask = 0;
}
And my contact detection delegate method like so:
-(void)didEndContact:(SKPhysicsContact *)contact
{
NSLog(@"Working!");
//Condition for tile and key contact
if (contact.bodyA.categoryBitMask == ContactCategoryTile && contact.bodyB.categoryBitMask == ContactCategoryKey)
{
NSLog(@"Tile contact with key");
}
//condition for tile and tile contact
else if (contact.bodyA.categoryBitMask == ContactCategoryTile && contact.bodyB.categoryBitMask == ContactCategoryTile)
{
NSLog(@"Tile contact with tile");
}
//condition for tile and rotor contact
else if(contact.bodyA.categoryBitMask == ContactCategoryTile && contact.bodyB.categoryBitMask == ContactCategoryRotor)
{
NSLog(@"Tile contact with rotor");
}
}
And both nodes are being instantiated in initWithSize like so:
CGPoint position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 180);
TileNode *tileNode1 = [TileNode tileNodeAtPosition:position tileComboScore:self.comboScore tileArray:tileImagesArray randomNumber:randomTileGenerator initialCombo:self.initialCombo];
[self addChild:tileNode1];
KeyNode *keyNode1 = [KeyNode keyNodeAtPosition:CGPointMake(CGRectGetMidX(self.frame) - 100, CGRectGetMidY(self.frame) - 15)];
[self addChild:keyNode1];
Any help would be greatly appreciated.
I found the answer in a thread from last year that worked. You can work around wanting static bodies to have collisions.
If you set the gravity to be non-existent and make your static nodes dynamic it works:
self.physicsWorld.gravity = CGVectorMake(0, 0);
self.physicsBody.dynamic = YES;