cpSpaceEachShape and update sprites position

Official forum for the Chipmunk2D Physics Library.
Post Reply
returnvoid
Posts: 12
Joined: Sun Jan 22, 2012 5:17 pm
Contact:

cpSpaceEachShape and update sprites position

Post by returnvoid »

Hi everyone

Im so confused about a principleof Chipmunk and updating its CCSprites. I have many sprites with their shapes and bodys. Im calling cpSpaceEachShape in update every x time. In other side, im trying to drag the shapes inside the touch events. That is fine, but sprites dont update his positions when drag

-(id) init{
if( (self=[super init])) {
// enable events
self.isTouchEnabled = YES;
self.isAccelerometerEnabled = YES;
CGSize s = [[CCDirector sharedDirector] winSize];
CCDirectorIOS* director_ = (CCDirectorIOS*) [CCDirector sharedDirector];
[self initPhysics];

cpVect piedra1Verts[] = {
cpv(-19.038f, 11.095f),
cpv(-8.663f, 14.595),
cpv(18.962f, -6.155f),
cpv(18.962f, -10.905),
cpv(15.087f, -14.665f),
cpv(9.587f, -15.03f),
cpv(-9.788f, -7.655f),
cpv(-20.288f, 4.72f)};
cpVect piedra2Verts[] = {
cpv(1, 8),
cpv(8, 5),
cpv(9, -1),
cpv(3, -8),
cpv(-3, -9),
cpv(-8, -5),
cpv(-6, 8)};


CCSprite *p1 = [CCSprite spriteWithFile:@"2_piedra1.png"];
[self addChild:p1 z:10];
cpBody *p1Body = cpBodyNew(1, cpMomentForPoly(1, 8, piedra1Verts, cpvzero));
p1Body->p = ccp(607,617);
cpSpaceAddBody(space_, p1Body);
cpShape *p1Shape = cpPolyShapeNew(p1Body, 8, piedra1Verts, cpvzero);
p1Shape->e = 0.0f;p1Shape->u = 0.5f;
p1Shape->data = p1;
cpSpaceAddShape(space_, p1Shape);

CCSprite *p2 = [CCSprite spriteWithFile:@"2_piedra2.png"];
[self addChild:p2 z:10];
cpBody *p2Body = cpBodyNew(1, cpMomentForPoly(1, 7, piedra2Verts, cpvzero));
p2Body->p = ccp(713,630);
cpSpaceAddBody(space_, p2Body);
cpShape *p2Shape = cpPolyShapeNew(p2Body, 7, piedra1Verts, cpvzero);
p2Shape->e = 0.0f;p2Shape->u = 0.5f;
p2Shape->data = p2;
cpSpaceAddShape(space_, p2Shape);
}
return self;
}

-(void) initPhysics{
CGSize s = [[CCDirector sharedDirector] winSize];
cpInitChipmunk();
space_ = cpSpaceNew();
space_->gravity = ccp(0, -800);
// bottom
walls_[0] = cpSegmentShapeNew( space_->staticBody, ccp(0, 0), ccp(s.width,0), 0.0f);
// top
walls_[1] = cpSegmentShapeNew( space_->staticBody, ccp(0,s.height), ccp(s.width,s.height), 0.0f);
// left
walls_[2] = cpSegmentShapeNew( space_->staticBody, ccp(0,0), ccp(0,s.height), 0.0f);
// right
walls_[3] = cpSegmentShapeNew( space_->staticBody, ccp(s.width,0), ccp(s.width,s.height), 0.0f);
for( int i=0;i<4;i++) {
walls_->e = 1.0f;
walls_->u = 1.0f;
cpSpaceAddStaticShape(space_, walls_ );
}
}

static void eachShape(cpShape* shape, void* data){
//this run ok
CCSprite* sprite = (__bridge Rocas*)shape->data;
if (sprite != nil) {
cpBody* body = shape->body;
sprite.position = body->p;
sprite.rotation = CC_RADIANS_TO_DEGREES(body->a) * -1;
}
}

-(void) update:(ccTime) delta{
int steps = 2;
CGFloat dt = [[CCDirector sharedDirector] animationInterval]/(CGFloat)steps;
for(int i=0; i<steps; i++){
cpSpaceEachShape(space_, &eachShape, nil);
cpSpaceStep(space_, dt);
}

}

-(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event{
CGPoint location = [touch locationInView: [touch view]];
location = [[CCDirector sharedDirector] convertToGL: location];

CGPoint oldTouchLocation = [touch previousLocationInView:touch.view];
oldTouchLocation = [[CCDirector sharedDirector] convertToGL:oldTouchLocation];
oldTouchLocation = [self convertToNodeSpace:oldTouchLocation];

CGPoint translation = ccpSub(location, oldTouchLocation);
if (rocaActiva) {
CGPoint newPos = ccpAdd(rocaActiva.position, location);
//this is executing but the sprite position no changing
rocaActiva.position = newPos;
}
}

thanks
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: cpSpaceEachShape and update sprites position

Post by slembcke »

You are changing the position of the sprite. Then eachShape() will overwrite it the next frame. You need to move the body instead. You should look at how the Chipmunk demo app does its mouse control using joints.

Also, I don't recommend wasting the data pointers on sprites or iterating the shapes in a space to sync sprites. You should update your sprites to match the positions of your bodies when the sprites are drawn.
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
returnvoid
Posts: 12
Joined: Sun Jan 22, 2012 5:17 pm
Contact:

Re: cpSpaceEachShape and update sprites position

Post by returnvoid »

Thanks

I saw the examples using something call ChipmunkMultiGrab in the pro version. My company bought the pro version but when install that class give an error.
Is very hard understand things like that because lack of documentation.
It will be posible has some idea (tutorial or code) about how can i do it?

Thanks
returnvoid
Posts: 12
Joined: Sun Jan 22, 2012 5:17 pm
Contact:

Re: cpSpaceEachShape and update sprites position

Post by returnvoid »

Sorry but this is not working:

static void forEachShape(cpShape *shape, void *data){
CCSprite *sprite = (CCSprite *)shape->data;
if (sprite != nil){
//this is the problem. This body reference is bad but in all tutorials i have seen is ok
cpBody *body = shape->body;
//here update the sprite with the body position, no?
sprite.position = body->p;
}
}


-(void) step: (ccTime) delta{
int steps = 2;
for(int i=0; i<steps; i++){
[_space step:FIXED_TIMESTEP];
cpSpaceEachShape(_space, &forEachShape, nil);
}
}
User avatar
slembcke
Site Admin
Posts: 4166
Joined: Tue Aug 14, 2007 7:13 pm
Contact:

Re: cpSpaceEachShape and update sprites position

Post by slembcke »

What was the issue with the ChipmunkMultiGrab code?

What isn't working about it? Is it crashing or are the sprites not showing up in the right place?
Can't sleep... Chipmunks will eat me...
Check out our latest projects! -> http://howlingmoonsoftware.com/wordpress/
Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 33 guests