cocos_catch01

Cocos2d-xで対角線グラデーションを実装してみる(LayerGradient)。

cocos2d-xのLayerGradientは通常、グラデーションの位置を調整することができませんが少し工夫するとグラデーションの最終地点を変えることができます。

下記のような対角線を最終地点とするグラデーションを目標とします。

下記図形を使って説明していきましょう。

対角線に沿ってグラデーション図形を傾けます

対角まで幅を引き延ばします

ここで上の図に示す r およびθを求めます

次にdを求めましょう

結果的に描画に必要な情報は以下のように算出されます。

グラデーション(LayerGradient)オブジェクトの各値

width : r = sqrt(a^2 + b^2)
height : d = b sinθ
rotation : θ = atan( b / a)

あとは元となった対象図形(図の水色部分)でマスクすれば、出来上がり。
ソースも掲載しておきますのでご自由にお使いください。

DiagonalHarfGradationLayer.h

#ifndef DiagonalHarfGradationLayer_h
#define DiagonalHarfGradationLayer_h

#include "cocos2d.h"
// 右上から左下へグラデ
#define GRAD_DIRECTION_TO_BOTTOM_LEFT 1
// 左上から右下へグラデ
#define GRAD_DIRECTION_TO_BOTTOM_RIGHT 2
// 右下から左上へグラデ
#define GRAD_DIRECTION_TO_TOP_LEFT 3
// 左下から右上へグラデ
#define GRAD_DIRECTION_TO_TOP_RIGHT 4

class DiagonalHarfGradationLayer : public cocos2d::Layer
{
public:
    CREATE_FUNC(DiagonalHarfGradationLayer);
    void initView(const cocos2d::Color4B& startColor, const cocos2d::Color4B& endColor, int direction);
};

#endif /* DiagonalHarfGradationLayer_h */

DiagonalHarfGradationLayer.cpp

※2017/7/1 グラデーションオブジェクトの座標位置に謝りがありました。訂正しております。


#include "DiagonalHarfGradationLayer.h"

#define PI 3.14159265358979323846

USING_NS_CC;

void DiagonalHarfGradationLayer::initView(const Color4B& startColor, const Color4B& endColor, int direction)
{
    Size s0 = this->getContentSize();
    
    int a = s0.width;
    int b = s0.height;
    
    // clip view
    ClippingNode* clipNd = ClippingNode::create();
    clipNd->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
    clipNd->setContentSize(s0);
    clipNd->setPosition(Point(0, 0));
    this->addChild(clipNd);
    
    // mask
    LayerColor* mask = LayerColor::create(Color4B::BLACK, s0.width, s0.height);
    clipNd->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
    clipNd->setPosition(Point(0, 0));
    clipNd->setStencil(mask);
    
    // gradation
    LayerGradient* gLayer;
    
    int r = sqrt(a*a + b*b);
    float theta = atan((double)b / a);
    float phy = PI * 0.5 - theta;
    int d = b * sin(phy);
    
    switch (direction) {
        case GRAD_DIRECTION_TO_BOTTOM_LEFT:
            gLayer = LayerGradient::create(startColor, endColor, Point(0, -1));
            gLayer->setContentSize(Size(r, d));
            gLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_RIGHT);
            gLayer->setRotation(theta / PI * 180);
            gLayer->setPosition(Point(a-r, 0));
            clipNd->addChild(gLayer);
            break;
            
        case GRAD_DIRECTION_TO_BOTTOM_RIGHT:
            gLayer = LayerGradient::create(startColor, endColor, Point(0, -1));
            gLayer->setContentSize(Size(r, d));
            gLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
            gLayer->setRotation(-theta / PI * 180);
            gLayer->setPosition(Point(0, 0));
            clipNd->addChild(gLayer);
            break;
            
        case GRAD_DIRECTION_TO_TOP_LEFT:
            gLayer = LayerGradient::create(startColor, endColor, Point(0, 1));
            gLayer->setContentSize(Size(r, d));
            gLayer->setAnchorPoint(Point::ANCHOR_TOP_RIGHT);
            gLayer->setRotation(-theta / PI * 180);
            gLayer->setPosition(Point(a-r, b-d));
            clipNd->addChild(gLayer);
            break;
            
        case GRAD_DIRECTION_TO_TOP_RIGHT:
            gLayer = LayerGradient::create(startColor, endColor, Point(0, 1));
            gLayer->setContentSize(Size(r, d));
            gLayer->setAnchorPoint(Point::ANCHOR_TOP_LEFT);
            gLayer->setRotation(theta / PI * 180);
            gLayer->setPosition(Point(0, b-d));
            clipNd->addChild(gLayer);
            break;
        default:
            break;
    }
    
}

呼び出し例

...
#include "DiagonalHarfGradationLayer.h"
USING_NS_CC;
...
    std::vector<float> bgColor = {128,128,128};
    DiagonalHarfGradationLayer* bgLayer = DiagonalHarfGradationLayer::create();
    bgLayer->setContentSize(Size(320,160));
    bgLayer->setAnchorPoint(Point::ANCHOR_BOTTOM_LEFT);
    bgLayer->initView(Color4B(bgColor[0], bgColor[1], bgColor[2], 255), Color4B(bgColor[0], bgColor[1], bgColor[2], 0), GRAD_DIRECTION_TO_BOTTOM_LEFT);
    bgLayer->setPosition(Point(200, 200));
    this->addChild(bgLayer, BgTag, BgTag);
...

コメントを残す

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