cocos2d-x 3.x系 TIPS Armature同士の当たり判定 | 最高のゲームを、最高の仲間と作って、最高のお客様に遊んでほしいと思う人のブログ

最高のゲームを、最高の仲間と作って、最高のお客様に遊んでほしいと思う人のブログ

静岡のゲーム開発教室を運営しているモノリズムの代表。
ゲームをクリエイトするために必要な情報から技術。
それらを投稿していきながら自分の勉強も兼ねて不定期で投稿するブログです。

つまりcocostudioで作成したアニメーション同士で
衝突判定をしたいってことですな。

あまりこのあたりの情報が無いのでできるか模索して
できたっぽいのでメモ。

まぁ、最悪直接プログラミングで全てやることも場合によってはありかと。。
ただ、全体効率化を考えると外部データとして置いた方が、絶対楽でスマートでいいですよね。

で、早速ソース。

念のためアニメーションデータを読み込んで再生する部分も記載。
ちなみにアニメーションデータ内はそれぞれ内部に複数の画像が
存在しアニメーションしている前提です。

===============================================================
{// アニメーションAの読み込みと再生
cocostudio::CCArmatureDataManager::getInstance()->addArmatureFileInfo("AAA.ExportJson");
Armature* armCC = Armature::create("AAA", this);
CCASSERT(armCC!=nullptr, "armature create failed");
armCC->setPosition(Point(320, 320));
armCC->getAnimation()->play("Animation");
this->addChild(armCC, ZORDER_AAA, OBJ_TAG_AAA);
}

{// アニメーションBの読み込みと再生
cocostudio::CCArmatureDataManager::getInstance()->addArmatureFileInfo("BBB.ExportJson");
Armature* armCC = Armature::create("BBB", this);
CCASSERT(armCC!=nullptr, "armature create failed");
armCC->setPosition(Point(320, 320));
armCC->getAnimation()->play("Animation");
this->addChild(armCC, ZORDER_BBB, OBJ_TAG_BBB);
}
===============================================================

これで再生して表示はされるはず。

そして次にマイフレームA, Bが接触しているか判定。
とりあえず各アニメーション内にあるボーン(つまりオブジェクト)を総当たり判定です。

*当然initメソッド内で「scheduleUpdate」を呼び出して、
*updateメソッドが呼び出されるようにしておきましょう。
*そしてupdateをオーバーライドしましょう。

===============================================================
void MainGame::update(float dt)
{
// まずArmature AAA のボーン(つまり1オブジェクト分に指す)の配列を取得します。
cocostudio::Armature* armAAA = dynamic_cast<cocostudio::Armature*>(this->getChildByTag(OBJ_TAG_AAA));
cocos2d::Map<std::string, cocostudio::Bone*> boneMapAAA = armAAA->getBoneDic();

// オブジェクト分ループ実施
cocos2d::Map<std::string, cocostudio::Bone*>::iterator map_iteAAA;
for (map_iteAAA=boneMapAAA.begin();map_iteAAA!=boneMapAAA.end();map_iteAAA++){

//log("AAA name = %s", map_iteAAA->first.c_str());

// オブジェクトを取得しあたり判定矩形情報(Rect)を取得する。
cocostudio::Bone* boneAAA = dynamic_cast<cocostudio::Bone*>(map_iteAAA->second);
Rect brAAA = boneAAA->getDisplayManager()->getBoundingBox();

// 判定相手を取得 つまり Armature BBB ですね。
cocostudio::Armature* armBBB = dynamic_cast<cocostudio::Armature*>(this->getChildByTag(OBJ_TAG_BBB));
cocos2d::Map<std::string, cocostudio::Bone*> boneMapBBB = armBBB->getBoneDic();
cocos2d::Map<std::string, cocostudio::Bone*>::iterator map_iteBBB;
for (map_iteBBB=boneMapBBB.begin();map_iteBBB!=boneMapBBB.end();map_iteBBB++)
{
//log("BBB name = %s", map_iteBBB->first.c_str());

// オブジェクトを取得しあたり判定矩形情報(Rect)を取得する。
cocostudio::Bone* boneBBB = dynamic_cast<cocostudio::Bone*>(map_iteBBB->second);
Rect brBBB = boneBBB->getDisplayManager()->getBoundingBox();

// AAA と BBB の当たり判定実施
if ( brAAA.intersectsRect(brBBB) == true )
{
log("HIT!");
}
}
}
}
===============================================================

悩んだのがアニメーション計算結果(つまり座標やサイズなど)が
どこに格納されているかでした。同じような情報が点在していましたが、
とりあえずこれで大丈夫なような気がします。

あとはこれを基本にあたり判定対象をボーン名などで必要なオブジェクトだけ
当たり判定をするようにしたりすればいいかと思います。