cocos2dx 3.0 用ClippingNode作游戏的新手引导

转自:http://blog.csdn.net/star530/article/details/20851263node

本篇介绍的是用ClippingNode 作游戏的新手引导,额,或者说是作新手引导的一种可尝试的方式。
ClippingNode的解释,我盗用Jacky的话来讲就是:
CCClipingNode是一个可裁剪节点,简单理解:
(1)首先它是一个节点,继承于CCNode,因此它能够像普通节点同样放入CCLayer,CCScene,CCNode中。
(2)做为节点,它就能够用做容器,承载其余节点和精灵。我把它叫底板。
(3)若是想要对一个节点进行裁剪,那须要给出裁剪的部分,这个裁剪区域,我把它叫模版。
因此CCClipingNode裁剪节点在组成上=底板+模版,而在显示上=底板-模版。不知道这样解释会不会好理解一点。
函数

具体的用法,请看大屏幕:this

一、假如游戏的开始,游戏界面就只有一个button,点击它能够显示出“Welcome to star blog!”,代码实现以下:spa

Size visibleSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();

auto closeItem = MenuItemImage::create(
                                       "CloseNormal.png",
                                       "CloseSelected.png",
                                       CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

closeItem->setPosition(Point(160,400));
closeItem->setTag(99);//这里设置item的tag,方便其余地方获取到这个item

auto menu = Menu::create(closeItem, NULL);
menu->setPosition(Point::ZERO);
menu->setTag(99);//这里一样设置tag 为99
this->addChild(menu, 2);
//它的回调函数是点击这个button后,会出现一行字:Welcome to star blog!。
void HelloWorld::menuCloseCallback(Object* pSender)
{
    auto _lable = LabelTTF::create("Welcome to star blog!","Arial",25);
    _lable->setPosition(Point(160,300));
    this->addChild(_lable,2);
}

效果如图所示:.net

 

二、而后添加ClippingNode:3d

auto clip = ClippingNode::create();//设置裁剪节点
clip->setInverted(true);//设置底板可见
clip->setAlphaThreshold(0.0f);//设置透明度Alpha值为0
this->addChild(clip,10);

auto layerColor = LayerColor::create(Color4B(0,0,0,150));
clip->addChild(layerColor,1);//在裁剪节点添加一个灰色的透明层

//建立模板,也就是你要在裁剪节点上挖出来的那个”洞“是什么形状的,这里我用close的图标来做为模板
auto nodef = Node::create();//建立模版  
auto close = Sprite::create("CloseSelected.png");//这里使用的是close的那个图标 
nodef->addChild(close);//在模版上添加精灵  
nodef->setPosition(Point(160,400));//设置的坐标正好是在close button的坐标位置上
clip->setStencil(nodef);//设置模版  

clippingNode的用法注释已经写得很清楚啦,我就再也不一一解释。使用clippingNode后,效果如图所示,我特地添加了一个用close图标作的精灵,方便对比。code

三、这个时候,场景中的close按钮是高亮的,点击close按钮也是能够响应的,可是假设我界面上有许多按钮,它们也都是能够响应,若是我只想让玩家点击close按钮,其余按钮不能用,那该怎么作?(总有那么些”调皮“的玩家不按常理出牌)。方法很简单,就是添加一个覆盖整个屏幕的空白按钮。orm

auto blackItem = MenuItem::create();
blackItem->setPosition(visibleSize.width/2,visibleSize.height/2);
blackItem->setContentSize(visibleSize);//设置大小为整个屏幕的大小

auto blackMenu = Menu::create(blackItem,NULL);
blackMenu->setPosition(Point::ZERO);
blackMenu->setAnchorPoint(Point::ZERO);
this->addChild(blackMenu,100);

这样点击按钮就没法响应了,由于在按钮上还覆盖着一个霸道的空白按钮。但是...如今连close 按钮都点击不了。怎么就这么麻烦?还能不能一块儿快乐的玩耍了?!看来只能出大招了,把触摸监听事件扯出来。我在场景的最上方添加一个layer(注意是最上方,若是是在空白按钮的下面,那么就触摸不到layer了),当玩家手指触摸到屏幕,我经过判断触摸的位置判断是否在close 按钮上,若是是的话,手动的响应close  按钮。blog

auto listen_layer = Layer::create();//首先在场景的最上方再添加一个layer
this->addChild(listen_layer,200);//zOrder设置为200,反正能在最上方就好

auto listener = EventListenerTouchOneByOne::create();//建立一个触摸监听(单点触摸)
listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this);//指定触摸的回调函数
_eventDispatcher->addEventListenerWithSceneGraphPriority(listener,listen_layer);//将listener和layer绑定,放入事件委托中

bool HelloWorld::onTouchBegan(Touch* touch, Event  *event)
{
    auto point = Director::getInstance()->convertToGL(touch->getLocationInView());//得到当前触摸的坐标
    auto rect = Rect(160-30,400-30,60,60);//设置框坐标和大小处于close 按钮的位置上

    if(rect.containsPoint(point))//若是触点处于rect中
    {
        auto menu = (Menu*)this->getChildByTag(99);//经过tag获取到menu
        auto item = (MenuItem*)menu->getChildByTag(99);//经过tag从menu中获取item
        item->activate();//让item响应
    }

    return true;//返回true表示接收触摸事件
}
相关文章
相关标签/搜索