Duck
Duck

Reputation: 36003

SpriteKit - physicsBody not respecting edge

I have this object that has a physicsBody created from a path.

The whole scene area ( = the whole screen) itself is the boundary from where this object should not escape.

This scene's boundary is defined by

self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];

Everything works almost as expected. The object collides and bounces on the edges and is constrained by them most part of the time, but if you insist several times, firing the object with high impulse to the edge the object will eventually do not respect the edge and escape, what is probably one more SpriteKit bug.

The object's class init is like this:

self.physicsBody.dynamic = YES;

CGFloat offsetX = self.frame.size.width/2.0f;
CGFloat offsetY = self.frame.size.height/2.0f;

CGMutablePathRef path = CGPathCreateMutable();

CGPathMoveToPoint(path, NULL, 60 - offsetX, 79 - offsetY);
CGPathAddLineToPoint(path, NULL, 96 - offsetX, 69 - offsetY);
CGPathAddLineToPoint(path, NULL, 124 - offsetX, 44 - offsetY);
CGPathAddLineToPoint(path, NULL, 120 - offsetX, 23 - offsetY);
CGPathAddLineToPoint(path, NULL, 85 - offsetX, 0 - offsetY);
CGPathAddLineToPoint(path, NULL, 62 - offsetX, 3 - offsetY);
CGPathAddLineToPoint(path, NULL, 37 - offsetX, 19 - offsetY);
CGPathAddLineToPoint(path, NULL, 12 - offsetX, 29 - offsetY);
CGPathAddLineToPoint(path, NULL, 3 - offsetX, 39 - offsetY);
CGPathAddLineToPoint(path, NULL, 7 - offsetX, 58 - offsetY);
CGPathAddLineToPoint(path, NULL, 27 - offsetX, 46 - offsetY);
CGPathAddLineToPoint(path, NULL, 36 - offsetX, 61 - offsetY);

CGPathCloseSubpath(path);

self.physicsBody = [SKPhysicsBody bodyWithPolygonFromPath:path];
self.physicsBody.restitution = 0.0f;
self.physicsBody.usesPreciseCollisionDetection = YES;

What measures can I do to detect that and prevent the object from leaving the screen?

thanks.

Upvotes: 4

Views: 1264

Answers (1)

CodeSmile
CodeSmile

Reputation: 64477

I didn't trace the points but it looks like you have either a non-convex polygon or one where the vertices do not follow counter-clockwise winding, or both. Make sure the shape is convex and vertex order (winding) is in counter-clockwise order.

If this shape is intended to be a static (non-moving) body only for collision detection you can use bodyWithEdgeLoop or bodyWithEdgeChain where winding and convex shape don't matter.

PS: don't forget to release the path:

CGPathRelease(path);

Upvotes: 5

Related Questions