cocos2d-x 3.0で複雑なあたり判定をもつspriteをつくった話

PhysicsBodyには凸多角形のボディを作る機能があるので、それを使った。別に複雑でもない。
そんなに書くことないけどわからない人向け。

PhysicsBodyを作る

PhysicsBody::createPolygonは、第一引数に点の順序付き配列のポインタ、第二引数に点の数を取る。

Hoge.cpp

Sprite* sprite = Sprite.create("sprite.png");
Point spritePoints[8] =
  {
    Point(-170,-110), Point(-186,-67), Point(-186,-51), Point(-118,110),
    Point(184,110), Point(184,96), Point(-37,-89), Point(-164,-110)
  };
auto spriteBody = PhysicsBody::createPolygon(spritePoints, 8);
sprite->setPhysicsBody(sptiteBody);

spritePointで多角形の頂点を作ってやって、createPolygonに渡すだけ。
Pointの中身は、spriteの基準点(デフォルトでは中心)からの距離。
点をつないだ多角形の一部でもへこんでいたら(凸多角形じゃなかったら)エラーを吐く。

注意としては、spritePointの頂点群は、作ろうとしている多角形を右回りにたどる順番にすること。
点と点をつないだ直線の右側に判定領域が形成されるイメージ。

あたり判定をつける

つくったspriteBodyを

spriteBody->setEnable(true);
spriteBody->setContactTestBitmask(1);
spriteBody->setVelocityLimit(100.0);
spriteBody->setTag(kBodyTagSprite);
this->addChild(sprite, オーダー, タグ);

こんな感じで実体化してやればonContactBeginに反応してくれる。

bool Hoge::onContactBegin(cocos2d::PhysicsContact& contact)
{
  if ( ( contact.getShapeA()->getBody()->getTag() == kBodyTagSprite || contact.getShapeB()->getBody()->getTag() == kBodyTagSprite ) )
    {
      CCLOG("あたった");
      return true;
    }
}