CCClippingNode:在游戏中实现遮罩效果、剪切效果,以涂抹糖霜为例,如何更好的实现涂抹效果
设备/引擎:Mac(11.6)/cocos2d-x
开发工具:Xcode(13.0)
开发需求:实现用户在饼干上涂抹糖霜的效果
最近工程中需要在新玩法中增加一个在饼干上涂抹糖霜的效果,方法跟前一篇的吃东西差不多,都是用到CCClippingNode来完成效果。
不同的是涂抹效果需要考虑以下问题
1.用户更换不同的糖霜:需要考虑实时更换对应的糖霜Node;
2.涂抹糖霜的层级:新的糖霜需要在旧的糖霜之上;
3.糖霜与其他topping的层级:避免出现糖霜覆盖其余topping的情况;
1.创建糖霜Node:
注:除了初始化需要创建,每次更换糖霜时也需要创建
//初始化
……
CCNode* newNOde = CCNode::create();
CCSprite* maskInLayer = CCSprite::create(糖霜资源路径);
maskInLayer->setScale(1.1);
maskInLayer->setPosition(ccp(center.x,center.y+70));
maskInLayer->setTag(kFrostMaskTextureInClipping);
CCClippingNode* clip2 = CCClippingNode::create(newNOde);
clip2->addChild(maskInLayer);
clip2->setInverted(false); //糖霜默认看不见
clip2->setAlphaThreshold(0.0f);
……
//更换糖霜:在CCTouchBegan中
CCClippingNode* frostcookieNode = this->MakeFrostClipNode(糖霜资源路径);//与初始化创建一样的方法
this->addChild(frostcookieNode,5);
frostNodeArr->addObject(frostcookieNode); //将新建的糖霜节点加到数组中
2.将创建的糖霜节点存放到一个动态数组CCArray中
注:游戏中用户随时会更换糖霜,为了保证涂抹的糖霜永远都在最上层显示,我们每更换一种糖霜都需要将新创建的糖霜节点存放到同一个动态数组中,当创建剪切区域时再从数组中取出糖霜节点即可
……
CCArray* frostNodeArr = CCArray::create();
frostNodeArr->retain();
……
frostNodeArr->addObject(clip2);
3.创建触摸显示区域并将精灵加到糖霜节点上
注:需要在涂抹过程中不停去创建剪切区域,也就是放到CCTouchMoved中
if (frostNodeArr->count()>0) {
int lastNum = frostNodeArr->count()-1;
CCClippingNode* frostNode = (CCClippingNode*)frostNodeArr->objectAtIndex(lastNum); //获取最新的糖霜节点
if (frostNode != NULL) {
CCNode* newFrostNode = frostNode->getStencil();
if (newFrostNode) {
CCPoint frostPos = frostNode->convertToNodeSpace(location);
CCSprite* mask = CCSprite::create("makeup/makeupbrush.png");
mask->setPosition(ccp(frostPos.x, frostPos.y));
mask->setScale(0.8);
newFrostNode->addChild(mask,9);
}
}
}
4.糖霜与其他非CCClippingNode类型的Topping层级问题
遇到此类情况如果不处理就很容易会出现糖霜将其他topping覆盖的情况,但是直接更改层级也没什么效果,这种情况就需要考虑将糖霜跟其他不同类型的topping放到同一个layer上,可以新创建一个layer,然后通过layer对他们的层级进行修改调整。
希望能给大家带来帮助!!!有什么问题需要讨论的可以评论私信欢迎讨论~