[cocos2d-x v3] DrawNodeを使用したマスク

前回は、Pepperで任意の画像を取得して、端末内に保存する方法についてご紹介しました。
今回は、cocos2d-x v3で、DrawNodeを使用したマスクについてご紹介します。

DrawNodeは、線や図形を描画するクラスで、Spriteのように画像素材は使用しません。
当記事の目的は、cocos2d-xでマスクを実現することですが
単純な形のマスクのために、画像素材を用意するのは手間ですよね。
そういう時、DrawNodeを使用することで、無駄な素材を使用せずにマスク処理を実現することが出来ます。

■DrawNodeの生成
Spriteと同じようにcreate関数を使用し、インスタンスを生成します。

まずは簡単な円を描画してみましょう。
インタスタンスの生成が出来ましたら、DrawNodeクラスが持つ drawDot関数で円を描画します。

drawDotの引数には以下の通りです。
 第1引数 : 図形中心の座標位置
 第2引数 : 図形の半径サイズ
 第3引数 : 図形の色

    auto winSize = Director::getInstance()->getVisibleSize();

    auto draw = DrawNode::create();
    draw->drawDot( Vec2( 0, 0 ),
                   200.0f,
                   Color4F::WHITE );
    draw->setPosition( Vec2( winSize.width / 2, winSize.height / 2 ) );
    this->addChild( draw );

次は、drawPolygonを使用して多角形の図形の描画です。

drawDotの引数には以下の通りです。
 第1引数 : 頂点座標格納配列
 第2引数 : 頂点数
 第3引数 : 図形の色

    auto winSize = Director::getInstance()->getVisibleSize();

    auto draw = DrawNode::create();
    //頂点座標設定
    std::vector<Vec2>vecs;
    vecs.push_back( Vec2( 0, 200 ) );
    vecs.push_back( Vec2( 200, -100 ) );
    vecs.push_back( Vec2( 100, -200 ) );
    vecs.push_back( Vec2( -100, -200 ) );
    vecs.push_back( Vec2( -200, -100 ) );

    draw->drawPolygon( &vecs[0], 5, Color4F::WHITE, 1, Color4F::YELLOW );
    draw->setPosition( Vec2( winSize.width / 2, winSize.height / 2 ) );
    this->addChild( draw );

三角形

五角形

DrawDotで図形の描画ができたところで、当記事の本題であるマスク処理に移ります。

■ClippingNodeでマスク処理
これからご紹介するマスク処理には
cocos2d-x v2系から用意されている、ClippingNodeクラスを使用します。

当記事のcocos2d-xは v3系ですが、v2系の場合でもほとんど同じ書き方で使用することが出来ます。

他のNode継承クラスと同様、create関数でインスタンスを生成します。
あとは、ClippingNodeインスタンスに生成したマスク用Nodeを設定するだけでマスク処理を実現することが出来ます。

ClippingNodeクラスのsetInverted関数にtrueを設定することで、マスクの効果が反転します。

    auto winSize = Director::getInstance()->getVisibleSize();

  // addChildはしない
    auto draw = DrawNode::create();
    draw->drawDot( Vec2( 0, 0 ),
                   200.0f,
                   Color4F::WHITE );
    draw->setPosition( Vec2( winSize.width / 2, winSize.height / 2 ) );


    auto clipping = ClippingNode::create();
    clipping->setStencil( draw );
    clipping->setInverted( true );
    clipping->setAlphaThreshold( 1.0 );
    addChild( clipping );

    auto sprite = Sprite::create("HelloWorld.png");
    sprite->setPosition( Vec2( winSize.width / 2, winSize.height / 2 ) );
    clipping->addChild( sprite );

DrawNodeでマスク処理をする上で、注意しなければいけない点が1つあります。

当記事の始めでご紹介した drawDot関数で描画した円を使用した場合
正常に円の形ではマスクされず、円が持つ矩形範囲でマスクがかかります。

この問題を解決するには、丸く塗りつぶされている画像を使用してSpriteでマスクを行うか
drawDotではなくdrawPolygonを使用して以下のような処理で作成した円を使用します。


    auto draw = DrawNode::create();

    std::vector<Vec2>vecs;

    //頂点数
    int vertices = 50;

    for (int i = 0; i < vertices; i++)
    {
        vecs.push_back( Vec2( 30 * cos( 3.14 / 180 * ( 360 * i / vertices ) ),
                             30 * sin( 3.14 / 180 * ( 360 * i / vertices ) ) ) );
    }
    draw->setPosition( Vec2( winSize.width / 2, winSize.height / 2 ) );
    draw->drawPolygon( &vecs[0], vertices, Color4F::WHITE, 0, Color4F::WHITE );

以上で、cocos2d-xでの基本的なマスク方法のご紹介は終了です。
最後までご覧頂き、ありがとうございました。


弊社では全国各地の請負い(ご自宅)で作業協力頂ける、フリーランスエンジニアの方を常時探しております。
ご興味ある方は、お気軽にお問い合わせ下さい。


コメントを残す

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

*