首页 > 代码库 > 节点裁剪 ClippingNode
节点裁剪 ClippingNode
有时候我们需要一张圆形的图片,可是美术提供的是一个矩形的资源图片,怎么办?让美术再做一张圆形的?即使这样能暂时解决问题,无疑增加了开销,何况有时候你可能需要显示一张图片里的不同部分,不可能每种情况都让美术都做一次修改吧,这时候 cocos2d-x 里提供的节点裁剪技术就派上用场了。
节点裁剪 原理
cocos2d-x 提供 CCClippingNode 类的可以用来对节点进行裁剪,可以根据一个模板切割节点图片,生成任何形状(取决于模板)的节点显示。
CCClippingNode 是 CCNode 的子类,可以放入到其他 CCNode、CCLayer、CCScene中。
节点裁剪是利用模板遮罩来完成对Node区域裁剪的技术,看下图:
图中的模板和底板一起构成了CCClipperNode,但是在底板上,只有模板在底板上的投影部分是可见的(或者取反,除投影以外的地方可见),底板上投影之外的地方都是不可见的(或者说是透明的),这样将CCClipperNode放到Layer中后,你看到的就是Layer中间位置有底板的部分图像,没错这部分图像就是对底板进行节点裁剪的结果。
通过下面一个例子来加深理解,图1是模板图片,图2是底板图片,这里Layer是黑色(没有任何内容),使用模板对底板进行裁剪后的结果(也就是CCClipperNode)放到Layer中,看到的效果如图3。
图 1 模板
图 2 底板
图 3 从上往下看
使用节点裁剪(CCClipperNode类)
CCClipperNode 的使用一般步骤:
- 创建模板和底板
- 创建裁剪节点(设置属性)
- 裁剪节点设置模板并添加底板
- 将裁减节点添加到其他节点中使用
下面代码实现了上面图3的裁剪效果:
bool Scene0::init()
{
if (!CCScene::init())
return false;
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
CCSprite *stencil = CCSprite::create("stencil.png");
CCSprite *content = CCSprite::create("content.png");
CCClippingNode *clipper = CCClippingNode::create();
// 设置模板
clipper->setStencil(stencil);
// 默认为false. 该值为false时,以模板中不透明区域作为模板;该值为true时,以模板中透明区域作为模板
clipper->setInverted(false);
// 默认为0.0,表示模板透明区域的alpha阈值,其值越小模板中透明区域越小,不透明区域就越大
clipper->setAlphaThreshold(0.4f);
clipper->addChild(content);
addChild(clipper);
// 设置模板位置(改变该值,会改变裁剪出来的内容)
stencil->setPosition(ccp(0, 0));
// 设置底板位置(改变该值,会改变裁剪出来的内容)
content->setPosition(ccp(0, 0));
// 设置裁剪后的节点位置(改变该位置,裁剪出来的内容不会变化)
clipper->setAnchorPoint(ccp(0.5f, 0.5f));
clipper->setPosition(ccp(visibleSize.width/4 + origin.x, visibleSize.height/2 + origin.y));
return true;
}
改变上面代码的部分参数,看看是什么效果:
- 反转模板,即以模板中透明部分作为模板
clipper->setInverted(true);
- 将模板向右偏移 50, 底板和Layer保持不变
stencil->setPosition(ccp(50, 0));
- 将底板向右偏移 100, 模板和Layer保持不变(接着上一步)
content->setPosition(ccp(100, 0));
- 将裁剪节点向右偏移 200,模板、底板和Layer保持不变(接着上一步)
clipper->setPosition(ccp(visibleSize.width/4 + origin.x + 200, visibleSize.height/2 + origin.y));
移动裁剪节点不会改变裁剪的内容,而是底板和模板整体的移动。
上面代码基于 cocos2d-x 2.x, 对于 3.x 原理和代码一样,只需要将类的CC
前缀去掉就OK了。
参考:
cocos2d-x 官方文档 —— ClippingNode的使用
节点裁剪 ClippingNode