views:

516

answers:

3

I've been working on a game and implementing the physics stuff with chipmunk. All was going fine on the cocos2d part until the integration with chipmunk. A bit of background:

The game is a game with blocks. Levels are defined in a property list, where positions, size of the blocks, gravitational forces, etc., are all defined for each block to be shown in the level.

The problem is with the blocks showing up. I have a method on my BlockLayer class which is part of my game's main scene. Upon creation of the layer, the property list is read, and all the blocks are created. The following method is called to create the blocks:

- (void)createBlock:(Block*)block withAssets:(NSBundle*)assets
{
    Sprite* sprite;
    switch(block.blockColour)
    {
     case kBlockColourGreen:
      sprite = [Sprite spriteWithFile:[assets pathForResource:@"green" ofType:@"png" inDirectory:@"Blocks"]];
      break;
     case kBlockColourOrange:
      sprite = [Sprite spriteWithFile:[assets pathForResource:@"orange" ofType:@"png" inDirectory:@"Blocks"]];
      break;
     case kBlockColourRed:
      sprite = [Sprite spriteWithFile:[assets pathForResource:@"red" ofType:@"png" inDirectory:@"Blocks"]];
      break;
     case kBlockColourBlue:
      sprite = [Sprite spriteWithFile:[assets pathForResource:@"blue" ofType:@"png" inDirectory:@"Blocks"]];
      break;
    }
    sprite.position = block.bounds.origin;
    [self addChild:sprite];
    if(block.blockColour == kBlockColourGreen || block.blockColour == kBlockColourRed)
     space->gravity = cpvmult(cpv(0, 10), 1000);
    cpVect verts[] = {
     cpv(-block.bounds.size.width, -block.bounds.size.height),
     cpv(-block.bounds.size.width, block.bounds.size.height),
     cpv(block.bounds.size.width, block.bounds.size.height),
     cpv(block.bounds.size.width, -block.bounds.size.height)
    };
    cpBody* blockBody = cpBodyNew([block.mass floatValue], INFINITY);
    blockBody->p = cpv(block.bounds.origin.x, block.bounds.origin.y);
    blockBody->v = cpvzero;
    cpSpaceAddBody(space, blockBody);
    cpShape* blockShape = cpPolyShapeNew(blockBody, 4, verts, cpvzero);
    blockShape->e = 0.9f;
    blockShape->u = 0.9f;
    blockShape->data = sprite;
    cpSpaceAddShape(space, blockShape);
}

With the above code, the sprites never show up. However, if I comment out the "cpSpaceAddBody(space, blockBody);" line, the sprites show up.

The position and size of the blocks are stored in the "bounds" property of instances of the Block class, which is a CGRect.

Not sure if it's important, but the orientation of the app is in landscape left, and all the coordinates are based on that orientation.

Any help would be greatly appreciated.

A: 

Make sure that no particular bodies overlap. If two bodies overlap, the force computation algorithm gets a little crazy and you end up having two bodies wayyy outside the screen coordinates.

That being said, the verts array seems to be wrong:

cpVect verts[] = {
    cpv(-block.bounds.size.width, -block.bounds.size.height),
    cpv(-block.bounds.size.width, block.bounds.size.height),
    cpv(block.bounds.size.width, block.bounds.size.height),
    cpv(block.bounds.size.width, -block.bounds.size.height)
};

You should work with halves of the given values, since: |x| + |-x| = 2x. (and you want only 1x)

cpVect verts[] = {
    cpv(-(block.bounds.size.width/2), -(block.bounds.size.height/2)),
    cpv(-(block.bounds.size.width/2), block.bounds.size.height/2),
    cpv(block.bounds.size.width/2, block.bounds.size.height/2),
    cpv(block.bounds.size.width/2, -(block.bounds.size.height/2))
};
arul
The verts array was indeed wrong. And having moved the blocks way out of the way (they're 48x48 right now, made them uniform for testing) and placed 80 pixels apart starting at cpv(50, 50), at y=50 for all 3, while x = previous_x + 80. Still not showing up, but as soon as I take out that line, they show up.
jer
Just a followup, I took out every block from my level except one. Same problem persists. So I'm confident it's not due to overlap, as there's only one sprite, one body and one shape in the game now.
jer
A: 

Ok so I found the answer. The problem was believe it or not, with gravity when setting up chipmunk. I was setting it up incorrectly, setting gravity to cpv(0,0) got my blocks displaying on screen. Then after some tinkering with some other code, I was able to introduce gravity again. Just had to play around in my block creation method.

jer
A: 

Can I just ask how you calculate the mass of your block(s)?

cpBody* blockBody = cpBodyNew([block.mass floatValue], INFINITY);
Fulvio