I'm using Chipmunk 6.0.3 (plain C version) to make a simple game (iPad) in which the user can throw balls around inside a square frame. The space inside the frame has no gravity and the ball just bounces around indefinitely, without losing / gaining any speed. I'd like the user to be able to rotate the frame whist the ball is still bouncing, however this is causing some issues for me.
When the frame gets rotated, the path of the ball gets affected in that it starts to curve in the opposite direction that the frame is spinning. This is only a slight curvature, but it is noticeable. Also, the ball sometimes tends to pass through the bounds of the frame, sometimes getting stuck in the edges which causes it to just follow the spinning frame. It's like it's getting sucked in.
These effects only happen when the frame is spinning, and when it is spinning at a slow speed. If the angular velocity is set above 10, everything works well.
As everything is fine when the frame is not rotating, I was wondering if there are things I should be aware of when manually rotating the frame.
I tried adding the cpSpaceReindexShapesForBody method after every rotation, but that didn't help.
The code I'm using is an adapted version of the Tumble demo.
Code: Select all
//Make a space
cpSpace *room = cpSpaceNew();
cpSpaceSetGravity(room, cpvzero);
cpSpaceSetDamping(room, 1.0f);
cpSpaceSetCollisionSlop(room, 0.9);
//Add an infinite mass rogue body. Bounds is the size of the UIView that holds the frame
cpBody *squareFrame = cpBodyNew(INFINITY,INFINITY);
cpBodySetPos(squareFrame, cpv(bounds.size.width * 0.5,bounds.size.width * 0.5));
//Add four segement shapes to the rogue body. These create the frame for the ball bounce around in. The cushion variable is thickness of the segments.
int size = bounds.size.width;
cpFloat cushion = 100.0f;
cpVect a = cpv(-(size * 0.5) - cushion, -(size * 0.5) - cushion);
cpVect b = cpv((size * 0.5) + cushion, -(size * 0.5) - cushion);
cpVect c = cpv((size * 0.5) + cushion, (size * 0.5) + cushion);
cpVect d = cpv(-(size * 0.5) - cushion, (size * 0.5) + cushion);
cpFloat friction = 0.0f;
cpFloat elastic = 1.0f;
cpDataPointer mySelf = (__bridge void*) self;
cpShape *shape2;
shape2 = cpSpaceAddShape(room, cpSegmentShapeNew(squareFrame, a, b, cushion));
cpShapeSetElasticity(shape2, elastic);
cpShapeSetFriction(shape2, friction);
cpShapeSetCollisionType(shape2, 7);
shape2->data = mySelf;
shape2 = cpSpaceAddShape(room, cpSegmentShapeNew(squareFrame, b, c, cushion));
cpShapeSetElasticity(shape2, elastic);
cpShapeSetFriction(shape2, friction);
cpShapeSetCollisionType(shape2, 8);
shape2->data = mySelf;
shape2 = cpSpaceAddShape(room, cpSegmentShapeNew(squareFrame, c, d, cushion));
cpShapeSetElasticity(shape2, elastic);
cpShapeSetFriction(shape2, friction);
cpShapeSetCollisionType(shape2, 9);
shape2->data = mySelf;
shape2 = cpSpaceAddShape(room, cpSegmentShapeNew(squareFrame, d, a, cushion));
cpShapeSetElasticity(shape2, elastic);
cpShapeSetFriction(shape2, friction);
cpShapeSetCollisionType(shape2, 10);
shape2->data = mySelf;
//This is where the ball gets added to the space. It's triggered by a user touch event. The pt variable is a CGPoint for position, whilst v is a CGPoint for velocity.
cpFloat mass = 10;
cpFloat elastic = 1.0f;
cpBody *body = cpBodyNew(mass, INFINITY);
cpBodySetPos(body, cpv(pt.x, pt.y));
cpSpaceAddBody(room, body);
cpShape *shape = cpCircleShapeNew(body, 10.0f, cpvzero);
cpShapeSetElasticity(shape,elastic);
cpShapeSetFriction(shape, 0.0f);
cpSpaceAddShape(room, shape);
cpBodyApplyImpulse(shape->body, cpv(v.x * 2.5, v.y * 2.5), cpv(0, 0));
//The update method for the whole thing. Rotation is an external variable, again from a touch event.
cpBodySetAngVel(room, rotation);
cpBodyUpdatePosition(squareFrame, dt);
cpSpaceStep(room, dt);
Thanks,
James