1
votes

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.

3
why are you repeating the sprite = [Sprite spriteWithFile:[assets pathForResource:@"green" ofType:@"png" inDirectory:@"Blocks"]]; so many times when you can just do a variable substitution on the @"green" part? might as well do createGreenBlock, createRedBlock, createBlueBlock etc etc ...Lukman

3 Answers

0
votes

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))
};
0
votes

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.

0
votes

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

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