cocos2dxでマルチ解像度に対応させる

Pocket

マルチ解像度対応できてないとても残念な例

マルチ解像度対応できてないとても残念な例

他の端末で見たら上みたいなことになってたし、こりゃ先にやっといた方がいいなって思ったんで、マルチレゾリューション(マルチ解像度)の対応の方法とか調べてやってみました。普段Eclipseで開発してたからか、Android側の方は簡単だったんだけど、初めて開いてみたXcodeのiPhone側ではまりまくったんで、メモとして残しておきます。

ちなみに、ソースなどは「Cocos2d-x開発のレシピ」を参考にさせてもらいました。

まずは用意する画像の大きさを決める

下記のは全部端末を縦にした場合の大きさです。

Androidの画像解像度

  • xxdpi(480dpi):1080×1920px
  • xdpi(320dpi):720×1280px
  • hdpi(240dpi):540×960px
  • mdpi(160dpi):360×640px

他にもmdpiよりさらに小さいldpiというのもあるけど、もうほとんど出回ってないらしいので割愛。

iPhoneの解像度

  • iPad(第三世代以降):1536×2048px
  • iPhone5:640×1136px
  • iPad(1、2):768×1024px
  • iPhone4(S):640×960px
  • iPhone3G(S):320×480px

ちなみに、下記のサイトに詳しく載ってます。ぼくもそこを参考にしちゃった。
http://www.find-job.net/startup/iphone-android-size-2013-summer

こんな感じにたくさんあるんで、とりあえず大・中・小と3種類くらい画像を用意して、それをぴっちり引き延ばすという方法で対応しようかと思います。
またもともとぼくがAndroid向けに作っちゃってたんで、Androidのxdpi、hdpi、mdpiで対応させることに。

(ちなみに、画像をわざわざ分けなくてもxdpiまたはiPhone5向けの画像ひとつ用意するだけでもそんなかわらないぽいです)

Resources内のディレクトリ構成

multiresolution_folda2

まあこんな感じで、「xdpi」「mdpi」「hdpi」というディレクトリで作成しました。
ディレクトリ名は自由でいいそうです。ついでだからBGMとか入れる「sound」のディレクトリも作成しちゃった。

どうでもいいんですけど、ディレクトリとフォルダって微妙に違うそうですね。

マルチレゾリューションを実装する

次はソースをいじっていきます。
MultiResolution.hファイルを作成し、そこに設定内容を入れます。

#ifndef MULTIRESOLUTION_H_
#define MULTIRESOLUTION_H_
#include "cocos2d.h"
using namespace cocos2d;
typedef struct tagResource{
	cocos2d::CCSize size;
	char directory[100];
} Resource;

static Resource mdpi = { cocos2d::CCSizeMake(360 , 640) , "mdpi"};
static Resource hdpi = { cocos2d::CCSizeMake(540 , 960) , "hdpi"};
static Resource xdpi = { cocos2d::CCSizeMake(720 , 1280) , "xdpi"};
static cocos2d::CCSize designResolutionSize = cocos2d::CCSizeMake(720 , 1280);

#endif /* MULTIRESOLUTION_H_ */

いつもすぐ忘れちゃうぼくのメモもかねて解説しとくと、この

typedef struct tagResource{
	cocos2d::CCSize size;
	char directory[100];
} Resource;

の部分でResourceという型を設定し、その下でmdpi、hdpi、xdpiを設定してます。
sizeはサイズ、directoryはディレクトリ。わかりますよね。
最後のdesignResolutionSizeはデザイン解像度なるものを設定してます。

次に、AppDelegate.cppの中に直接ソースを書いていきます。

#include "MultiResolution.h"
...
bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    CCDirector* pDirector = CCDirector::sharedDirector();
    CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
    pDirector->setOpenGLView(pEGLView);
    //デザインサイズの設定
    pEGLView->setDesignResolutionSize(
                                      designResolutionSize.width ,
                                      designResolutionSize.height ,
                                      kResolutionExactFit);
    CCSize frameSize = pEGLView->getFrameSize();
    //マルチレゾリューション設定
    std::vector<std::string> resolution;
    Resource dpi;
    if(frameSize.height > hdpi.size.height){
        CCLog("xdpi");
        dpi = xdpi;
    }else if(frameSize.height > mdpi.size.height){
        CCLog("hdpi");
        dpi = hdpi;
    }else{
        CCLog("mdpi");
        dpi = mdpi;
    }
    resolution.push_back(dpi.directory)
    pDirector->setContentScaleFactor(MIN(
                    dpi.size.height / designResolutionSize.height ,
                    dpi.size.width / designResolutionSize.width
                    ));

    CCFileUtils::sharedFileUtils()->setSearchPaths(resolution);
    CCFileUtils::sharedFileUtils()->setSearchResolutionsOrder(resolution);
    //soundファイルもついでに設定しとく
    CCFileUtils::sharedFileUtils()->addSearchPath("sound");

    //setMultiResolution::set();
    // turn on display FPS
    pDirector->setDisplayStats(true);
    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);
    // create a scene. it's an autorelease object

    ...
}

やってることは簡単で、画面の大きさによって条件分岐して
setContentScaleFactorと
setSearchPathsと
setSearchResolutionsOrderを設定してるとうだけです。

最後のは別に必要ないのかもしれないけど、一応念のため。
これでマルチ解像度対応となっていきます。

ちなみに、setSearchPaths()を呼び出すと、最初設定したのは初期化されちゃうので注意。パスを追加したい場合はaddSearchPathを使うといいみたい。

setDesignResolutionSizeに関して

これもぼくのメモをかねてます。この第三引数によって画像をどのように表示するかを決めることができるみたい。

この引数は、以下のものを指定します。

kResolutionNoBorder
切れない部分がないようにアスペクト値は保持したまま引き延ばしてくれるみたい。
縦横両方を同じように拡大するということですね。
ただ、そのせいで画像が切れる箇所がでてきたりもします。

kResolutionShowAll
縦か横どっちかにぴったりフィットするように拡大(または縮小)を行います。
画像は全部表示されるけど、その分画面に黒い場所ができたりする。

kResolutionExactFit
縦も横も両方ぴったりフィットするように拡大(または縮小)を行います。
全部表示され、画面に黒い場所ができたりもしないけど、アスペクト値は保持されず場合によっては画像が長く伸びたりぺしゃんこになったりする。

まあぼくのは画像伸びてもいいやって思ったんで、kResolutionExactFitでいくことに。

マルチレゾリューションを意識したCCPositionの指定方法

NoBorderなどにして画面の端が見切れるようにしちゃう場合、他の画像も単純にsetPositonで指定すると見切れちゃう場合があるみたい。
そこで、以下のような感じにセットするようにするといいみたいです。

(posX、posYはもとの位置ってことで)
element->setPosition(
ccp(
CCDirector::sharedDirector()->getVisibleOrigin().x + posX ,
CCDirector::sharedDirector()->getVisibleOrigin().y + posY
));

結構面倒だからマクロ登録する方がいいかも。

補足:Xcodeではまったこと

もともとぼくはEclipseで作成してて今回はじめてXcodeを出してみたんだけど、その設定などでやたらとはまったんでメモしておきます。

Classes、Resourcesディレクトリに作ったファイルがひとつもない

わーいクロスプラットフォームでの開発〜\(^o^)/
…(´・ω・`)
的な感じでした。最初に自動でできてたHalloWorld.cppとかがそのままある感じで、
しかも本当は消してたからリンク切れみたいな感じで赤く表示されてた。

どうも、Xcodeではcocos2dxで作成したのはシンボリックリンクのようなので管理してるんだね。

ただ、これはClasses、Resourcesディレクトリを二本指タップし、
「Add Files to “myproject”」の部分からそれぞれ作成したファイルを追加していけば
無事に入ってくれました。

Android.mkでひとつひとつcppファイルを記載していかなきゃいけないのと同じような感じなのかな。

マルチレゾリューション対応にならない

5〜6時間くらいハマりました(´・ω・`)
ちゃんとできてるはずなのに、エミュレータを起動すると、あの子そのときの機嫌次第で「xdpi」「hdpi」「ldpi」からランダムに取り出してくるからひどいことになった(それが一番最初の画像のです)。

どうも、リソースの追加の仕方がだめだったみたい。
いろいろなことをやってるうちにエミュレータ自体が起動しなくなったりと泥沼化しちゃったけど、対応としては、追加する際に「Create folder reefrences for any added folders」を選択したらよかったみたいです。

multiresolution_folda

 

これで再び全部入れ直したら無事に対応できました。

cocos2dxでマルチ解像度に対応させる” への1件のコメント

  1. ピンバック: [cocos2d-x]CCLabelBMFontのフォントサイズを変更 | たそがれブランチ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です