衝突判定を実装する2回目です。 今回は「オブジェクト」と「タイルマップのレイアー」との衝突判定について書いていこうと思います。 あくまでも私が利用している方法ですので、これ以外にもやり方はあるかと思います。是非、一度見てみて参考になる部分があれば幸いです。
◀前回▶
Tiledでの設定
準備として、衝突判定に利用したいレイアーを作成します。
「名前」や「プロパティ」を設定して、後でレイアーを取り出せるようにします。
[Tiled] タイルマップはこの「Tiled」で作成してください。
レイアーを取り出す
Tiledで設定したタイルマップから、衝突判定のレイアーを取り出します。 [c]
//タイルマップの初期化 CCTMXTiledMap *map = myTMXTileMap::create("map.tmx");
//レイアーの名前で取り出す CCTMXLayer *collisionLayer = map->layerNamed("collision");
[/c]
タイルレイアーとの衝突判定についての概要
取り出したレイアーと衝突判定を行いたいオブジェクトを利用して、下記の画像のように判定を行います。
オブジェクトから、スプライトの頂点を取り出す
まずは、オブジェクトのポジションやスプライトのサイズから、スプライトの頂点を取り出します。
[c]
//connerは頂点を格納するCCPoint型 //objectRectは、衝突判定をしたいオブジェクトの領域 void GameObject::setConnerPoint(cocos2d::CCPoint*corner,cocos2d::CCRect objectRect){
corner[0] = ccp(objectRect.origin.x,objectRect.origin.y);
corner[1] = ccp(objectRect.origin.x,objectRect.origin.y + objectRect.size.height);
corner[2] = ccp(objectRect.origin.x + objectRect.size.width,objectRect.origin.y);
corner[3] = ccp(objectRect.origin.x + objectRect.size.width,objectRect.origin.y + objectRect.size.height);
}
[/c]
衝突判定を行う
上記の方法で、4つの頂点を取り出します。 これをfor文を利用して、タイルマップのレイアーと重なっていないかを判定します。
頂点をタイルマップの座標に置き換える
頂点をタイルマップ上で利用できる座標に変換をしなくてはいけません。 [c]
//頂点をタイルマップの座標に置き換えます。 float x = (conrner[i].x -this->getPosition().x) / tileSize.width; float y = *1;
[/c]
int型のtileに何か値が代入されているかどうかで衝突を判定します。 [c]
for (int i = 0; i < 4; i++) {
int tile = 0;
float x = (conrner[i].x -this->getPosition().x) / tileSize.width; float y = *2;
return tile;
}
[/c]
後はこれをオブジェクトのルート内で利用して衝突判定時に、動きを止めるなりのアクションを行います。
最後に
簡単ながら、タイルマップのレイアーとの衝突判定について記述をしていきました。 あくまで基本的な考え方などを書いていますので、これを上手く拡張させれば、色々な場面で衝突判定ができるでしょう。
冒頭でも書きましたが、これはあくまで1通りの方法です。 私も、これで正しいのかはわかりませんが、これで上手く判定ができています。 もし、この方法以外に何か良い方法があれば、教えていただけると嬉しいです。引き出しは多いほうがいいと思います。
![]() | Cocos2d‐x開発のレシピ―iOS/Android対応 松浦 晃洋,齊藤 建二,古木 映治 秀和システム 売り上げランキング : 1224 Amazonで詳しく見る |
*1:map2->getMapSize().height * tileSize.height)-point.y + this->getPosition().y )/_tileSize.height;
[/c]
衝突判定を行います。
タイルマップの座標x,yを利用して、最初に取り出したcollisionLayerと衝突判定を行います。 その際には[tileGIDAt]を利用します。 [c]
//レイアーと判定をします。 int tile = collisionLayer->tileGIDAt(ccp((int)x, (int)y
*2:map2->getMapSize().height * tileSize.height)-point.y + this->getPosition().y )/_tileSize.height; tile = collisionLayer->tileGIDAt(ccp((int)x, (int)y