1

I have two nodes and a boolean. Simple enough. When node A contacts Node B and the boolean is 0, nothing happens. However if the boolean is 1, Node A is removed through the didBeganContact method.

Extremely simple, however I have an annoying problem on when I want Node A removed.

Node B is a rectangle and node A is a square going in the middle of the rectangle, the boolean is called and turned into 1 when I tap and hold the Node B using the touchesBegan method. Now before Node A contacts Node B, I tap and hold Node B and when Node A contacts, its removed, but when Node A is already in the middle, and I tap Node B, nothing happens and I don't know why.

Rectangle Method

-(void)rectangle
{
SKSpriteNode *rectangle = [[SKSpriteNode alloc] init];
rectangle = [SKSpriteNode spriteNodeWithColor:[UIColor blueColor] size:CGSizeMake(75, 150)];
rectangle.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
rectangle.name = @"rect";
rectangle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:rectangle.size];
rectangle.physicsBody.categoryBitMask = rectangleCategory;
rectangle.physicsBody.contactTestBitMask = fallingSquareCategory;
rectangle.physicsBody.collisionBitMask = 0;

[self addChild:rectangle];
}

touchesBeganMethod

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

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];

if ([node.name isEqualToString:@"rect"])
{
    radBool = 1;
}
}

touchesEnded

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

UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];

if ([node.name isEqualToString:@"rect"])
{
    radBool = 0;
}
}

square Method

-(void)square
{
SKAction *move = [SKAction moveToY:CGRectGetMidY(self.frame) duration:1.75];

SKSpriteNode *fallingSquare = [[SKSpriteNode alloc] init];
fallingSquare = [SKSpriteNode spriteNodeWithColor:[UIColor yellowColor] size:CGSizeMake(75, 75)];
fallingSquare.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMaxY(self.frame));
fallingSquare.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:fallingSquare.size];
fallingSquare.physicsBody.categoryBitMask = fallingSquareCategory;
fallingSquare.physicsBody.contactTestBitMask = rectangleCategory
fallingSquare.physicsBody.collisionBitMask = 0;

[self addChild:fallingSquare];
[fallingSquare runAction:move];
}

didBeginContact

static inline SKSpriteNode *nodeFromBody(SKPhysicsBody *body1, SKPhysicsBody *body2, uint32_t category) {
SKSpriteNode *node = nil;
if (body1.categoryBitMask & category) {
    node = (SKSpriteNode *)body1.node;
}
else if (body2.categoryBitMask & category) {
    node = (SKSpriteNode *)body2.node;
}
return node;
}

-(void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;

SKSpriteNode *R1 = nil;
SKSpriteNode *fallingS = nil;

firstBody = contact.bodyA;
secondBody = contact.bodyB;

R1 = nodeFromBody(firstBody, secondBody, rectangleCategory);
fallingS = nodeFromBody(firstBody, secondBody, fallingSquareCategory);

if (R1 && fallingS && radBool == 1)
{
    [fallingS removeFromParent];
}
}
CodeSmile
  • 64,284
  • 20
  • 132
  • 217
Blank
  • 113
  • 9
  • At first glance it sounds like you might have a zPosition issue. – sangony Feb 01 '15 at 14:08
  • @sangony I wish it were that simple, but it is not, I tried setting both nodes to the same position, one above the other, vice versa, and then got rid of the zPosition entirely as it didn't really change my results. – Blank Feb 01 '15 at 17:08

1 Answers1

3

I believe your issue is the "begin" part of didBeginContact. It only gets called the first time they contact and not every loop. Because the bool was not set to YES when they first contacted it will never be evaluated again.

I believe I ran into this issue once before and the solution was to create a new physical body when you touch it. This "should" trigger didBeginContact the next go around. You might also be able to change a property on the physical body, but if I recall correctly I didn't get that to work and had to init a new physical body.

For example try updating your touchesBegan with this

touchesBeganMethod

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

    UITouch *touch = [touches anyObject];
    CGPoint location = [touch locationInNode:self];
    SKNode *node = [self nodeAtPoint:location];

    if ([node.name isEqualToString:@"rect"])
    {
        radBool = 1;
        node.physicsBody = nil;
        node.physicsBody = [SKPhysicsBody     bodyWithRectangleOfSize:rectangle.size];
        node.physicsBody.categoryBitMask = rectangleCategory;
        node.physicsBody.contactTestBitMask = fallingSquareCategory;
        node.physicsBody.collisionBitMask = 0;
    }
}

Hope that works for you.

Skyler Lauren
  • 3,792
  • 3
  • 18
  • 30
  • Could you explain creating a new physical body with some sample code? I don't entirely understand. – Blank Feb 01 '15 at 20:36