Cocos2d-x ver3.2 … PhysicsSprite を試してみる (忘れている… ^^;

今日はこのチュートリアルを試してみる…

[Cocos3.0 Tutorial] Accurate hit testing with Cocos2d-x 3.0 integrated physics feature
http://discuss.cocos2d-x.org/t/cocos3-0-tutorial-accurate-hit-testing-with-cocos2d-x-3-0-integrated-physics-feature/13393

… ターミナルで コマンド “java -jar ph physics-body-editor.jar” 試してみると… 落ちてる… っぽい… (英語がわからんwww ^^;

うむむむ… ここをは気を取り直して… これを試してみよう… ^^;;;
Cocos2d-x V3 Accurate Physics Body Shape With PhysicsEditor
http://jslim.net/blog/2014/10/10/cocos2d-x-v3-accurate-physics-body-shape-with-physicseditor/

PhysicsEditor から Chipmunk用のデータを出力したplistとpngをプロジェクトに取り込んで… コードを記述。ふむふむ…

    auto sprite = Sprite::create("test01.png");
    {
        auto body   = PhysicsBody::createBox(sprite->getContentSize());
        sprite->setPhysicsBody(body);
    }

    this->addChild(sprite);

あれ?説明のようなデバッグ表示されなくね?
そういえばデバッグ表示どうだっけ…?

薄い記憶を辿っても全然思い出せなかったので…サンプルコードを覗いてみると、 あーそうだったわ…ww Scene がメソッドを持ってたわーww ^^;;

しかも、そうか、 Scene は Scene::createWithPhysics() で生成するのかwww
ということで、Scene を返す createScene() で以下の記述

    auto scene = Scene::createWithPhysics();
    scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL);

自己不信になりつつもデバッグ実行じゃー… ^^;

って、落ちていくのかいーwww

あー、なるほど…
先ほど作った PhysicsBody を static_body に設定するのか…

    //static_bodyに
    body->setDynamic(false);

この時点では 四角 になるので、先ほど作った plistを読み込むための Loader を https://github.com/baibai2013/PhysicsEditor-Loader-for-cocos2d-x-3.0 からコピってくると…

なるほどww
PhysicsEditor で作成したデータを読み込む記述は、以下のような感じ。

     PEShapeCache::getInstance()->addBodysWithFile("body.plist");

     //形状
     //auto body = PhysicsBody::createBox(sprite->getContentSize());
     auto body = PEShapeCache::getInstance()->getPhysicsBodyByName("test01");

「Physics Body Editor」を動かせずに完全に目的を見失ってましたが…、最初の目的のタップした座標とSpriteの当たり判定を試してみました。

まずは当たり判定のメソッドを…コピペ ^^;

//タッチ判定例
Node* HelloWorld::nodeUnderTouch(Touch *touch)
{
    Node * node = nullptr;

    do
    {
        if (!touch)
        {
            break;
        }

        auto sprite = dynamic_cast<Sprite *>(this->getChildByName("test01"));
        if (!sprite)
        {
            break;
        }

        //TODO: 座標の取得の仕方...(要勉強...)
        //auto location = touch->getLocation();
        auto location = this->convertToNodeSpace(touch->getLocation());

        //当たり判定をしてくれてるみたい
        //戻り値は Vector<PhysicsShape *>
        auto array = this->getScene()->getPhysicsWorld()->getShapes(location);

        //当たり判定したノードの中から目的のものがあるか
        for (auto obj : array)
        {
            auto tmpNode = obj->getBody()->getNode();
            if (tmpNode == sprite)
            {
                node = tmpNode;
                break;
            }
        }

    } while (0);

    return node;
}

次に、シングルタップの実装を…おぉぅ?完全に忘れてる(自己不信…
イベントリスナーの部分…とか完全に忘れていて凹みつつも、実装 ^^;

bool GameLayer::init()
{
    //...

        //ラベル
        {
            auto label = Label::createWithSystemFont("test", "", 48.0f);

            label->setPosition(center);

            label->setName("label");
            this->addChild(label);
        }

        //タッチ
        {
            auto listener = EventListenerTouchOneByOne::create();
            listener->onTouchBegan = CC_CALLBACK_2(GameLayer::onTouchBegan, this);

            this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(listener, this);
        }

   //...
}

bool HelloWorld::onTouchBegan(Touch *touch, Event *unused_event)
{
    CCLOG("%s", __PRETTY_FUNCTION__);

    do
    {
        auto label = dynamic_cast<Label *>(this->getChildByName("label"));
        if (!label)
        {
            break;
        }

        if (this->nodeUnderTouch(touch))
        {
            label->setString("touch the sprite !!");
            label->setColor(Color3B::RED);
        }
        else
        {
            label->setString("no touch.");
            label->setColor(Color3B::WHITE);
        }

    } while (0);

    return false;
}

デバッグ実行してみると…
おーすごいww 簡単にタップ判定できてるwww


Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です