cocos2dx入门之ClippingNode裁切节点

来源:互联网 发布:企业网络拓扑图及配置 编辑:程序博客网 时间:2024/06/05 05:27

ps:demo代码中其实就是官网的demo,打洞洞和斩杀三国闪烁图标。

(https://github.com/CheukKin/ClippingNodeDemo.git)(demo代码)

ClippingNode裁切节点用来实现遮罩效果,可以理解为一个大节点你自定义地去选择要显示的部分,可用于实现新手指南。

对于ClippingNode的理解,首先要搞懂的是ClippingNode继承自node,一样可以放入场景啊布景层中,而其他Node(及其子类)也一样可以加到ClippingNode中。

然后这里还有两个概念,模板、底板。

底板是ClippingNode的孩子,就是真实的显示部分,当然可以放很多的孩子。

模板的作用仅仅是描边,你可以用drawnode画个形状出来,也可以直接精灵等(node及其子类),模板用于自定义裁切的形状,模板本身不会被渲染显示出来

好,上代码,这个demo应该很容易懂·····

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"#include "SimpleAudioEngine.h"#include "cocos-ext.h"using namespace cocos2d;using namespace cocos2d::extension;using namespace CocosDenshion;class HelloWorld : public cocos2d::Layer{public:    virtual bool init();      static cocos2d::Scene* scene();    void menuCloseCallback(Ref* sender);CREATE_FUNC(HelloWorld);Size visibleSize;Size winSize;Vec2 origin;ClippingNode* holesClipper; //裁剪节点Node* holesStencil;         //模板节点Node* holes;                //底板节点 //触摸回调void onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event);//添加小洞void pokeHoleAtPoint(Vec2 point);};#endif // __HELLOWORLD_SCENE_H__




#include "HelloWorldScene.h"USING_NS_CC;using namespace std;Scene* HelloWorld::scene(){Scene* scene = Scene::create();HelloWorld* layer = HelloWorld::create();    scene->addChild(layer);    return scene;}bool HelloWorld::init(){    if (!Layer::init() )    {        return false;    }        visibleSize = Director::getInstance()->getVisibleSize();winSize = Director::getInstance()->getWinSize();    origin = Director::getInstance()->getVisibleOrigin();/*holesClipper = ClippingNode::create();holesClipper->setPosition(visibleSize / 2);//  holesClipper的孩子 作为底板this->addChild(holesClipper);//  是否显示被裁剪下来的底板内容holesClipper->setInverted(true);//  表示只绘制模板中alpha像素大于0.5的内容。holesClipper->setAlphaThreshold(0.5f);holesClipper->runAction(RepeatForever::create(RotateBy::create(1, 45)));//模板holesStencil = Node::create();holesClipper->setStencil(holesStencil);holesStencil->addChild(Sprite::create("ball.png"), -1);holes = Node::create();holesClipper->addChild(holes);Sprite* content = Sprite::create("blocks.png");holesClipper->addChild(content, -1, "content");auto listener = EventListenerTouchAllAtOnce::create();listener->onTouchesBegan = CC_CALLBACK_2(HelloWorld::onTouchesBegan, this);_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);    */    //模板    Sprite* gameTitle = Sprite::create("game_title.png");        Size clipSize = gameTitle->getContentSize();        Sprite* spark = Sprite::create("spark.png");    spark->setPosition(-clipSize.width, 0);            //创建 裁切节点    ClippingNode* clippingNode = ClippingNode::create();//   像素大于0的才会渲染    clippingNode->setAlphaThreshold(0);//模板的透明部分是否描边 取值[0,1]    clippingNode->setPosition(visibleSize / 2);    this->addChild(clippingNode);    CCLOG("%f,%f",clippingNode->getPosition().x,clippingNode->getPosition().y);    CCLOG("%f,%f",spark->getPosition().x,spark->getPosition().y);            Sprite*  helloWorld = Sprite::create("HelloWorld.png");    //  gameTitle为模板 模板就是要裁切的形状,就是按照模板形状做裁切的描边,模板是不显示的,只描边    clippingNode->setStencil(gameTitle);//    clippingNode->setInverted(true);//倒置裁切//  gameTitle也作为底板 底板就是被裁切的,裁切内容才能显示出来 给clippingNode->addChild添加底板,底板用于显示    clippingNode->addChild(helloWorld, 1);    clippingNode->addChild(spark,2);            MoveTo* moveAction = MoveTo::create(2.0f, Vec2(clipSize.width, 0));    MoveTo* moveBackAction = MoveTo::create(2.0f, Vec2(-clipSize.width, 0));    Sequence* seq = Sequence::create(moveAction, moveBackAction, NULL);    RepeatForever* repeatAction = RepeatForever::create(seq);    spark->runAction(repeatAction);    return true;}void HelloWorld::onTouchesBegan(const std::vector<Touch*>& touches, Event *unused_event){Vec2 point = touches[0]->getLocation();point = holesClipper->convertToNodeSpace(point);Sprite* content =(Sprite*)this->holesClipper ->getChildByName("content");Size contentSize = content->getContentSize();Rect rect = Rect(-contentSize.width / 2, -contentSize.height / 2, contentSize.width, contentSize.height);if (rect.containsPoint(point)){pokeHoleAtPoint(point);}}void HelloWorld::pokeHoleAtPoint(Vec2 point){CCLOG("Add a Hole!!!");auto hole = Sprite::create("hole_effect.png");hole->setPosition(point);holes->addChild(hole);auto holeStencil = Sprite::create("hole_stencil.png");holeStencil->setPosition(point);holesStencil->addChild(holeStencil);holesClipper->runAction(Sequence::create(ScaleTo::create(0.05f, 1.05f), ScaleTo::create(0.05f, 1.0f), NULL));}








0 0