Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS - bodyWithPolygonFromPath : Body is the same as the path but collisions are not working properly

First i'd like to say thanks to every users on this website because i'm always finding solutions here and it's sooo helpful !

I'm trying to make a game like Xonix, Bix or Jezzball with SpriteKit. Anyway, i have a ball bouncing against walls, and i'm trying to make obstacles where it can't go, those obstacles are made from CGPathref (the user makes it with its movements)

I'm using bodyWithPolygonFromPath to create the physicsbody of the skspritenode, it's working, but not always. I've downloaded YMCPhysicsDebugger to see the content of the body, and in every case, it's good, but i've seen that when i have more than 4 points on the CGPath, the ball does not collide against the whole of the body, it only collides against a smaller zone.. I've tried and searched a lot without any results.. I've tried to make the points of CGPath counterclockwise, it doesn't work as well, even in the other side..

I'm copying you the code for the creation of SKSpriteNode, but i doubt it will be useful, i think the problem is with my points, maybe i need more explanations on how the physicsbody works with a polygon

SKSpriteNode *zone = [SKSpriteNode spriteNodeWithColor:[UIColor redColor] size:CGSizeMake(50, 50)];
zone.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path.CGPath]; // 1
zone.physicsBody.friction = 0.0f;
zone.physicsBody.restitution = 0.0f;
zone.physicsBody.linearDamping = 0.0f;
zone.physicsBody.allowsRotation = NO;
zone.physicsBody.categoryBitMask = wallsCategory;
zone.physicsBody.dynamic = NO; // 2
[self addChild:zone];

Here are two pictures of my "game", the first one works, the ball bounces right back against it. The second one is not working like it should, only the upper part is detected for collision.

http://hpics.li/86a69e2

http://hpics.li/e16d18e

I've also tried to detect when the ball enters an obstacle in the update function to manually make it bounce against it, but of course, it's not really working. Plus my math studies are not that good lol

for(SKSpriteNode *zone in zonesTab) 
{
    UIBezierPath *path = [zoneesTab objectAtIndex:i]; // Array of UIBezierPath for the obstacles
    if(CGPathContainsPoint(path.CGPath, NULL, ball.frame.origin, FALSE)) 
    {
        ball.physicsBody.velocity=CGVectorMake(ball.physicsBody.velocity.dx*-1, ball.physicsBody.velocity.dy*-1);
        NSLog(@"Touches iT");
    }
    i++;

}

I've also thought about making several SKSpriteNode everytime a CGPath has more than 4 points, but i don't really know how to do that in mathematics..

Anyway, that's a long post, I hope some of you will read it all and understand it all (sorry for my english, i'm french!) and most of all, will be able to help me !!

Thank you very much

like image 594
user3198930 Avatar asked Jan 15 '14 16:01

user3198930


1 Answers

The shape in the first screenshot is convex but the shape in the second screenshot is concave.

The physics polygon shapes need to be convex for them to work correctly. You can do one of two things:

  • Create two nodes and two bodies whose individual shapes are convex but together they form the concave shape. These bodies can be dynamic. You may want to set them to static or connect them together with a rigid distance joint, or otherwise ensure they are not going to move apart.
  • Use bodyWithEdgeLoopFromPath: or bodyWithEdgeChainFromPath: to be able to create concave collision shapes. These bodies will not be dynamic and won't be able to move by themselves but they are the perfect solution for arbitrary collision shapes with a static playfield.
like image 103
LearnCocos2D Avatar answered Nov 17 '22 19:11

LearnCocos2D