iphone高分辨率 Retina Screen Display in cocos2d(>=iphone4)

来源:互联网 发布:试衣服的软件 编辑:程序博客网 时间:2024/06/14 07:58

Who should read this

This guide is for those of you who want to create a RetinaDisplay game. The game might also support the low-res too.

This guide is valid for cocos2d v0.99.5-rc0 or newer. This document is not valid for previous cocos2d versions.

RetinaDisplay in cocos2d

Introduction

The entire cocos2d API was converted to Points. Previous versions were using Pixels.

cocos2d v0.99.4 has RetinaDisplay support, however it required you to use two different sets of positions depending on the device , since the API was in Pixels.

For example to position an sprite on the top-right corner, you had to do:

// in v0.99.4






if


(


iPhone4isUsed)






sprite.position =


ccp(


960


,640


)


;



else






sprite.position =


ccp(


480


,320


)


;

But in v0.99.5-rc0 (and newer) the only thing that you have to do is:

// v0.99.5






sprite.position =


ccp(


480


,320


)


;

Point vs. Pixel

What is a pixel ? A pixel according to wikipedia is this: http://en.wikipedia.org/wiki/Pixel.

The difference between Pixels and Points is that the logical coordinate space is measured in Points, while the device coordinate space is measured in Pixels.

Example:

Device Points Pixels iPhone 3GS or older [1] 480×320 480×320 iPhone4 in LowRes mode [2] 480×320 480×320 iPhone4 in HighRes mode [2] 480×320 960×640 iPad 1024×768 1024×768 Mac W x H W x H

[1]: It is also valid for iPod Touch 3rd generation and older devices

[2]: It is also valid for iPod Touch 4th generation

So, only on iPhone4 when HighRes mode is enabled 1 Point == 4 pixels (2×2 pixels), otherwise 1 Point == 1 Pixel.

The API in Points

As mentioned previously, in v0.99.5 the API is in points, it means that:

   // director






CCDirector *


director [


CCDirector sharedDirector]


;



CGSize sizeA =


[


director winSize]


; // is in Points






CGSize sizeB =


[


director winSizeInPixels]


; // in Pixels






CGSize sizeA =


[


director displaySize]


; // is in Points






CGSize sizeB =


[


director displaySizeInPixels]


; // in Pixels






 



// Node






CCNode *


node =


[


...]


;



CGPoint posA =


[


node position]


; // is in Points






CGPoint posB =


[


node positionInPixels]


; // is in Pixels






CGSize sizeA =


[


node contentSize]


; // is in points






CGSize sizeB =


[


node contentSizeInPixels]


; // is in pixels






CGRect rectA =


[


node boundingBox]


; // is in Points






CGSize rectB =


[


node boundingBoxInPixels]


; // is in pixels






 



// Sprite






CCSprite *


sprite =


[


...]


;



CGRect rectA =


[


sprite rect]


;



CGRect rectB =


[


sprite rectInPixels]


;

This is also valid for the setters. eg:

   [


sprite setPosition:


ccp(


x,y)


]


; // in Points






[


sprite setPositionInPixels:


(


x,y)


]


// in Pixels


etc… The methods are ONLY in pixels if the methods or properties end with the “InPixels” suffix. If they don't have that suffix it means that they use Points.

When should you use Points, and when Pixels

95% of the time you will want to use the Point API, but there are special cases when you might need to use the Pixel API.

Some of cocos2d's complex objects use the Pixel API. eg: `CCSprite`, `CCTMXLayer`, `CCLabelBMFont`.

So, you might need to use the Pixel API if you are developing a complex object, specially if you need to parse a data file that has values in pixels.

The -hd suffix

Most likely, you'll want to have low-res images on iPhone 3GS and older devices, and high-res images on iPhone 4.

Apple uses the ”@2x” suffix, but cocos2d doesn't use that extension because of some incompatibilities. So cocos2d has its own suffix: the ”-hd” suffix.

If you want to use your own suffix, you can do it by editing the ccConfig.h file.

// Modify it to use your own suffix






#define CC_RETINA_DISPLAY_FILENAME_SUFFIX @"-hd"


WARNING: It is NOT recommend to use the ”@2x” suffix. Apple treats those images in a special way which might cause some bugs in your cocos2d application.

The only exception is the “Default@2x.png” image. Since cocos2d is not loaded at that time, you can use that image in order to have a High Res splash image.

Each file opened by cocos2d (image file, config file, sprite sheet, etc…) is opened using the CCFileUtils class.When RetinaDisplay is enabled, this class will try to open the ”-hd” file instead. If that file doesn't exist, it will open the originally requested file.

Example: If you try to open the file “sprite.png” when RetinaDisplay mode is enabled, then the following will happen:

  1. Obtain the full path of “sprite.png” → ”/Volumes/XXX/sprite.png”
  2. Is the Application in Retina Display mode ?. If not, then return the fullpath name. If yes, then continue with step 3.
  3. Does “sprite.png” have the ”-hd” suffix ?
  4. In this case particular case, the answer is No, so it will try append the ”-hd” suffix to “sprite.png” → “sprite-hd.png”
  5. Does the HD image exist (”/Volumes/XXX/sprite-hd.png”) ?
  6. If it does exist it will use it, otherwise it will use the non-hd image

Same example, but trying to open the file “sprites-hd.plist”

  1. Obtain the full path of “sprites-hd.plist” → ”/Volumes/XXX/sprites-hd.plist”
  2. Is the Application in Retina Display mode ?. If not, then return the fullpath name. If yes, then continue with step 3.
  3. Does “sprites-hd.plist” have the ”-hd” suffix ?
  4. Yes. So, try to use it.

As you can see, the ”-hd” suffix is valid for any file: Images (.png, .gif, .bmp, etc), TMX files (.tmx, .png), BMFont files (.fnt, .png), Sprite sheets (.plist, .png).

cocos2d, as of v0.99.5-rc0, doesn't support any other suffix, like an ”-ipad” suffix, but it will support it in the near future.

Enabling Retina Display mode

You should enable RetinaDisplay mode ONLY if you want to use HighRes images on an iPhone4. Remember that an iPhone4 also works in “low res” mode.

// Add this code in your Application Delegate, right after initializing the director






 



// Director Initialization






[


director setOpenGLView:


glView]


;



 



// Enables High Res mode (Retina Display) on iPhone 4 and maintains low res on all other devices






if


(


!


[


director enableRetinaDisplay:


YES


]


)






CCLOG(


@


"Retina Display Not supported"


)


;

CCNode details

CCNode

  • position is in points
  • positionInPixels is in pixels
  • contentSize is in points
  • cotentSizeInPixels is in pixels
  • boundingBox is in points
  • boundingBoxInPixels is in pixels

CCLabelAtlas

The API is in Points:

  • +(id) labelWithString:(NSString*) string charMapFile: (NSString*) charmapfile itemWidth:(int)w itemHeight:(int)h startCharMap:(char)c;

It means that the width and height are in points. So, if you call this method when RetinaDisplay mode is enabled, you MUST have a -hd image.

Quick way to create a “pseudo” high res image by using ImageMagick:

$ convert fps_label.png -scale 200%  fps_label-hd.png

WARNING: You should NOT scale up a raster image. You won't gain quality. The above given example is a quick way to create an ”-hd” image so that you can test your game quickly.

CCLabelBMFont

The API is in points, so if you want to have both a low res and high res version, you have to create a 2x file by using Hiero (or your favorite BMFont editor).

Example: If have a low res BMFont called times32.fnt (and times32.png) (Times New Roman font with a font size of 32), then you'll have to:

  1. Create a Times New Roman file with a font size of 64.
  2. You should save this file: times32-hd.fnt (and times32-hd.png)

This will create REAL HighRes images.

TMX maps

The API is in Points, so if you want to create a HighRes version you'll have to:

  1. copy map.tmx to map-hd.tmx
  2. Edit “map-hd.tmx” and multiply by 2 the tile size and spacing in the tileset information like tilewidth, tileheight, spacing and margin.
  3. Then you'll have to create a HD version of the tileset image

Sample of map.tmx:

<map version="1.0" orientation="orthogonal" width="10" height="10" tilewidth="32" tileheight="32">



<tileset firstgid="1" name="Desert" tilewidth="32" tileheight="32" spacing="1" margin="1">



<image source="tileset.png"/>



</tileset>

Sample of map-hd.tmx:

<map version="1.0" orientation="orthogonal" width="10" height="10" tilewidth="64" tileheight="64">



<tileset firstgid="1" name="Desert" tilewidth="64" tileheight="64" spacing="2" margin="2">



<image source="tileset-hd.png"/>



</tileset>



Quick way to create a “pseudo” high res image by using ImageMagick:

$ convert tileset.png -scale 200% tileset-hd.png

WARNING: You should NOT scale up a raster image. You won't gain quality. The above given example is a quick way to create an ”-hd” image so that you can test your game quickly.

Spritesheets (Zwoptex / TexturePacker / .plist)

You should generate the files (.plist and .png) again, this time using the high res sprites.Example: If you have generated your spritesheet.plist and spritesheet.pngfiles using the these 4 low-res images:

  1. sprite1.png
  2. sprite2.png
  3. sprite3.png
  4. sprite4.png

Then you'll have to create an HD version of those 4 images. But you should NOT rename them. Instead, what you should do is to place the HD files in another directory. eg:

$ mkdir hd_sprites



$ convert sprite1.png -scale 200% hd_sprites/sprite1.png



$ convert sprite2.png -scale 200% hd_sprites/sprite2.png



$ convert sprite3.png -scale 200% hd_sprites/sprite3.png



$ convert sprite4.png -scale 200% hd_sprites/sprite4.png

Then you will have to generate the spritesheet-hd.plist and spritesheet-hd.png files from the sprites that are located in the “hd_sprites” subdirectory.

WARNING: You should NOT scale up a raster image. You won't gain quality. The above given example is a quick way to create an ”-hd” image so that you can test your game quickly.

Sprites

The sprite API is in points:

  1. -(id) initWithFile:(NSString*)filename rect:(CGRect)rect;
  2. The property rect is in points
  3. But the property rectInPixels is in pixels

So, if you are going to use this method, be sure to have an ”-hd” image, otherwise your sprite won't look good.

Quick way to create a “pseudo” high res image by using ImageMagick:

$ convert spritesheet.png -scale 200% spritesheet-hd.png

WARNING: You should NOT scale up a raster image. You won't gain quality. The above given example is a quick way to create an ”-hd” image so that you can test your game quickly.

 

See also:

 

原创粉丝点击