cocos2dx入门之ClippingNode裁切节点

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值