様々なディスプレイのサイズに合わせてゲームをつくるのにはどうしたらよいのでしょうか。書籍などには様々な設定方法とその表示結果が紹介されていますが結局どれを選択したらよいのか?できるだけ手間をかけずに対応したかったので以下の条件でいろいろ試しました。
- ゲーム画面のデザインが簡単
- プログラムへの画像の組み込みが簡単
- 解像度に関係なく用意する画像は1つにしたい
- スマホだけ考えてタブレットの画質は考慮しない
その結果、ゲーム画面は以下のルールで作成することに決めました。
- ゲーム画面は640 x 1136 pxで設計
- 画像の座標は640 x 1136 pxの中央を原点とする
- ゲームの操作は中央を原点とした640 x 960 pxの範囲内にする
このルールで作られた画像をResolutionPolicy::NO_BORDERでディスプレイにフィットさせて表示しています。
実際にこの条件で作った画面をiPhone 4, iPhone 5s, nexus 5で表示してみて操作と画質に問題がないと判断してこの仕様に決めました。iPhone 4をサポートしていることもありますがiPadで操作できないとappleの審査でリジェクトされるのでゲームの操作は640 x 960 pxの範囲内で可能にしています。
AppDelegate.h
1 2 3 4 5 6 7 |
横画面のとき #define APP_VIEW_WIDTH 1136 #define APP_VIEW_HEIGHT 640 縦画面のとき #define APP_VIEW_WIDTH 640 #define APP_VIEW_HEIGHT 1136 |
AppDelegate.cpp
1 |
glview->setDesignResolutionSize(APP_VIEW_WIDTH, APP_VIEW_HEIGHT, ResolutionPolicy::NO_BORDER); |
画像の位置は画面の中央を原点にしてデザインしています。
画面のデザインもプログラムへの画像の組み込みも中央が原点の方が直感的に解りやすいのでこの方法に決めました。
プログラムで画像の座標を指定するときは中央が原点の座標を画面の原点へ変換する関数を使用しています。左端と右端を原点とした座標の変換も実装しています。
HelloWorldScene.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#include "cocos2d.h" #include "AppDelegate.h" USING_NS_CC; class HelloWorld : public Layer { private: // 画面の座標を中心に変換する関数 Point cntr(int x, int y); Point left(int x, int y); Point right(int x, int y); public: static Scene* createScene(); virtual bool init(); CREATE_FUNC(HelloWorld); }; |
HelloWorldScene.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include "HelloWorldScene.h" Scene* HelloWorld::createScene() { auto scene = Scene::create(); auto layer = HelloWorld::create(); scene->addChild(layer); return scene; } bool HelloWorld::init() { if ( !Layer::init() ) { return false; } // 画像を画面中央に表示 auto imageCenter = Sprite::create("HelloWorld.png"); imageCenter->setPosition(cntr(0, 0)); imageCenter->setScale(0.5); this->addChild(imageCenter); // 画像を画面左端に表示 auto imageLeft = Sprite::create("HelloWorld.png"); imageLeft->setPosition(left(0, 0)); imageLeft->setScale(0.5); this->addChild(imageLeft); // 画像を画面右端に表示 auto imageRight = Sprite::create("HelloWorld.png"); imageRight->setPosition(right(0, 0)); imageRight->setScale(0.5); this->addChild(imageRight); return true; } // 中心からの座標を計算 Point HelloWorld::cntr(int x, int y) { return Point(APP_VIEW_WIDTH / 2 + x, APP_VIEW_HEIGHT / 2 + y); } // 左端からの座標を計算 Point HelloWorld::left(int x, int y) { // デザインの画面サイズと実際の画面サイズの差を計算 Size visibleSize = Director::getInstance()->getVisibleSize(); int d = (APP_VIEW_WIDTH - visibleSize.width) / 2; return Point(d + x, APP_VIEW_HEIGHT / 2 + y); } // 右端からの座標を計算 Point HelloWorld::right(int x, int y) { // デザインの画面サイズと実際の画面サイズの差を計算 Size visibleSize = Director::getInstance()->getVisibleSize(); int d = (APP_VIEW_WIDTH - visibleSize.width) / 2; return Point(APP_VIEW_WIDTH - d - x, APP_VIEW_HEIGHT / 2 + y); } |
私たちはこのような方法でゲームをデザインしています。