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

1

6

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.

Kaitlin answered 1/5, 2011 at 17:27 Comment(0)
K
7

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.

Kiernan answered 3/5, 2011 at 15:21 Comment(6)
Interesting, I'll have to give that a try later today. It would be fantastic if it was as simple as that.Kaitlin
Unfortunately, that does not still seem to be enough. I'm still finding that my box2d fixture shapes are still twice as large in retina mode as they should be. Don't you need to take PTM_RATIO (whether it be 32 or 64) into account when specifying vertices for your box2d fixtures?Kaitlin
@unforgiven3 but I've been using the same PTM_RATIO regardless if [director enableRetinaDisplay:YES] or [director enableRetinaDisplay:NO]. How about the Cocos2D sprites: did you prepare -hd version of all the sprite images used?Kiernan
HD images are indeed used - I don't see how you can use the same PTM_RATIO. In non-retina, it's generally 32 pixels per meter, and in retina, it's 64 pixels per meter... right? For a sprite to cover the same screen area in retina mode, it has to be twice as large as in non-retina mode... or so I thought?Kaitlin
@unforgiven3 cocos2d uses point-based coordinates where it's always 32 points in retina mode or non-retina. Are you using pixel-based calculations?Kiernan
Wow, I think I understand now - I was able to get it to work by thinking in terms of points instead of pixels. Thanks Lukman, I think you just may have solved my problem!Kaitlin

© 2022 - 2024 — McMap. All rights reserved.