0
votes

Recently I published a question regarding this topic and I received a useful answer, but my experimentation points me in a different way that I don’t understamd.

From the answer is clear that we should use the same PTM_RATIO for retina and non-retina devices. However we may double it from iPhone to iPad if we want to show the same portion of the world. In my case I used 50 for iPhone and 100 for iPad because Box2d simulations works better if the bodies are between 0.1 and 10m and the main sprite is about 2m.

I used Physics Editor to build the fixtures using GB2ShapeCache without success for retina devices. Then I decided to feed Box2D coordinates directly and I reached strange conclusions that I would like to clarify.

I created a debug method (independent from any sprite) to draw a single line from 1/3 of screens height to 1/3 of screens wide.

- (void)debugGround
{
    // iPad: 1024x768
    // iPhone: 480x320
    CGSize winSize = [CCDirector sharedDirector].winSize;    // unit is points
    b2EdgeShape groundShape;
    b2FixtureDef groundFixtureDef;
    groundFixtureDef.shape = &groundShape;
    groundFixtureDef.density = 0.0;

    b2Vec2 left = b2Vec2(0, winSize.height/3/PTM_RATIO);
    b2Vec2 right = b2Vec2(winSize.width/3/PTM_RATIO, winSize.height/3/PTM_RATIO);
    groundShape.Set(left, right);
    groundBody->CreateFixture(&groundFixtureDef);
}

If Box2D takes coordinates in points and converts them dividing by PTM_RATIO, the result should be the same for iPhone and iPad retina and non retina.

The result for iPad non retina is as expected:

enter image description here

But for iPhone retina and iPad retina, the fixtures are doubled!!

enter image description here

The most obvious correction should be divide by 2, this means dividing by CC_CONTENT_SCALE_FACTOR.

I managed to make it work for all devices refactoring the code to:

- (void)debugGround
{
    CGSize winSize = [CCDirector sharedDirector].winSize;
    b2EdgeShape groundShape;
    b2FixtureDef groundFixtureDef;
    groundFixtureDef.shape = &groundShape;
    groundFixtureDef.density = 0.0;

    b2Vec2 left = b2Vec2(0, winSize.height/3/PTM_RATIO/CC_CONTENT_SCALE_FACTOR());
    b2Vec2 right = b2Vec2(winSize.width/3/PTM_RATIO/CC_CONTENT_SCALE_FACTOR(), winSize.height/3/PTM_RATIO/CC_CONTENT_SCALE_FACTOR());

    groundShape.Set(left, right);
    groundBody->CreateFixture(&groundFixtureDef);
}

I also managed to display correctly the lower platforms dividing by the scale the vertex, the offsets and anywhere I use PTM_RATIO to convert to Box2D coordinates.

It is supposed I shouldn’t use CC_CONTENT_SCALE_FACTOR by any means to multiply positions because GL functions already take this into consideration.

Can anyone clarify this behavior? In which concepts I’m wrong?

I hope this helps the community to understand better Box2D coordinate system.

1
winSize.width always gives 320x480 not 640x960 even in hd. So no need to use CC_CONTENT_SCALE_FACTOR. It works.Guru
You are right, but it is a typo. Considering landscape mode winSize returns always 480,320 (iPhone) and 1024x768 (iPad). Then, how do you explain that Box2D coordinates takes a screem size of (10.24,7,68) on iPad non retina and (5.12,3.84) on iPad retina using the same PTM_RATIO? I KNOW I MUST NOT divide by the scale, but IT's WORKING for all devices!!! I'm just trying to understand why.Jorge Piedrafita
:) see for example you need point on center, then (winSize.height*0.5)/PTM_RATIO it works for all modes...height can be 768 or 320..works for all....to add make point on 20% in x axis then put (winSize.height*0.2)/PTM_RATIO . Hope u got the point !Guru
Yes, that is the theory. But according to the first method I posted, winSize.height/3/PTM_RATIO draws the fixture at 1/3 of the screen in non-retina, which is correct (pic 1), and winSize.height/3/PTM_RATIO is drawn at 2/3 in retina display (pic2). Box2D is multipling by 2 the coordinates somewhere, and I don't know where or why.Jorge Piedrafita
may be something wrong with your debug draw code....which cocos2d version you are using ? I guess its not Cocos2d 2.0...long back I observed same problem in Cocos2d 1.0...its fixed in 2.0Guru

1 Answers

1
votes

you misunderstood: GL functions (this includes ccDraw* functions!) require multiplication with content scale factor because GL works on pixel resolution, whereas UIKit views and cocos2d nodes use point coordinates.