開発時には、テキストマスクや画像マスクなど、画像の一部を表示する必要がある場合があります。
このセクションで説明するClippingNodeの機能効果は、上で見たマスク効果とほぼ同じです。
ClippingNode
1.原則
ClippingNodeを使用してノードをクリップできます。ClippingNodeはNodeのサブクラスであり、通常のノードと同様にレイヤー、シーン、ノードに配置できます。
これは主に、画像のノードをカットして任意の形状のノード表示を生成するテンプレート(ステンシル)に基づいています。
ClippingNodeは、テンプレートマスクを使用してノード領域をトリミングするテクノロジーです。
ClippingNodeのマスクを理解するにはどうすればよいですか?以下の例をご覧ください。
2.例
テンプレート(ステンシル):レイヤー、ノード、スプライトなどを使用できます。
バックプレーン:レイヤー、ノード、スプライトなどを使用できます。
Layer层
2.1、最初のグループ(背景画像のないレイヤーレイヤー)
テンプレート(ステンシル):テンプレートはノードノードで、5つのスプライトボールを配置します。
下部プレート:下部プレートはノードノードであり、スプライトのABCDダイアグラムが配置されます。
レイヤー:要素なし、背景色は黒。
クロッピングマスク効果の模式図:
2.2、2番目のグループ(レイヤーレイヤーには背景画像があります)
テンプレート(ステンシル):テンプレートはノードノードで、5つのスプライトボールを配置します。
下部プレート:下部プレートはノードノードであり、スプライトのABCDダイアグラムが配置されます。
レイヤー:SpriteのCocos2d-xの背景画像があります。
クロッピングマスク効果の模式図:
2.3分析と要約
ClippingNodeによるクリッピングマスクは、実際には次のようになります。
テンプレート(ステンシル)のすべての要素の形状コレクションは「形状テンプレート」と見なされ、要素自体はレンダリングされません。
「形状テンプレート」を使用して底板をカットします。
下部プレートからトリミングされた画像領域を表示します。
一般に:
テンプレート(ステンシル)は、さまざまな形状の多くの「穴」を持つテンプレートと同等です。
次に、テンプレートに従って、底板をカットして「掘る」。
次に、元の位置に従ってカットピースを配置します。
その中でも:テンプレート(ステンシル)は単なる「形状テンプレート」であり、画像自体は描画されません。
3.主な機能
ClippingNodeはNodeクラスを継承し、ノードのクリッピングとマスキングに使用されます。
3.1、ClippingNodeを作成する
2つの方法:テンプレート(ステンシル)を使用して作成するかどうか。
//
//テンプレートなしで作成(ステンシル)
ClippingNode * clippingNode = ClippingNode :: create();
//テンプレートを作成、使用(ステンシル)
ClippingNode * clippingNode = ClippingNode :: create(stencil);
//
3.2、テンプレートの設定(ステンシル)
テンプレートノードはノードのサブクラスです。さまざまな形状のグラフィックを描画できるため、DrawNodeがよく使用されます。もちろん、Nodeノードをテンプレートとして直接使用することもできます。
//
/ **
*カットに使用されるステンシルノード(ノード)
*テンプレート(ステンシル)オブジェクト、デフォルトはnull(nullptr)
** /
Node* stencil = Node::create(); //模板stencil节点Node
stencil-> addChild(spriteBall1); //小さなボールを追加1
stencil-> addChild(spriteBall2); //小さなボール2を追加
stencil-> addChild(spriteBall3); //小さなボール3を追加
stencil-> addChild(spriteBall4); //小さなボール4を追加
stencil-> addChild(spriteBall5); //小さなボール5を追加
clippingNode-> setStencil(stencil); //テンプレートステンシルを設定
//
3.3。底板のセット(内容)
//
// ClippingNodeを作成した後、addChild()を使用してノードを追加します。これは、下部のボードコンテンツです
clippingNode-> addChild(content); //ボトムプレートを設定する
//
3.4、反転表示(反転)
false:テンプレートによって切り取られた下部プレートのコンテンツを表示します。デフォルトはfalseです。
true:残りの部分を表示します。
//
//デフォルトはfalseです
//下部プレートのコンテンツが表示されることを示します
clippingNode-> setInverted(false);
//
3.5、アルファしきい値(alphaThreshold)
alpha:ピクセルの透明度の値を表します。
コンテンツは、ステンシル内のピクセルのアルファ値がアルファしきい値よりも大きい場合にのみ描画されます。
アルファしきい値(alphaThreshold):値の範囲[0,1]。
デフォルトは1です。これは、アルファテストがデフォルトで閉じていること、つまりすべてが描画されていることを意味します。
1でない場合は、アルファピクセルがalphaThresholdより大きいテンプレートのコンテンツのみが描画されることを意味します。
//
//アルファ透明度ゲート値を設定します
//表示テンプレートで、アルファピクセルが0.05より大きいコンテンツ
holesClipper-> setAlphaThreshold(0.05f);
//
具体的な手順:
以下は、40 * 40の画像で、ボールを除く他の領域のピクセルは透明です(つまり、アルファは0です)。
(1)AlphaThresholdゲート値またはsetAlphaThreshold(1.0f)を設定しない場合:
(2)setAlphaThreshold(0.5f)を設定した場合:
(3)結論:
アルファゲート値が設定されていない場合、テンプレートによって描画される領域は40 * 40の長方形であることがわかります。
アルファゲート値が0.5に設定されている場合、透明度アルファが0のピクセルは描画されず、小さな円のみが描画されます。
コード戦闘
ここにいくつかの興味深い例があります。
公式の「パンチ穴」
「テキストマスクの光沢のある特殊効果」
ClippingNodeクラスは非常に用途が広いです。
1.公式の「穴あけ」
ClippingNodeを使用して公式のcpp-testプロジェクトの「穴あけ」効果を完成させる例がありますが、これは非常に興味深いものです。
その他の使用法については、公式のcpp-testプロジェクトを参照してください。
最初に効果を見てみましょう:
1.1、素材
1.2。HelloWorld.hに次の変数と関数を追加します
//
ClippingNode * holeClipper; //ノードのクリップ
Node * holesStencil; //テンプレートノード
ノード*ホール; //ボトムボードノード
//タッチコールバック
void onTouchesBegan(const std :: vector&touches、Event * unused_event);
//小さな穴を追加します
void pokeHoleAtPoint(Vec2 point);
//
1.3。HelloWorld.cppのinit()でクリッピングノードClippingNodeを作成する
//
// [1]。背景レイヤー画像(レイヤーレイヤー内)
Sprite * bg = Sprite :: create( "HelloWorld.png");
bg-> setPosition(visibleSize / 2);
this-> addChild(bg);
// [2]。クリッピングノードを作成する:holeClipper
holesClipper = ClippingNode :: create();
holesClipper-> setPosition(visibleSize / 2);
this-> addChild(holesClipper);
//プロパティ設定
holesClipper-> setInverted(true); //反転表示、切り取られていない残りの部分
holesClipper-> setAlphaThreshold(0.5f); //アルファ透明度ゲート値を設定
holesClipper-> runAction(RepeatForever :: create(RotateBy :: create(1、45)))); //回転アクション
// [3]。テンプレートを作成します:holeStencil
holesStencil = Node :: create();
holesClipper-> setStencil(holesStencil); //テンプレートノードを設定
//テンプレートマスクボールを追加します
holesStencil-> addChild(Sprite :: create( "ball.png")、-1);
// [4]。底板を作成:穴
穴=ノード::作成();
holesClipper-> addChild(holes); //底板を設定します
//別のボードコンテンツブロックを追加します
Sprite * content = Sprite :: create( "blocks.png");
holesClipper-> addChild(content、-1、 "content");
// [5]。タッチイベント
自動リスナー= EventListenerTouchAllAtOnce :: create();
listener-> onTouchesBegan = CC_CALLBACK_2(HelloWorld :: onTouchesBegan、this);
_eventDispatcher-> addEventListenerWithSceneGraphPriority(listener、this);
//
1.4。タッチイベントコールバックを設定します。タッチポイントが下部パネル領域内にある場合、「穴」
//
void HelloWorld :: onTouchesBegan(const std :: vector&touches、Event * unused_event)
{
// [1]。連絡先を取得し、holesClipperノードの相対座標に変換します
Vec2ポイント= touches [0]-> getLocation();
ポイント= holesClipper-> convertToNodeSpace(point);
// [2]。床面積の長方形の四角形を取得します
Sprite * content =(Sprite *)holesClipper-> getChildByName( "content");
サイズcontentSize = content-> getContentSize();
Rect rect = Rect(-contentSize.width / 2、-contentSize.height / 2、contentSize.width、contentSize.height);
// [3]。タッチポイントは下部プレート内にあり、「パンチ穴」
if(rect.containsPoint(point))
{
pokeHoleAtPoint(point);
}
}
//
1.5。「穴あけ」操作機能を実現
//
void HelloWorld :: pokeHoleAtPoint(Vec2 point)
{
CCLOG( "穴を追加!!!");
// [1]。底板の内容を追加:穴の跡
自動穴= Sprite :: create( "hole_effect.png");
hole-> setPosition(point);
穴-> addChild(穴);
// [2]。テンプレートコンテンツを追加する:小さな穴
auto holeStencil = Sprite :: create( "hole_stencil.png");
holeStencil-> setPosition(point);
holesStencil-> addChild(holeStencil);
// [3]。アクション効果:ズームインおよびズームアウト
holesClipper-> runAction(Sequence :: create(ScaleTo :: create(0.05f、1.05f)、ScaleTo :: create(0.05f、1.0f)、NULL));
}
//
1.6、分析と要約
ここでは、反転表示(Inverted)を設定しています。つまり、テンプレートを使用して底板をカットした後、カットされていない残りの部分が表示されます。
(1)テンプレートステンシル:
(2)底板:
(3)トリミングマスクの効果:テンプレートでトリミングされていない残りの部分を表示します。
2.「テキストマスク効果」
最初に効果を見てみましょう:
2.1、素材
2.2、コードの実装
//
// [1]。背景画像
Sprite * bg = Sprite :: create( "HelloWorld.png");
bg-> setPosition(visibleSize / 2);
this-> addChild(bg、-1);
// [2]。テーマテキストを作成:gameTitle
Sprite * gameTitle = Sprite :: create( "game_title.png");
//サイズを取得します
サイズclipSize = gameTitle-> getContentSize();
// [3]。底板の輝く画像を作成します:spark
Sprite * spark = Sprite :: create( "spark.png");
spark-> setPosition(-clipSize.width、0);
// [4]。クリッピングノードを作成:clippingNode
ClippingNode * clippingNode = ClippingNode :: create();
clippingNode-> setPosition(visibleSize / 2);
this-> addChild(clippingNode);
clippingNode-> setAlphaThreshold(0.05f); //アルファゲート値を設定
clippingNode-> setContentSize(clipSize); //サイズを設定
clippingNode-> setStencil(gameTitle); //テンプレートステンシルを設定
clippingNode-> addChild(gameTitle、1); //最初にタイトルを追加すると、テンプレートと同じサイズであるため、完全に表示されます
clippingNode-> addChild(spark、2); //カットされます
// [5]。スパークを左右に移動
MoveTo * moveAction = MoveTo :: create(2.0f、Vec2(clipSize.width、0));
MoveTo * moveBackAction = MoveTo :: create(2.0f、Vec2(-clipSize.width、0));
spark-> runAction(RepeatForever :: create(Sequence :: create(moveAction、moveBackAction、NULL)));
//
2.3分析と要約
実際には、テキストをテンプレートステンシルとして使用し、テキストの「形状テンプレート」を作成して、底板をカットします。底板は文字と発光棒を組み合わせたもので、発光棒を動かすと文字が光って見えます。
(1)テンプレートステンシル:
(2)底板:
(3)クリッピングマスクの効果図: