2Dゲームを作成する際に、タイルマップを利用すれば簡単にステージが作成できます。 私個人としても「BOOKQUEST」「CHAINSHOT」ともにタイルマップを利用しています。 今回は、cocos2dx3.xでこの「タイルマップ」についてブログで紹介をしていきたいと思います。
タイルマップの作成
タイルマップを作成する際には「Tiled」を利用します。 久しぶりに利用をしてみたら、少しUIが変わっていましたが、以前と同じように簡単にタイルマップが作成できます。
cocos2dxのプロジェクトへ追加
作成したタイルマップをcocos2dxのプロジェクトへ追加します。 [.tmx]を読み込む専用のクラスが用意されているのでとても簡単に利用ができます。 [c]
//タイルマップ作成 auto tileMap = TMXTiledMap::create("tiledMap.tmx"); tileMap->setPosition(Point(0,winSize.height*0.35)); this->addChild(_tileMap);
//特定のLayerの取り出し auto collisionLayer =(TMXLayer*)_tileMap->getLayer("collision");
[/c]
画面のチラツキへの対応
ここからは、今回初めて勉強したことです。 特にAndroid側で、タイルマップに隙間ができたり、タイルがチラついて見える場合があります。 この問題への対応は以下の通りです。 [c] //AppDelegate.cpp
bool AppDelegate::applicationDidFinishLaunching() { // initialize director auto director = Director::getInstance(); auto glview = director->getOpenGLView(); if(!glview) { glview = GLView::create("My Game"); director->setOpenGLView(glview); }
//この2行を追加
director->getInstance()->setProjection(Director::Projection::_2D);
director->getInstance()->setDepthTest(false);
/// /// ///
} [/c]
またタイルマップを追加したレイアーでも以下の処理を行います。 [c] //タイルマップ作成 auto tileMap = TMXTiledMap::create("tiledMap.tmx"); tileMap->setPosition(Point(0,winSize.height*0.35)); this->addChild(_tileMap);
//アンチエイリアスを無視する(tiled) Vector<Node> array = _tileMap->getChildren(); SpriteBatchNode tileChild = NULL;
for(int i = 0; i < array.size();i++){
tileChild = (SpriteBatchNode*)array.at(i); if (!tileChild) {
break;
}
tileChild->getTexture()->setAntiAliasTexParameters(); } [/c]
個人的な感想としてAppDelegate.cppでの処理だけで不具合が出ることが無くなりました。 詳しくは下記サイトを参考にして下さい。 【参考】 ㊱タイルマップに挑戦
マルチディスプレイへの対応
cocos2dxでは、色々なディスプレイへの対応が必要なのです。 私が、タイルマップをしばらく敬遠していたのが、このタイルマップの対応でした。 以前も色々と調べていたのですが、画面サイズが変わると、「衝突判定」が上手くいかないこと、また「タイルマップの位置がおかしくなる」などが解消できなかったからです。 ただ、これも上手くいきそうです。
画面サイズをあわせる
まずは、画面サイズをデバイスサイズに合わせて調整をします。 このような感じです。 [c] //Appdelegate.cpp glview->setDesignResolutionSize(320, 480, ResolutionPolicy::SHOW_ALL); director->setContentScaleFactor(2.0f);
[/c]
こうすることで、Size(320,480)を基準に画面を調節します。 Retinaの場合は、setContentScaleFactor()を使って画像サイズを調整します。
タイルマップ上の位置を取得する
ここが大事な所です。 通常の画像は、上記の方法だけで特に何もしなくて良いのですが、タイルマップの「位置」を取得する場合は少し工夫が必要です。 [c] //タイルマップの大きさを調整する Director *director = Director::getInstance(); float width1 = timeMap->getTileSize().width/director->getContentScaleFactor(); float height1 = timeMap->getTileSize().height/director->getContentScaleFactor(); float height2 = timeMap->getMapSize().height;
int x = (int)(point.x / width1); int y = (int)(height2 * height1 - point.y + timeMap->getPosition().y)/_height1;
//タイルマップの位置 = Point(x,y);
[/c]
このように、Retina時に利用をしたScaleFactorで「タイル」の大きさを調整します。
【iPod Retina4】
【Nexus4】
【Nexus5】
最後に
画面の調整は、万能ではなにので気になる部分はあります。 特にRetina4に関しては空白ができるので、何かで調整をしないといけない感じがします。
ともあれ、これでタイルマップに関する懸念点は無くなりましたので、「ドット絵」を使ったゲームを作る準備はできました。 今年中には、アクションRPGを作りたいと思います。