cocos2dでのRetinaDisplay対応法

                                                                                                                  • -

2/28に追記しました。
cocos2dでのRetinaDisplay対応時の注意点&追記

                                                                                                                  • -

先週悩んでるとお伝えしていたRetinaDisplayへの対応方法について書こうと思います。知らない方もいらっしゃるかもしれませんが、「iPhone3G」、「iPhone3GS」と、「iPhone4」とでは解像度が2倍も違います。なので、iPhone3G,3GS用の画像のみでアプリを作成していると、iPhon4では画像があらく、しょぼく見えてしまうのです。。。


具体的には、

iPhone3G,iPhone3GS → 320 × 480
iPhone4(RetinaDisplay) → 640 × 960

iPad → 768 × 1024
(単位はピクセル

なので、両方の端末に対応するためには、RetinaDisplay用の画像(画質2倍のもの)を別途用意する必要があります。


通常の方法でアプリを作る場合には、画像ファイルを2種類用意したのち、Retina版の画像に「@2x」とすればよいみたいなのですが、(eg. sample.png → sample@2x.png))


cocos2dの場合はどうやら事情が異なるようですので、以下にまとめてみます。
ちなみに僕は、この対応にめちゃくちゃ時間をとられてしまいました。。。

cocos2dでのRetina対応

cocos2d v0.99.5-rc1

のバージョンからRetina対応しているらしく、詳細はここに記載されていました。
「cocos2d for iPhone v0.99.5-rc1 Release Notes」の RetinaDisplay support 項目の  How to develop RetinaDisplay games in cocos2d というリンクに長々と書いてありますが、やることは2つのみ

1、Retina版画像には、「-hd」を付ける
→「Sample.png」 → 「sample-hd.png
*icon画像と、Default画像は@2xでOK
*ただし、Info.plist 内の「Icon file」を「Icon」する(Icon.png)では識別してくれないので注意!
icon@2x.pngがRetinaに反映されない
*Icon画像の光沢を消す場合には、info.plist内に、UIPrerenderedicon というのを追加し、Boolean を選択し、チャックを付ける
参考→http://sygnas.jp/2010/07/07/iconeffectscu/


2、AppDelegateファイル内の- (void) applicationDidFinishLaunching:(UIApplication*)application メソッド内に、以下を追記する

- (void) applicationDidFinishLaunching:(UIApplication*)application {

       ・・・・・・・・

	if ([UIScreen instancesRespondToSelector:@selector(scale)] )
		[[CCDirector sharedDirector] setContentScaleFactor:[[UIScreen mainScreen] scale]];

       ・・・・・・・・


この2つの作業を行えば、プログラム側でよきにはからってくれます。(今思うと、めちゃくちゃ簡単なのですが。。。。)



気になったので、「scale」についてAppleReferenceで調べてみると。

Properties


scale
The natural scale factor associated with the screen. (read-only)


@property(nonatomic,readonly) CGFloat scale

Discussion
This value reflects the scale factor needed to convert from the default logical coordinate space into the device coordinate space of this screen. The default logical coordinate space is measured using points, where one point is approximately equal to 1/160th of an inch. If a device’s screen has a reasonably similar pixel density, the scale factor is typically set to 1.0 so that one point maps to one pixel. However, a screen with a significantly different pixel density may set this property to a higher value.


Availability
Available in iOS 4.0 and later.


Related Sample Code
PhotoScroller


Declared In
UIScreen.h


Sprite(画像ファイル)を表示させる座標自体は一切いじらずにRetinaに対応できるので、pointsというのがx、y座標などで使用する値。そんで、pixcelは単純に画素のこと。

Referenceの英語を読んでみるに、「scale」は、pointsと、pixcelの倍率を呼び出すプロパティだと思われます。

scale = pixel / point

iPhone3,iPhone3GS → scale = 1.0

iPhone4 → scale = 2.0


そのため、applicationDidFinishLaunchingに追加した

       ・・・・・・・・

	if ([UIScreen instancesRespondToSelector:@selector(scale)] )
		[[CCDirector sharedDirector] setContentScaleFactor:[[UIScreen mainScreen] scale]];

       ・・・・・・・・

は、UIScreenオブジェクトに、scaleというメッセージに反応できるかどうか尋ね、


↓反応できる場合、(if文内がYESの場合)


Directorのシングルトンオブジェクトに各Deviceのscale=point/pixcel の値を返している

のではないかと思われます。


ちなみに、Xcodeで「scale」を選択して、右クリックし、「定義にジャンプ」→「[UIScreen scale]」を押すと、

@property(nonatomic,readonly) CGFloat scale __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_0);


となっていたので、iPhone4以上の端末でないと反応しないみたいです。
(__ 以降のやつの意味はよくわからないけど。。。こういうのなんていうんだろう?)



以下、NSObjectクラスのReference より instancesRespondToSelector についての説明。

nstancesRespondToSelector:
Returns a Boolean value that indicates whether instances of the receiver are capable of responding to a given selector.

  1. (BOOL)instancesRespondToSelector:(SEL)aSelector

Parameters
aSelector
A selector. See “Selectors” for a description of the SEL type.


Return Value
YES if instances of the receiver are capable of responding to aSelector messages, otherwise NO.


Discussion
If aSelector messages are forwarded to other objects, instances of the class are able to receive those messages without error even though this method returns NO.
To ask the class whether it, rather than its instances, can respond to a particular message, send to the class instead the NSObject protocol instance method respondsToSelector:.


Availability
Available in Mac OS X v10.0 and later.


See Also
– forwardInvocation:


Declared In
NSObject.h

Retina対応したアプリを見てみましたが、iPhone4の画像のきれいさに感動!
あの小ささにも関わらずiPad並みの画素数があるって本当にすごい!
自分の3GSとはえらい違いだった。。。
と、cocos2dのRetinaDisplay対応についてはこんなところです。


来週はcocos2dの特徴のひとつでもあるSpriteを動かす豊富なActionをご紹介しようかと。。。ほんとうに便利で面白い動きを提供してくれます。

あと、最近、cocos2dについて一から学びたい人向けの本を見つけました。少し古い本ですが、



がオススメです。