Search code examples
sprite-kitcollision-detectionskspritenode

Collision without sprites colliding


I have some simple code that adds a block sprite at the leftmost part of a tile like this :

block.position = CGPointMake((-self.size.width * 0.5), 0);
[self addChild:block];

Since the anchor point is in the middle of the block sprite. self refers to the actual tile.

This works fine and indeed adds the block on the left side of the tile sprite.

Now I also have a player sprite that can collide with that block if it tries to go through it. That also works just fine.

The problem happened when i tried to get the block sprite to show in the exact same spot using another anchor point (i need a new anchor point for a shrink effect i wanted to create - which appears to work fine btw).

The new code becomes :

block.position = CGPointMake(-(self.size.width * 0.5), -(self.size.width * 0.5));
block.anchorPoint = CGPointZero;
[self addChild:block];

The new block appears in a similar to the first case position (though not totally identical). I am not sure why the position is not identical but i can fix that by adding/subtracting 1 or 2 from the x,y points.

The weird problem is that if my player sprite now tries to go below that block on the tile below (which is an open tile without any blocks), i get a contact between the player and the block.

I have even added debug paths with SKShapeNode to make sure that the player and block sprites do not actually collide. And they don't ! But i still get a collision event.

The player scale is (0.8, 0.9), but i don't think this would play much of a role.

I really don't get why this could be happening. Any ideas guys ?


Solution

  • Changing the sprite's anchor point have no effect on the physics body.

    When talking about CGRect, the rect origin is at point {0, 0},

    So what is happening is that you now have a sprite that its image is centred around anchor point {0, 0} but with a physics body, that starts at {0, 0} and is the size of the sprite, meaning that it is centred around {0.5, 0.5}.
    So even that the player doesn't collide with the image of the sprite, it does collide with its physics body.

    What is happening is that you have a physics body, that before had the same centre point as the sprite,
    But as oppose to before, where the sprite anchor point were in the middle, which would 'fit' into the physics body,
    Now the sprite's anchor point is {0, 0}, which causes the physics body centre point, to actually be the most bottom left point of the sprite.

    To resolve this, you need to offset your physics body, so it will be centred around the new anchor point.

    For example:

    block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size center:CGPointZero];  
    

    CGPoint newCenter = CGPointMake(block.size.width, block.size.height);
    block.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:block.size centre:newCenter];  
    

    Good luck mate.

    EDIT- On a second thought, I think I got confused with the offset directions.
    An edit has been made to correct it.