Isometric MapのZオーダーの指定方法
Cocos2d-xでIsometric Mapを使ったゲームのサンプルを作成していたところz-order(zorder, zindex, z-index)の指定で結構ハマったのでメモです。
Isometric Mapというのはよくある2.5D的な1マスが菱形になっているマップのことです。こんな感じのやつです。
Isometric Mapを使った有名なゲームだとクラッシュオブクランなんかがあります。
ゲームで使用するマップデータの作成を無料のTiled Map Editorというツールを使ってCocos2d-xと連携させて使っていました。
TiledMap Editorを使うとわりと簡単にマップを作成することはできるものの、マップの上にキャラだったり建物だったりを配置するとZオーダーの問題が出てきます。
そこで以下の図のようにマップ座標のxとyを足した値をZオーダーに設定するとうまくいきました(図は40マス×40マスのマップの例です)。
プログラムにすると以下のような感じになります。
bool HelloWorldScene::init() { ////////////////////////////// // 1. super init first if ( !Layer::init()) { return false; } auto tiledMap = TMXTiledMap::create("tiledmap.tmx"); this->addChild(tiledMap, 1, "tiledMap"); auto layer = tiledMap->getLayer("layer_name"); Size size = tiledMap->getMapSize(); // マップのサイズ分まわす for (int i = 0; i < size.width; i++) { for (int j = 0; j < size.height; j++) { Vec2 pos = Vec2(i, j); // タイルオブジェクトを取得 auto tile = layer->getTileAt(pos); // タイルが存在する場合 if (tile) { // GIDを取得 auto gid = layer->getTileGIDAt(pos); // GIDごとに建物を配置 if (gid == 1) { auto sprite = Sprite::create("building.png"); // タイルの真ん中の位置にスプライトをセット Vec2 midPoint = tile->getPosition() + (tile->getContentSize() / 2); sprite->setPosition(midPoint); // Zオーダーを指定してスプライトをタイルマップに追加する tiledMap->addChild(sprite, i + j); } } } } }
上記は動かないスプライトの例ですが、スプライトを動かす場合はポジションからマップ上の座標を計算してZオーダーを設定してやると上手くいきます。
通常の座標からマップ上に座標に変換する方法は以下のサイトが参考になります。