Basically I'm trying to get a top-down game working where I can push objects (nothing fancy). I first got my player movement working how I wanted without using the control body. So I just have a cpBody and a cpCircleShape. Using the mouse I would set a goal position and then use cpBodySlew() to move towards that goal position. Everything was working as expected that way. Then I tried to add the control body like the tank demo does and all hell broke loose ^_^. So I thought I could simply set up the control body and the pivot joint, and then run cpBodySlew() on my control body and everything would just work. However I'm getting a lot of unexpected behavior (I'm sure it's expected, I'm just not expecting it).
1) Does cpBodySlew work on static bodies that aren't part of the space? As far as I can see, it has no effect.
2) Do I need to manually update the control body position after the body is updated? From what I'm seeing, my normal body is anchored to the position of the static body, but with some amount of give. From looking at the tank demo, it looks like the control body position is never updated. However I can only get my body to move if I update the control body position after I call cpSpaceStep().
3) When I do manually update the control body, and then try to collide with another object with the same settings, they appear to stop each other, but they are very jittery. My guess would be that they are continually trying to get to their goal and so you get the jitter as they attempt to reach it. The objects also are overlapping quite a bit. I'm essentially trying to create two tanks which can push each other (depending on which one you are controlling).
4) At the moment I'm not worried about objects rotating when they collide, do I still need to use the gear constraint (could this be part of my problem since I'm excluding it)? When I add in the gear constraint, things seem to get much worst (I'm sure I'm doing it wrong ;_;).
Here is how I am setting up the objects:
Code: Select all
// create bodies
body = cpBodyNew(1.0f, 1.0f);
controlBody = cpBodyNew(INFINITY, INFINITY);
// create shape
shape = cpCircleShapeNew(body, 32.0f, cpv(0.0f, 0.0f));
shape->e = 0.0f;
shape->u = 1.0f;
shape->group = CP_GROUP_PLAYERS + playerId;
shape->collision_type = CP_COLLISION_TYPE_PLAYER;
shape->data = self;
pivot = cpPivotJointNew2(controlBody, body, cpvzero, cpvzero);
pivot->biasCoef = 0.0f; // disable joint correction
pivot->maxForce = 10000.0f; // emulate linear friction
// init position
body->p = cpv(spawnPoint.x, spawnPoint.y);
controlBody->p = body->p; // body will appear at (0, 0) if I don't initialize control body position
// add objects to space
cpSpaceAddBody(space, body);
cpSpaceAddShape(space, shape);
cpSpaceAddConstraint(space, pivot);
Code: Select all
CGPoint diff = ccp(abs(self.position.x - goalPosition.x),
abs(self.position.y - goalPosition.y));
if (diff.x < 10.0f && diff.y < 10.0f) {
// update chipmunk body
//cpBodySlew(body, self.position, elapsedTime);
controlBody->v = cpvzero;
return;
}
// figure out our new position
float delta = velocity * elapsedTime;
CGPoint direction = ccpSub(goalPosition, self.position);
direction = ccpNormalize(direction);
CGPoint newPosition = ccpAdd(self.position, ccpMult(direction, delta));
// update chipmunk body (hacked out cpBodySlew() basically)
// cpBodySlew(body, newPosition, elapsedTime);
cpVect deltaPosition = cpvsub(newPosition, body->p);
cpVect deltaDirection = cpvnormalize(deltaPosition);
cpVect velocity = cpvzero;
if (deltaDirection.x != 0 && elapsedTime != 0)
velocity.x = deltaPosition.x / (deltaDirection.x * elapsedTime);
if (deltaDirection.y != 0 && elapsedTime != 0)
velocity.y = deltaPosition.y / (deltaDirection.y * elapsedTime);
controlBody->v.x = deltaDirection.x * velocity.x;
controlBody->v.y = deltaDirection.y * velocity.y;
Code: Select all
- (void)chipmunkUpdate {
// sync sprite with chipmunk body
self.position = body->p;
controlBody->p = body->p;
}