Rob
Rob

Reputation: 26324

cocos2d, box2d and retina mode: give up, or try to get it to work?

I've been trying to get my box2d game to work in retina mode, and I'm running into a lot of irritating issues when running in higher-resolution mode.

cocos2d renders my graphics correctly in retina mode, but I'm finding the need for hack after hack to get box2d to work the same as in lower-resolution mode. For example, I'm finding I need to do something like this to get the debug draw shape size correct in retina mode:

b2Vec2 vertices[4];
vertices[0].Set(-0.5f / CC_CONTENT_SCALE_FACTOR(), 1.0f / CC_CONTENT_SCALE_FACTOR());
vertices[1].Set(-0.5f / CC_CONTENT_SCALE_FACTOR(), -1.0f / CC_CONTENT_SCALE_FACTOR());
vertices[2].Set(0.5f / CC_CONTENT_SCALE_FACTOR(), -1.0f / CC_CONTENT_SCALE_FACTOR());
vertices[3].Set(0.5f / CC_CONTENT_SCALE_FACTOR(), 1.0f / CC_CONTENT_SCALE_FACTOR());  
int32 count = 4;    
b2PolygonShape polygon;    
polygon.Set(vertices, count);

That hack (adjusting all vertex points by CC_CONTENT_SCALE_FACTOR()), of course inevitably leads to a density hack, to keep movement similar to lower-resolution mode:

b2FixtureDef fixtureDef;
fixtureDef.shape = &polygon;
fixtureDef.density = 1.0f * CC_CONTENT_SCALE_FACTOR();
fixtureDef.friction = 0.9f;
playerBody->CreateFixture(&fixtureDef);

And that leads to another adjustment hack when applying forces:

b2Vec2 force = b2Vec2(10.0f / CC_CONTENT_SCALE_FACTOR(), 15.0f / CC_CONTENT_SCALE_FACTOR());
playerBody->ApplyLinearImpulse(force, playerBody->GetPosition());

Keep in mind, I'm drawing in debug mode by scaling my debug draw calls, like so:

glPushMatrix();  
glScalef(CC_CONTENT_SCALE_FACTOR(), CC_CONTENT_SCALE_FACTOR(), 1.0f);
world->DrawDebugData();
glPopMatrix();

What is it that I'm fundamentally misunderstanding about getting box2d to work with retina mode? I'm using Steffen Itterheim's suggested Box2DHelper class in place of PTM_RATIO, but that just doesn't seem to be enough. Any ideas? I'm about to give up entirely on retina mode for my game at this point.

Upvotes: 6

Views: 2103

Answers (1)

Lukman
Lukman

Reputation: 19164

I'm using the GLESDebugDraw class that comes with Cocos2D+Box2D Xcode template and the way I make the debug draw to scale up when in retina mode is just as simple as:

m_debugDraw = new GLESDebugDraw( PTM_RATIO * CC_CONTENT_SCALE_FACTOR() );
world->SetDebugDraw(m_debugDraw);

I don't need to use CC_CONTENT_SCALE_FACTOR() anywhere else since, except in some explicitly named class methods/properties like contentSizeInPixels etc, Cocos2D uses point-based coordinate space in which coordinate values remain the same whether in retina mode or low-res mode, which means the same PTM_RATIO can be used to create Box2D fixtures or shapes in both modes.

Upvotes: 7

Related Questions