3
votes

The problem is, Cocos seems to think retina devices are the same resolution as standard devices. If you draw a sprite at 768,1024 on the ipad, it will put it at the upper right corner. If you draw a sprite at 768,1024 on the retina ipad, content scaling makes it so it also puts it in the upper right corner. Yet if you draw a sprite on the retina iphone 5 at 640,1136 it isn't in the upper right corner, its off the screen by 2x the distance. In order to put it in the corner you have to draw it at 320,568 because of the content scaling.

I do have a [email protected] image, and I am on version 2.1.

My question is: Is there a way to get Cocos2d to make it so that drawing a sprite at 640,1136 on an iPhone5 will result in the sprite being in the upper right corner?

Is it possible to set up a cocos2d custom GL projection and set winSizeInPoints to equal winSizeInPixels and content scale 1.0 so that you can use the iPhone 4/5's full native resolution instead of using the half-size coordinates of older iPhones.

3
have you tried not enabling retina display, i.e. calling: [director enableRetinaDisplay:NO] when setting up your CCDirector?sergio

3 Answers

1
votes

You can easily do this by changing the iPad suffix to use "-hd" via CCFileUtils. That way iPad devices will load the regular -hd assets for Retina iPhones.

Update regarding comments:

The positions on devices is measured in points, not pixels. So a non-retina iPad and a retina iPad both have a point resolution of 1024x768. This is great exactly because it makes adapting to screens with different pixel densities a no-brainer. This also works on the iPhone devices.

My suspicion is that you simply haven't added the [email protected] launch image to your project yet, which may cause the widescreen devices to be treated differently.

And specifically on older cocos2d versions dated before iPhone 5 there's a bug that will treat the iPhone 5 as a non-Retina device, proper default image or not.

1
votes

Yes You can share, easy way to do this is put all common sprite in sprite sheet and in runtime check if iPad, if yes then load iPhone HD sheet. We did this in many project and worked.

if(IS_IPAD)
{
   [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"GameSpriteSheet-hd.plist"];
}
else 
{
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"GameSpriteSheet.plist"];

}

For background image, good to have separate iPad image, if scaling not look bad then you can scale image at runtime.

1
votes

As far as I can understand what you are trying to do, the following approach should work:

  1. call [director enableRetinaDisplay:NO] when setting up your CCDirector;

  2. hack or override the following methods in CCDirector's so that winSizeInPixels is defines as the full screen resolution:

    a. setContentScaleFactor:;

    b. reshapeProjection:;

    c. setView:;

Step 1 will make sure that no scaling factor is ever applied when rendering sprites or doing calculations; Step 2 will ensure that the full screen resolution is used whenever required (e.g., when defining the projection, but likely elsewhere as well).

About Step 2, you will notice that all listed methods show a statement like this:

winSizeInPixels_ = CGSizeMake( winSizeInPoints_.width * __ccContentScaleFactor, winSizeInPoints_.height * __ccContentScaleFactor );

__ccContentScaleFactor is made equal to 1 by step 1, and you should leave it like that; you could, e.g. customise winSizeInPixels calculation to your aim, like this:

if (<IPHONE_4INCHES>)
    winSizeInPixels_ = CGSizeMake( winSizeInPoints_.width * 2, winSizeInPoints_.height * 2 );
else 
    winSizeInPixels_ = CGSizeMake( winSizeInPoints_.width * __ccContentScaleFactor, winSizeInPoints_.height * __ccContentScaleFactor );

Defining a custom projection would unfortunately not work because winSizeInPixels is always calculated based on __ccContentScaleFactor; but, __ccContentScaleFactor is also used everywhere in Cocos2D to position/size sprites and the likes.

A final note on implementation, you could hack this changes into the existing CCDirectorIOS class or you could derive from it your own MYCCDirectorIOS and override the methods there.

Hope it helps.