Cocos2d-x 3.x basic learning: cropping node summary

In development, sometimes we need to display part of a picture, such as text mask, picture mask, etc.

 

 

The functional effect of ClippingNode to be discussed in this section is roughly the mask effect seen above.

ClippingNode

1. Principle

ClippingNode can be used to clip nodes. ClippingNode is a subclass of Node and can be placed in Layer, Scene, and Node like ordinary nodes.

It is mainly based on a template (Stencil) to cut the nodes of the picture to generate any shape of node display.

ClippingNode is a technology that uses template masks to trim the Node area.

How to understand ClippingNode's mask? Look at the example below.

 

 

2. Examples

Template (Stencil): You can use Layer, Node, Sprite, etc.

Backplane: You can use Layer, Node, Sprite, etc.

Layer layers

2.1, the first group (Layer layer without background image)

Template (Stencil): The template is a Node node, and put 5 Sprite balls.

Bottom plate: The bottom plate is a Node node, and the ABCD diagram of a Sprite is placed.

Layer: no elements, the background color is black.

 

 

 

 

Schematic diagram of cropping mask effect:

 

 

2.2, the second group (the Layer layer has a background image)

Template (Stencil): The template is a Node node, and put 5 Sprite balls.

Bottom plate: The bottom plate is a Node node, and the ABCD diagram of a Sprite is placed.

Layer: There is a background image of Cocos2d-x of Sprite.

 

 

 

 

 

 

Schematic diagram of cropping mask effect:

 

 

2.3 Analysis and summary

The clipping mask through ClippingNode is actually like this:

The shape collection of all elements on the template (Stencil) is regarded as the "shape template", and the elements themselves are not rendered.

Use the "shape template" to cut the bottom plate.

Shows the image area cropped from the bottom plate.

In general:

The template (Stencil) is equivalent to a template with many "holes" of different shapes.

Then according to the template, the bottom plate is cut and "dug".

Then place the cut pieces according to their original positions.

Among them: the template (Stencil) is just a "shape template", the picture itself is not drawn.

3. Main functions

ClippingNode inherits from the Node class and is used for node clipping and masking.

3.1, create a ClippingNode

Two ways: whether to use a template (stencil) to create.

//

//Create without template (stencil)

ClippingNode* clippingNode = ClippingNode::create();

//Create, use template (stencil)

ClippingNode* clippingNode = ClippingNode::create(stencil);

//

3.2, set template (Stencil)

The template node is a subclass of Node. DrawNode is often used because it can draw graphics of different shapes. Of course, you can also directly use the Node node as a template.

//

/**

* The stencil node (Node) used for cutting

* Template (stencil) object, the default is null (nullptr)

**/

Node * stencil = Node :: create (); // Model plate stencil 节 point Node

stencil->addChild(spriteBall1); //Add small ball 1

stencil->addChild(spriteBall2); //Add small ball 2

stencil->addChild(spriteBall3); //Add small ball 3

stencil->addChild(spriteBall4); //Add small ball 4

stencil->addChild(spriteBall5); //Add small ball 5

clippingNode->setStencil(stencil); //Set template Stencil

//

3.3. Set the bottom plate (Content)

//

//After creating ClippingNode, use addChild() to add the node, which is the bottom board content

clippingNode->addChild(content); //Set the bottom plate

//

3.4, inverted display (Inverted)

false: Display the content of the bottom plate clipped by the template. The default is false.

true: Display the remaining part.

//

//The default is false

//Indicates that the content of the bottom plate is displayed

clippingNode->setInverted(false);

//

3.5, alpha threshold (alphaThreshold)

alpha: Represents the transparency value of the pixel.

The content will be drawn only when the alpha value of the pixel in the stencil is greater than the alpha threshold.

Alpha Threshold (alphaThreshold): Value range [0,1].

The default is 1, which means that the alpha test is closed by default, that is, all are drawn.

If it is not 1, it means that only the content of the template whose alpha pixel is greater than alphaThreshold is drawn.

//

//Set the alpha transparency gate value

//In the display template, the content whose alpha pixel is greater than 0.05

holesClipper->setAlphaThreshold(0.05f);

//

Specific instructions:

The following is a 40*40 picture, in which the pixels of the other areas except the ball are transparent (ie: alpha is 0).

 

 

(1) Without setting the AlphaThreshold gate value or setAlphaThreshold(1.0f):

 

 

(2) In the case of setting setAlphaThreshold(0.5f):

 

 

(3) Conclusion:

It can be found that when the alpha gate value is not set, the area drawn by the template is a 40*40 rectangle.

When the alpha gate value is set to 0.5, pixels with a transparency alpha of 0 are not drawn, only a small circle is drawn.

Code combat

Here are a few interesting examples.

The official "hole punch"

"Text mask shiny special effects"

The ClippingNode class is very versatile.

1. The official "hole punching"

There is an example of using ClippingNode to complete the "hole punching" effect in the official cpp-test project. I think it is quite interesting.

For more usage, see the official cpp-test project.

Let's take a look at the effect first:

 

 

1.1, material

 

 

 

 

 

 

 

 

 

 

1.2. Add the following variables and functions in HelloWorld.h

//

ClippingNode* holesClipper; //Clip node

Node* holesStencil; //Template node

Node* holes; //bottom board node

//Touch callback

void onTouchesBegan(const std::vector& touches, Event *unused_event);

//Add small holes

void pokeHoleAtPoint(Vec2 point);

//

1.3. Create a clipping node ClippingNode in init() in HelloWorld.cpp

//

//[1]. Background image (in the Layer layer)

Sprite* bg = Sprite::create("HelloWorld.png");

bg->setPosition(visibleSize / 2);

this->addChild(bg);

//[2]. Create clipping node: holesClipper

holesClipper = ClippingNode::create();

holesClipper->setPosition(visibleSize / 2);

this->addChild(holesClipper);

//Property settings

holesClipper->setInverted(true); //Inverted display, the remaining part that has not been cropped

holesClipper->setAlphaThreshold(0.5f); //Set alpha transparency gate value

holesClipper->runAction(RepeatForever::create(RotateBy::create(1, 45))); //Rotation action

//[3]. Create template: holesStencil

holesStencil = Node::create();

holesClipper->setStencil(holesStencil); //Set template node

//Add a template mask ball

holesStencil->addChild(Sprite::create("ball.png"), -1);

//[4]. Create bottom plate: holes

holes = Node::create();

holesClipper->addChild(holes); //Set the bottom plate

//Add another board content blocks

Sprite* content = Sprite::create("blocks.png");

holesClipper->addChild(content, -1, "content");

//[5]. Touch event

auto listener = EventListenerTouchAllAtOnce::create();

listener->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this);

_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

//

1.4. Set the touch event callback. When the touch point is inside the bottom panel area, "hole"

//

void HelloWorld::onTouchesBegan(const std::vector& touches, Event *unused_event)

{

//[1]. Get the contact and convert it to the relative coordinates of the holesClipper node

Vec2 point = touches[0]->getLocation();

point = holesClipper->convertToNodeSpace(point);

//[2]. Get the rectangle Rect of the floor area

Sprite* content = (Sprite*)holesClipper->getChildByName("content");

Size contentSize = content->getContentSize();

Rect rect = Rect(-contentSize.width / 2, -contentSize.height / 2, contentSize.width, contentSize.height);

//[3]. The touch point is inside the bottom plate, and "punch holes"

if (rect.containsPoint(point))

{

pokeHoleAtPoint(point);

}

}

//

1.5. Realize the "hole punching" operation function

//

void HelloWorld::pokeHoleAtPoint(Vec2 point)

{

CCLOG("Add a Hole!!!");

//[1]. Add bottom plate content: a trace of a hole

auto hole = Sprite::create("hole_effect.png");

hole->setPosition(point);

holes->addChild(hole);

//[2]. Add template content: a small hole

auto holeStencil = Sprite::create("hole_stencil.png");

holeStencil->setPosition(point);

holesStencil->addChild(holeStencil);

//[3]. Action effect: zoom in and zoom out

holesClipper->runAction(Sequence::create(ScaleTo::create(0.05f, 1.05f), ScaleTo::create(0.05f, 1.0f), NULL));

}

//

1.6, analysis and summary

Here is set up inverted display (Inverted), that is, after using the template to cut the bottom plate, the remaining part that has not been cut is displayed.

(1) Template Stencil:

 

 

(2) Bottom plate:

 

 

(3) The effect of cropping mask: Show the remaining part that is not cropped by the template.

 

 

2. "Text mask effects"

Let's take a look at the effect first:

 

 

 

 

2.1, material

 

 

 

 

 

 

2.2, code implementation

//

//[1]. Background image

Sprite* bg = Sprite::create("HelloWorld.png");

bg->setPosition(visibleSize / 2);

this->addChild(bg, -1);

//[2]. Create theme text: gameTitle

Sprite* gameTitle = Sprite::create("game_title.png");

//Get the size

Size clipSize = gameTitle->getContentSize();

//[3]. Create a glowing picture of the bottom plate: spark

Sprite* spark = Sprite::create("spark.png");

spark->setPosition(-clipSize.width, 0);

//[4]. Create clipping node: clippingNode

ClippingNode* clippingNode = ClippingNode::create();

clippingNode->setPosition(visibleSize / 2);

this->addChild(clippingNode);

clippingNode->setAlphaThreshold(0.05f); //Set the alpha gate value

clippingNode->setContentSize(clipSize); //Set the size

clippingNode->setStencil(gameTitle); //Set template stencil

clippingNode->addChild(gameTitle, 1); //Add the title first, it will be displayed completely, because it is the same size as the template

clippingNode->addChild(spark,2); //will be cut

//[5]. Move spark left and right

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 Analysis and summary

In fact, it is to use the text as the template Stencil, make a "shape template" of the text, and then cut the bottom plate. The bottom plate is a combination of text and light-emitting sticks, and then move the light-emitting stick to show the effect of text glowing.

(1) Template Stencil:

 

 

(2) Bottom plate:

 

 

(3) Effect drawing of clipping mask:

 

 

Guess you like

Origin blog.csdn.net/qq_21743659/article/details/108637089