1.LayerColor做遮罩,ClippingNode做亮点区域裁剪

2.剪裁了一个区域,但是只想传递点击这个区域的触摸事件到下层
	//只有触摸在圆形区域才可以向下传递触摸时间
    auto touchListener = EventListenerTouchOneByOne::create();
    touchListener->onTouchBegan = CC_CALLBACK_2(CircleShelterLayer::onTouchBegan,this);
    touchListener->onTouchBegan = [=](Touch *touch,Event *event){
        Point point = touch->getLocation();
        float distance = point.getdistance(pos);
        if (distance > radius)
        {
            touchListener->setSwallowtouches(true);
            return true;
        }
        else
        {
            touchListener->setSwallowtouches(false);
        }
        return true;
    }; 

3.
	clippingNode:
		http://www.zaojiahua.com/ccclipping.html
	CcclippingNode做个新手引导:
		http://www.zaojiahua.com/beginner-guide.html

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


1.ClippingNode

CCClippingNode在做新手引导的时候经常用到,所以要想做个新手引导就得先学学这个,当然它的功能不会仅限于此,明白了原理以后你可以自由发挥啊。在网上看到不少的文章,但是说的不够明白,我今天好好给大家说说吧,这里只说下原理,下次利用这个做个新手引导出来。

需要明确的一点就是CcclippingNode本质上是一个节点,什么是节点,节点就是可以存放东西,它也可以放到其他的节点上。大家在新手引导中看到的画面,大多数是一些背景层什么的,这个CcclippingNode也是放到了场景中的,只不过zOrder是靠前的。我么需要完成的这些个效果都是在这个层中实现的,不要被搞乱了。首先我们在这个node层中添加一些我们的元素,当然根据你自己的情况了,基本上都是一些精灵,那个看起来透明的遮罩层就是添加到这个node中的节点。接着,最重要的一点是这个node有一个模板节点,什么是模板节点呢,就是一个模子,我们要按照这个模子来裁剪我们的这个层,道理就像我们用剪刀按照一个模子来减一块布一样,我们最后可以设置我们是要留下这个模子裁剪出来的区域还是要留下这个模子剩下来的区域,CcclippingNode有专门的函数来设置这个模子。下面看看代码中怎么实现吧,具体的函数调用也加了注释,很好懂的。

bool HelloWorld::init()
{
    if ( !cclayer::init() )
    {
        return false;
    }

    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

	//背景图片
	CCSprite * background = CCSprite::create("HelloWorld.png");
	background->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	this->addChild(background,0);

	//创建一个裁剪节点用来实现遮罩的效果
	CcclippingNode * clippingNode = CcclippingNode::create();
	this->addChild(clippingNode,1);
	//向裁剪节点中加入内容,这里加入的是一个透明的层
	cclayerColor * layer = cclayerColor::create(ccc4(0,200));
	clippingNode->addChild(layer);
	//继续向裁剪节点中加入内容,这里加入的是一个精灵
	CCSprite * sprite = CCSprite::create("1.png");
	sprite->setPosition(ccp(visibleSize.width/4,visibleSize.height/2));
	clippingNode->addChild(sprite);
	//向裁剪节点中加入精灵,精灵的位置和裁剪的位置相同,所以最后让裁剪掉了
	CCSprite * sprite2 = CCSprite::create("icon.png");
	sprite2->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	clippingNode->addChild(sprite2);

	//创建模板,裁剪节点将按照这个模板来裁剪区域
	CCSprite * stencil = CCSprite::create("icon.png");
	stencil->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	clippingNode-><strong>setStencil</strong>(stencil);
	//这个是用来设置显示裁剪区域还是非裁剪区域的
	clippingNode-><strong>setInverted</strong>(true);
	//我们之前放了一张裁剪的模板,按照这个模板裁剪的时候同时按照这个alpha的值裁剪,这个值的范围是0-1
	//设为0就把透明的区域裁剪掉了
	//clippingNode-><strong>setAlphaThreshold</strong>(0);

    return true;
}

你看到的上边的俩种图片就是通过setInverted这个函数来设置的,它可以设置你最终看到的是裁剪掉的区域还是模板的区域,我想原理你应该明白了吧。下面我们再来看一下init函数中最后注释掉的那行代码,意思注释已经写了,打开这句话我们看到的效果如下。

有了上面的基础我们应该想想怎么去做这个新手引导了,个人认为这个CcclippingNode节点上只应该添加一个cclayreColor,设置一下它的透明度,看起来就有了遮罩的效果了,而其他的元素都是在其他的层中的,然后我们为CcclippingNode设置一个模板,同时设置setAlphaThreshold这句话,将透明度为0的都裁剪掉,这样就留下了精灵的形状,然后做一下触摸操作的处理,应该是这样吧。下面这幅图就是这样做的。是不是有了新手引导的效果了!

http://www.zaojiahua.com/ccclipping.html

===================================================================================================================================

今天花了一下午的时间做了个新手引导,用到的知识就是上篇的博客CCClippingNode遮罩解析,还不明白CCClippingNode是怎么回事的就读一下上篇文章吧。先说一下整体的思路吧,游戏正常的界面代码都不改动,逻辑还是原来的逻辑,我们只是在正常的场景上加上一个层,这个层来负责完成新手引导的功能,使用完这个层的时候就将其从场景中清除掉。需要解决的一个重要的问题就是触摸,我们要让我们后添加的这个层注册触摸事件,当点击非模板区域的时候,将触摸事件吞噬掉,这样的话下层就接受不到了,给用户点击错误的感官,当点击了模板区域的时候我们记录一下当前引导的步数,然后向下层传递,下层按他们自己的逻辑处理触摸。最后完成了所有的引导步数后,将注册的触摸事件清除,将引导层清除。下面先看看我们要为哪个场景添加引导层,没添加之前的效果,具体代码实现如下。

bool HelloWorld::init()
{
    if ( !cclayer::init() )
    {
        return false;
    }

    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();

	//添加背景图片
	CCSprite * background = CCSprite::create("background.png");
	background->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	this->addChild(background);

	//添加如下的俩个按钮
	CCControlButton * first = this->addButton("first",ccp(visibleSize.width/4,visibleSize.height/3));
	//为按钮添加响应事件
	first->addTargetWithActionForControlEvents(this,cccontrol_selector(HelloWorld::first),CCControlEventTouchDown);

	CCControlButton * second = this->addButton("second",ccp(visibleSize.width*3/4,visibleSize.height/3));
	second->addTargetWithActionForControlEvents(this,cccontrol_selector(HelloWorld::second),CCControlEventTouchDown);

	//添加一个精灵,点击精灵的时候跟随手指移动
	this->m_sprite = CCSprite::create("sprite.png");
	m_sprite->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
	this->addChild(m_sprite);

	//添加新手引导层,到时候这里可以做一个判断,如果玩家首次完游戏就添加进这个新手引导,否则不添加
	BeginnerGuide * gudie = BeginnerGuide::create();
	this->addChild(gudie);

	//开启触摸
	this->setTouchEnabled(true);
    return true;
}
//向helloworld层中添加按钮
CCControlButton * HelloWorld::addButton(std::string str,CCPoint point)
{
	//创建俩张九妹图片做为底图
	CCScale9Sprite * normalButton = CCScale9Sprite::create("buttonBackground.png");
	CCScale9Sprite * selectedButton = CCScale9Sprite::create("buttonHighlighted.png");

	cclabelTTF * label = cclabelTTF::create(str.c_str(),"",30);
	CCControlButton * button = CCControlButton::create(label,normalButton);
	//设置按钮被选中时候的九图
	button->setBackgroundSpriteForState(selectedButton,CCControlStateSelected);
	button->setPosition(point);
	this->addChild(button);

	return button;
}
//单击按钮时候的事件响应函数
void HelloWorld::first(CCObject * object,CCControlEvent evt)
{
	cclabelTTF * text = cclabelTTF::create("first button clicked!",24);
	text->setPosition(ccp(400,400));
	text->setColor(ccc3(0,255,255));
	this->addChild(text);
}
//同上
void HelloWorld::second(CCObject * object,CCControlEvent evt)
{
	cclabelTTF * text = cclabelTTF::create("second button clicked!",200));
	text->setColor(ccc3(0,255));
	this->addChild(text);
}
//注册触摸
void HelloWorld::registerWithTouchdispatcher()
{
	CCDirector::sharedDirector()->getTouchdispatcher()->addTargetedDelegate(this,true);
}

//以下俩个函数实现拖动精灵移动的效果
bool HelloWorld::<strong>ccTouchBegan</strong>(CCTouch * touch,CCEvent * evt)
{
	//获得手指点击的点的坐标
	CCPoint point = touch->getLocation();
	//获得精灵所在的区域,CCRect包括x,y,width,height
	CCRect rect = this->m_sprite->boundingBox();

	//判断手指点击的点是否点在了精灵上
	if(rect.<strong>containsPoint</strong>(point))
	{
		//返回true则会接受其他的协议消息
		return true;
	}

	return false;
}

void HelloWorld::ccTouchMoved(CCTouch * touch,CCEvent * evt)
{
	//分别获得了手指现在的点击点和手指上次的点击点位置
	CCPoint point = touch->getLocation();
	CCPoint pointPre = touch->getPrevIoUsLocation();
	//ccpsub将俩个点相减,获得一个移动方向的向量
	CCPoint direction = ccpsub(point,pointPre);

	CCPoint spritePoint = m_sprite->getPosition();
	//ccpAdd将精灵现在的位置点和移动方向的向量相加,获得精灵将要移动到的位置点
	CCPoint spriteDirection = ccpAdd(spritePoint,direction);
	m_sprite->setPosition(spriteDirection);
}

#ifndef __BEGINNER_GUIDE_SCENE_H__
#define __BEGINNER_GUIDE_SCENE_H__

#include "cocos2d.h"

using namespace cocos2d;

//创建枚举类型,记录用户单击到多少步
enum STEP
{
	STEP_FirsT,STEP_SECOND,STEP_THIRD,STEP_FORTH //最后一步,有特殊作用
};

class BeginnerGuide : public cocos2d::cclayer
{
public:
    virtual bool init();
    static cocos2d::CCScene* scene();
    CREATE_FUNC(BeginnerGuide);
	//添加触摸事件
	void registerWithTouchdispatcher();
	bool ccTouchBegan(CCTouch * touch,CCEvent * evt);
	//设置当前新手引导的步数,根据不同的步数使用不同的模板和坐标
	void setStep(enum STEP);
	//当新手引导退出的时候在onExit()中处理一些事情
	void onExit();
private:
	CCSprite * m_sprite;
	//裁剪节点
	CcclippingNode * clippingNode;
	CCSize visibleSize;
	//记录当前的步数
	enum STEP m_step;
	//创建一个手型精灵用来指导用户点击
	CCSprite * m_hand;
};

#endif

bool BeginnerGuide::init()
{
    if ( !cclayer::init() )
    {
        return false;
    }

    visibleSize = CCDirector::sharedDirector()->getVisibleSize();

	//创建一个遮罩层
	cclayerColor * layer = cclayerColor::create(ccc4(0,150));

	//创建一个裁剪节点
	clippingNode = CcclippingNode::create();
	this->addChild(clippingNode);
	//设置一些属性
	clippingNode->addChild(layer);
	clippingNode->setInverted(true);
	clippingNode->setAlphaThreshold(0);

	//创建一个手型精灵用来指导用户点击
	this->m_hand = CCSprite::create("hand.png");
	this->addChild(m_hand);

	//设置当前新手引导为第一步
	this->m_step = STEP_FirsT;
	this->setStep(m_step);

	//开启触摸
	this->setTouchEnabled(true);
    return true;
}

void BeginnerGuide::registerWithTouchdispatcher()
{
	//Ccmenu的优先级是-128,而CCControlButton的优先级是0,这里的优先级至少要和helloWorld场景层中的
	//优先级一样大,也可以设置为0,因为新手引导层是最后添加上去的,所以最先收到触摸的消息
	CCDirector::sharedDirector()->getTouchdispatcher()->addTargetedDelegate(this,true);
}

bool BeginnerGuide::ccTouchBegan(CCTouch * touch,CCEvent * evt)
{
	//获取当前的模板
	<strong>CCNode * stencil = clippingNode->getStencil();
	CCRect rect = stencil->boundingBox();
	CCPoint point = touch->getLocation();</strong>
	//判断手指点击的位置是否为模板的位置
	if(rect.containsPoint(point))
	{
		if(m_step == STEP_FORTH)
		{
			//this->m_sprite->setVisible(false);
			this->removeFromParent();
			return false;
		}
		//改变步骤
		this->setStep((enum STEP)((int)m_step+1));
		return false;
	}

	return true;
}

//设置当前新手引导的步骤,根据不同的步骤使用不同的模板和坐标
void BeginnerGuide::setStep(enum STEP step)
{
	CCNode * stencil = NULL;
	//创建手型精灵的动作,一下动作写的相对的恶心,就是为了实现效果,大家就别看了
	CCScaleto * scale1 = CCScaleto::create(0.8f,0.8f);
	CCScaleto * scale2 = CCScaleto::create(0.8f,0.7f);
	CCSequence * sequence = CCSequence::create(scale1,scale2,NULL);
	CCRepeatForever * repeat = CCRepeatForever::create(sequence);

	CCMoveto * move1 = CCMoveto::create(3.0f,ccp(visibleSize.width*4/5,visibleSize.height/4));
	CCRepeat * repeat1 = CCRepeat::create(sequence,50);
	CCSequence * second = CCSequence::create(move1,repeat1,NULL);

	CCMoveto * move2 = CCMoveto::create(2.0f,ccp(visibleSize.width*0.55,visibleSize.height/3));
	CCRepeat * repeat2 = CCRepeat::create(sequence,2);
	CCMoveto * move2_2 = CCMoveto::create(2.0f,ccp(visibleSize.width/3,visibleSize.height/3));
	CCSequence * third = CCSequence::create(move2,repeat2,move2_2,NULL);

	m_hand->stopAllActions();

	switch(step)
	{
	case STEP_FirsT:
		//设置模板和模板的位置
		stencil = CCSprite::create("1.png");
		stencil->setPosition(ccp(visibleSize.width/4,visibleSize.height/3));
		//手型精灵执行动作
		this->m_hand->runAction(repeat);
		m_hand->setPosition(ccp(visibleSize.width/3,visibleSize.height/4));
		break;
	case STEP_SECOND:
		//与上边的相同
		stencil = CCSprite::create("2.png");
		stencil->setPosition(ccp(visibleSize.width*3/4,visibleSize.height/3));
		this->m_step = STEP_SECOND;
		//手型精灵执行动作
		this->m_hand->runAction(second);
		break;
	case STEP_THIRD:
		this->m_sprite = CCSprite::create("sprite.png");
		stencil = m_sprite;
		stencil->setPosition(ccp(visibleSize.width/2,visibleSize.height/2));
		this->m_step = STEP_THIRD;
		//手型精灵执行动作
		this->m_hand->runAction(third);
		break;
	case STEP_FORTH:
		this->m_sprite = CCSprite::create("sprite.png");
		this->m_sprite->setPosition(ccp(visibleSize.width/3,visibleSize.height/2));
		stencil = m_sprite;
		this->m_step = STEP_FORTH;
		break;
	}

	//添加模板
	clippingNode->setStencil(stencil);
}

//将当前新手引导层从父节点上移除的时候记住要remove掉触摸
void BeginnerGuide::onExit()
{
	cclayer::onExit();
	CCDirector::sharedDirector()->getTouchdispatcher()->removeDelegate(this);
}

效果如图所示,当然程序还是有bug的,比如用户快速点击的时候动作能否跟的上,最主要的问题是当用户点击了最后一步的时候如何进行判断用户是否点击完成,在我的程序中,我需要用户再次点击一下才能退出新手引导。还有就是如果用户没有按照要求点击的话,CcclippingNode的模板应该回到上一步的位置处才对,这里没有实现,不过项目中用的时候就需要根据你自己的需要去做了,这里只是为了说明原理。

http://www.zaojiahua.com/beginner-guide.html

cocos2d clippindNode,新手引导的更多相关文章

  1. 详解iOS游戏开发中Cocos2D的坐标位置关系

    这篇文章主要介绍了iOS游戏开发中Cocos2D的坐标位置关系,Cocos2D是专门用来开发iOS游戏的开源框架,文中示例代码采用Objective-C语言,需要的朋友可以参考下

  2. 剖析iOS开发中Cocos2d-x的内存管理相关操作

    这篇文章主要介绍了剖析iOS开发中Cocos2d-x的内存管理相关操作,Cocos2d-x是开发游戏的利器,需要的朋友可以参考下

  3. iOS开发中使用cocos2d添加触摸事件的方法

    这篇文章主要介绍了iOS开发中使用cocos2d添加触摸事件的方法,cocos2d是制作iOS游戏的利器,需要的朋友可以参考下

  4. ios – cocos2d 2.0-rc2:结束导演并重启

    我有一个使用UIKitmenues的cocos2d驱动游戏,所以我只使用一个viewcontroller的框架,这是游戏本身.此外,它只有一个场景.由于cocos2d2.0导演本身是一个UIViewController子类,所以我只需在用户点击一个开始按钮时将其推送到我的MenuViewController中:当用户启动第一个游戏时,第一次调用该方法时,这很好.当游戏结束时,我调用[[CCDire

  5. cocos2dx之飞机大战简单版1

    先说下版本vs2010+cocos2dx2.2本章主要是告诉大家如何实现创建背景、飞机、***精灵,并且然后他们动起来,然后做一个碰撞测试,当***和敌方飞机碰撞时就销毁精灵并且加一个爆炸的精灵。所以我们只需要在GameLogic中调用addMonster,在GameLogicaddBullet1中调用addBullet1就可以了注意一定要在参数中加上floatdt,它是表明多少秒调用一次这个函数。

  6. cocos2d: fullPathForFilename: No file found at /cc_2x2_white_image. Possible missing file.

    程序运行的时候输出这条信息cocos2d:fullPathForFilename:Nofilefoundat/cc_2x2_white_image.Possiblemissingfile.并没有影响程序正常运行产生的原因可能是某个精灵未配置纹理导致的,不需要关心。参考cc_2x2_white_imageismissing,givingwarningatruntime:http://www.coco

  7. Cocos2dx学习笔记3---LittleRunner

    4.创建场景类5启动6.不要在写代码的时候,把所有的功能都往一个类里面写,多分开几个类来写,多写一些注释,以便后面要修改或者查阅看不懂。

  8. 寒風的Cocos2dx之旅之添加按钮

    要在Cocos2d中使用Button,首先引入头文件#include"ui/CocosGUI.h"usingnamespaceuil;引入完毕后,就创建button。功能要比MenuItem要强大的多。他可以使按钮放大等功能。

  9. cocos2d实现CCLabelTTF真正字体描边效果

    在开发游戏中,我们需要在需要在游戏中显示一个字体轮廓比较清晰的效果,我们就需要给字体的周围进行描边,让字体显示比较更加突出,我重写了cclabelttf类,使它具有描边的特效,和描边的大小以及颜色。。。

  10. cocos2d刚体会被穿透

    在调试Coco2d-javaEditor的BoxShape刚体碰撞时,发现有时候没有碰撞效果,直接穿透过去了。后来发现,刚体碰撞必须在没有外在干扰下才正常,而我每次碰撞的时候,都执行了Action动作,这个action动作会优先于碰撞,所以,会先执行action,这个action导致碰撞无效。为了防止穿透,最好不要用action。

随机推荐

  1. 【cocos2d-x 3.x 学习笔记】对象内存管理

    Cocos2d-x的内存管理cocos2d-x中使用的是上面的引用计数来管理内存,但是又增加了一些自己的特色。cocos2d-x中通过Ref类来实现引用计数,所有需要实现内存自动回收的类都应该继承自Ref类。下面是Ref类的定义:在cocos2d-x中创建对象通常有两种方式:这两中方式的差异可以参见我另一篇博文“对象创建方式讨论”。在cocos2d-x中提倡使用第二种方式,为了避免误用第一种方式,一般将构造函数设为protected或private。参考资料:[1]cocos2d-x高级开发教程2.3节[

  2. 利用cocos2dx 3.2开发消灭星星六如何在cocos2dx中显示中文

    由于编码的不同,在cocos2dx中的Label控件中如果放入中文字,往往会出现乱码。为了方便使用,我把这个从文档中获取中文字的方法放在一个头文件里面Chinese.h这里的tex_vec是cocos2dx提供的一个保存文档内容的一个容器。这里给出ChineseWords,xml的格式再看看ChineseWord的实现Chinese.cpp就这样,以后在需要用到中文字的地方,就先include这个头文件然后调用ChineseWord函数,获取一串中文字符串。

  3. 利用cocos2dx 3.2开发消灭星星七关于星星的算法

    在前面,我们已经在GameLayer中利用随机数初始化了一个StarMatrix,如果还不知道怎么创建星星矩阵请回去看看而且我们也讲了整个游戏的触摸事件的派发了。

  4. cocos2dx3.x 新手打包APK注意事项!

    这个在编译的时候就可以发现了比较好弄这只是我遇到的,其他的以后遇到再补充吧。。。以前被这两个问题坑了好久

  5. 利用cocos2dx 3.2开发消灭星星八游戏的结束判断与数据控制

    如果你看完之前的,那么你基本已经拥有一个消灭星星游戏的雏形。开始把剩下的两两互不相连的星星消去。那么如何判断是GameOver还是进入下一关呢。。其实游戏数据贯穿整个游戏,包括星星消除的时候要加到获得分数上,消去剩下两两不相连的星星的时候的加分政策等,因此如果前面没有做这一块的,最好回去搞一搞。

  6. 利用cocos2dx 3.2开发消灭星星九为游戏添加一些特效

    needClear是一个flag,当游戏判断不能再继续后,这个flag变为true,开始消除剩下的星星clearSumTime是一个累加器ONE_CLEAR_TIME就是每颗星星消除的时间2.连击加分信息一般消除一次星星都会有连击信息和加多少分的信息。其实这些combo标签就是一张图片,也是通过控制其属性或者runAction来实现。源码ComboEffect.hComboEffect.cpp4.消除星星粒子效果消除星星时,为了实现星星爆裂散落的效果,使用了cocos2d提供的粒子特效引擎对于粒子特效不了

  7. 02 Cocos2D-x引擎win7环境搭建及创建项目

    官网有搭建的文章,直接转载记录。环境搭建:本文介绍如何搭建Cocos2d-x3.2版本的开发环境。项目创建:一、通过命令创建项目前面搭建好环境后,怎样创建自己的Cocos2d-x项目呢?先来看看Cocos2d-x3.2的目录吧这就是Cocos2d-x3.2的目录。输入cocosnew项目名–p包名–lcpp–d路径回车就创建成功了例如:成功后,找到这个项目打开proj.win32目录下的Hello.slnF5成功了。

  8. 利用cocos2dx 3.2开发消灭星星十为游戏添加音效项目源码分享

    一个游戏,声音也是非常的重要,其实cocos2dx里面的简单音效引擎的使用是非常简单的。我这里只不过是用一个类对所有的音效进行管理罢了。Audio.hAudio.cpp好了,本系列教程到此结束,第一次写教程如有不对请见谅或指教,谢谢大家。最后附上整个项目的源代码点击打开链接

  9. 03 Helloworld

    程序都有一个入口点,在C++就是main函数了,打开main.cpp,代码如下:123456789101112131415161718#include"main.h"#include"AppDelegate.h"#include"cocos2d.h"USING_NS_CC;intAPIENTRY_tWinMain{UNREFERENCED_ParaMETER;UNREFERENCED_ParaMETER;//createtheapplicationinstanceAppDelegateapp;return

  10. MenuItemImage*图标菜单创建注意事项

    学习cocos2dx,看的是cocos2d-x3.x手游开发实例详解,这本书错误一大把,本着探索求知勇于发现错误改正错误的精神,我跟着书上的例子一起调试,当学习到场景切换这个小节的时候,出了个错误,卡了我好几个小时。

返回
顶部