If you center the sprite you wouldn't be able to rotate nicely for example. So add an image to the sprite, center the image ( so the center of the image ends up on the top left of the sprite. Then position the box2d object on the top left of the sprite). And use the width and height of the image to define the dimensions of the dynamic box.
Here is a sample of how i handle it: (displays a square block on the screen)
The creation of the SPSprite:
SPSprite *barSprite = [[[SPSprite alloc] init] autorelease];
[barSprite setPosition:displayX y:displayY];
SPImage *barImage = [SPImage imageWithContentsOfFile:@"bar.png"];
[self setPostion:-([barImage width] / 2.0f) y:-([barImage height] / 2.0f)
[barSprite addChild:barImage];
The creation of the Box2D:
// Define body definition
b2BodyDef bodyDef;
// The bar is static, it is manually controlled by the player.
bodyDef.type = b2_staticBody;
// Rotation is fixed.
bodyDef.fixedRotation = true;
float x = PX_TO_PTM(displayX - (BAR_WIDTH / 2.0f));
float y = PX_TO_PTM(displayY - (BAR_HEIGHT / 2.0f));
bodyDef.position.Set(x, y);
b2PolygonShape polygonShape;
float width = PX_TO_PTM(BAR_WIDTH / 2.0f);
float height = PX_TO_PTM(BAR_HEIGHT / 2.0f);
polygonShape.SetAsBox(width, height);
// Create the fixture definition
b2FixtureDef fixtureDef;
fixtureDef.shape = &polygonShape;
// Create the body
b2Body *body = [self box2dWorld]->CreateBody(&bodyDef);
body->CreateFixture(&fixtureDef);
The method PX_TO_PTM is defined as follow:
/**
* Helper method for converting pixels to meters.
*/
static inline float PX_TO_PTM(float px) {
return px / PTM_RATIO;
}