Cocos2d-x 2.0.4以降でMulti-Resolution(マルチ解像度)対応する方法

cocos2d-x

cocos2d-xを2.0.4にアップグレードしてMulti-Resolution機能を使ってみたらいきなりハマった。

公式サイトの解説ページを2回読んでソース書いてみたけどこれはおかしいだろう…俺の頭がおかしいのかもしれないけど…

まぁ対応完了したのでメモしておきます。


setContentScaleFactor ではなく setDesignResolutionSize を利用する

解説のページ見ると両方使ってるのだけど、ソースコード見るとどう考えてもどちらか片方を使用するようになってるように見える。実際、CCEGLView#setDesignResolutionSizeだけで問題なく動作する。

この関数は第1,2引数にアプリケーションが想定する(拡大していない状態の)サイズを指定します。第3引数はどのように拡大するかを ResolutionType 列挙子 で指定します。

ケース1) iPhone向けに 320×480 を想定して画像を作成し、Retina対応をしていないiPhoneアプリの場合は

CCEGLView::sharedOpenGLView()->
setDesignResolutionSize(320, 480, kResolutionTypeNoBorder);

とします。Retinaディスプレイでは 320 x 480 の画面がRetinaディスプレイに合わせて2倍に拡大されて表示します。※その他の解像度でも解像度に合わせて拡大縮小されます。

使用する画像は当然、非Retina用のものを使用します。

ケース2) 640×960のRetina対応のみ想定して、320×480の非Retinaに対応していない場合は

CCEGLView::sharedOpenGLView()->
setDesignResolution(640, 940, kResolutionTypeNoBorder);

とします。非Retinaディスプレイでは0.5倍に縮小されて表示されます。※その他の解像度でも解像度に合わせて拡大縮小されます。

使用する画像は当然、Retina用のものを使用します。

ケース3) 320×480 にも Retina640x960 にも対応している場合は…?

デバイスの解像度からどちらに割り当てるかプログラムで判定して分岐するだけです。

CCSize frame = pEGLView->getFrameSize();

// どのように分岐するかはプログラマの自由です
// ここでは frame.width を基準にしてみます
CCEGLView *pEGLView = CCEGLView::sharedOpenGLView();

if ( frame.width < 640 ) {
	pEGLView->setDesignResolutionSize(320, 480, kResolutionTypeNoBorder);
	CCFileUtils->sharedFileUtils()->setResourceDirectory("320x480用に作成したリソースのフォルダを指定");

} else {
	pEGLView->setDesignResolutionSize(640, 960, kResolutionTypeNoBorder);
	CCFileUtils->sharedFileUtils()->setResourceDirectory("640x960用に作成したリソースのフォルダを指定");
}

ResolutionType列挙子の種類

4種類だけです。難しくありません。

  • kResolutionUnknown : 未指定の状態です使いません。
  • kResolutionExactFit : 画面にピッタリ表示。アスペクト比が変化して歪む可能性あり。
  • kResolutionNoBorder : アスペクト比を維持したまま、画面いっぱいになるように拡大。はみ出る可能性あり。
  • kResolutionShowAll : アスペクト比を維持したまま、はみ出ないように拡大。表示不可能な領域がでる可能性あり。

画面の表示位置や表示領域の変更も可能なようです。試してませんが、CCDirector::sharedDirector()->getVisibleOrign(), CCDirector::sharedDirector()->getVisibleSize() の2つのメソッドをセットで利用するようです。

細かいことは公式の解説をよんで下さい。NoBorderの解説図がおかしい気がしますが、私の頭がおかしい可能性もあるので、どちらがおかしいのか教えて下さる方はいらっしゃいませんか?

そういうことで自分のソースコードはこんな感じになってる

void initResolutionSettings() {
  CCEGLView *pEGLView = CCEGLView::sharedOpenGLView();

  // EGLViewの枠のサイズを取得
  CCSize frame = pEGLView->getFrameSize();

  //
  // プラットフォーム や 解像度別に設定を振り分ける
  // 振り分けには frameSize などを利用する
  //
  float scale;
  CCSize size; // resolution size
  std::string resourceDirectory;

  /* iOS の場合 */
#if ( CC_TARGET_PLATFORM == CC_PLATFORM_IOS )

  if ( spApp->getTargetPlatform() == cocos2d::kTargetIpad ) {
    /*
     * iPad の場合 : Retina用の画像は準備してない場合を想定
     */
    size = CCSizeMake(768.0f, 1024.0f);
    resourceDirectory = "ipad";

  } else {
    /*
     * iPhone の場合 : Retina用の画像もある場合を想定
     */
    scale = frame.width / 320.0f <= 1 ? 1 : 2 ;
    size.width = 320.0f * scale;
    size.height = (480.0f < frame.height ? frame.height * 0.5f : frame.height) * scale;
    resourceDirectory = scale <= 1.0f ? "iphone" : "iphone_retina";
  }
#else
  // 他のプラットフォームも同様に記述するか、
  // あるいはどのプラットフォームでも問題ないように記述するか。
#endif

  // リソースディレクトリの設定
  CCFileUtils *pFileUtils = CCFileUtils::sharedFileUtils();
  pFileUtils->setResourceDirectory(resourceDirectory.c_str());

  // DesignResolutionSizeの設定
  pEGLView->setDesignResolutionSize(size.width,
                                    size.height,
                                    kResolutionNoBorder);
}

CC_TARGET_PLATFORMで分岐せずとも問題なく動作するように書いたほうがいいような気がしますので…このコードはかなり微妙な感じです。まぁそれでもiOSでならちゃんと動作します。

  1. コメントはまだありません。

  1. トラックバックはまだありません。

*


Advertisement