转载请注明,原文地址: http://www.benmutou.com/archives/692
文章来源:笨木头与游戏开发
[笨木头Cocos2dx043]小玩半透明遮罩第01篇:添加半透明遮罩,屏蔽下层点击事件

 

呼呼,我现在是各种兴奋紧张恨,好久没有写教程了,不知道功力下降没(小若:不会的,不会下降的~已经最低了)。

今天我个人网游处女作内测了,欢迎关注:http://bbs.benmutou.com/forum.php?mod=viewthread&tid=1535

也正因为游戏内测,今天不会开发,所以心情比较舒畅,于是就来写教程了~

 

次我们来玩玩半透明遮罩吧,就是那种比如游戏中点了一个按钮,要等待服务器响应,然后就黑屏等待。O_O!不是黑屏,就是半透明的黑屏,盖在游戏最上层。

 

1. 新建项目

好,先新建一个HelloWorldScene项目,自动生成的HelloWorldScene场景不要删除,然后运行成功,这个过程太复杂了,我就不解释了,效果:



 

2. 添加透明层

先来实现第一步吧,随便加个透明层,随便取个名字,就叫做ShadeLayer吧,我查了字典的~

头文件:

[cce_cpp]

#ifndef ShadeLayer_H

#define ShadeLayer_H

#include "cocos2d.h"

USING_NS_CC;

class ShadeLayer : public CCLayer {

public:

static ShadeLayer* create(CCLayer* uiLayer);

bool init(CCLayer* uiLayer);

};

#endif

[/cce_cpp]

为什么要加个CCLayer参数?因为以后要用到,现在暂时忽略,就是一个普通的Layer类。

好,重点是init函数,如下:

[cce_cpp]

bool ShadeLayer::init(CCLayer* uiLayer) {

bool bRet = false;

do {

CC_BREAK_IF(!CCLayer::init());

CCAssert(uiLayer, "uiLayer == NULL!");

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

/* 半透明层 */

CCLayerColor* layerColor = CCLayerColor::create();

layerColor->setColor(ccc3(0, 0, 0));

layerColor->setOpacity(150);

layerColor->setContentSize(CCSizeMake(visibleSize.width, visibleSize.height));

this->addChild(layerColor);

bRet = true;

} while (0);

return bRet;

}

[/cce_cpp]

简单地添加了一个CCLayerColor作为半透明层,目前为止没有东西需要解释。

最后,在HelloWorldSceneinit函数的最后加上一句代码:

[cce_cpp]

bool HelloWorld::init()

{

bool bRet = false;

do {

/* 省略了一堆代码 */

/* 添加半透明层 */

this->addChild(ShadeLayer::create(this), 100);

bRet = true;

} while (0);

return bRet;

}

[/cce_cpp]

运行效果:



噗,完美,有半透明的效果了。

就这样,本教程结束...啊才怪啊!(小若:换个吐槽的招数好不好,听腻了)

 

3. 让下层的所有东西都不能点击

现在点击右下角的关闭按钮还是会响应,这不是我们想要的,在半透明遮罩出现的时候,下层的所有内容都不应该响应点击。

这很简单,修改一下ShadeLayerinit函数:

[cce_cpp]

bool ShadeLayer::init(CCLayer* uiLayer) {

bool bRet = false;

do {

CC_BREAK_IF(!CCLayer::init());

CCAssert(uiLayer, "uiLayer == NULL!");

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

/* 半透明层 */

CCLayerColor* layerColor = CCLayerColor::create();

layerColor->setColor(ccc3(0, 0, 0));

layerColor->setOpacity(150);

layerColor->setContentSize(CCSizeMake(visibleSize.width, visibleSize.height));

this->addChild(layerColor);

/* 全屏菜单,屏蔽下层点击事件 */

CCMenuItemImage* item = CCMenuItemImage::create();

item->setContentSize(CCSizeMake(visibleSize.width, visibleSize.height));

item->initWithTarget(this, menu_selector(ShadeLayer::itemCallback));

CCMenu* menu = CCMenu::create(item, NULL);

menu->setTouchPriority(-1280);

this->addChild(menu);

bRet = true;

} while (0);

return bRet;

} [/cce_cpp]


这是一个投机的做法,在遮罩层里添加一个菜单,大小全屏,并且将触摸优先级设为-1280,尽量设小一点,这样,其他层的按钮就无法获得点击事件了。因为所有的点击事件都会被这个全屏菜单截取。

OK,运行试试,有下角的关闭按钮不能点击了。

好,这些都是最简单的情况,本篇到此结束。

 

下一篇将介绍,在半透明遮罩上面要放UI怎么办?比如对话框弹出的时候,下层需要出现半透明遮罩,而对话框不能被遮罩挡住,并且对话框的按钮必须可以点击。

虽然不知道我啥时候会有空去写...

 

18 条评论
  • 常子绪-CaCa 2014-12-15 21:44:35

    不知道对我将要解决的事情有木有用收藏一下先
    0回复
  • yxlovemoney 2014-06-11 17:31:12

    我是来问,下篇有出来么?
    0回复
    • 博主 糟糕_树叶的mut 2014-06-11 18:26:06

      没有,3.0都出来了,改了触摸机制,这种处理就免了~
      0回复
      • yxlovemoney 2014-06-12 15:27:48

        什么,触摸机制改了, 感觉跟着COCOS走好累,一个版本出来差天共地(-__-)b
        0回复
        • 博主 糟糕_树叶的mut 2014-06-12 17:22:02

          确实...希望4.0不要再出现类似的情况...
          0回复
  • Oo幻想oO 2013-12-12 15:51:21

    木有留言功能,我只好到处评论了说……不知道你有没有使用裁剪功能呢,都是自己继承CCLayer然后重写函数么……本来使用CCClippingNode在win32里面是可以的,可是我tolua到lua后,在win32还是可以,可是在android中就是不行啊,我试过CCDirector:sharedDirector():setDepthTest(true);也还是不行,应该和tolua没关系的吧……现在只好不使用CCClippingNode,所以想问一下有什么好的方案或者自带的方法可以直接使用呢?我看网上的方法貌似都是继承CCLayer然后重写的,但是我不想要重写,希望可以有现有的……哎,之前写的滑动列表的裁剪就是使用CCClippingNode的
    0回复
    • 博主 糟糕_树叶的mut 2013-12-12 16:25:44

      你这是逼我开留言板的节奏么= =不过,我没有用过裁剪,所以不太清楚~但是我在想,Scrollview本身也有裁剪,我用在Android没啥问题,你可以看看它怎么实现的~不过你都说了不想自己实现
      0回复
      • Oo幻想oO 2013-12-12 16:33:06

        恩恩,ScrollView和TableView都是可以的,所以我才觉得奇葩,为什么CCClippingNode就不行,lua部分也没有示例,而c++是有示例的,所以我也怀疑过lua部分的问题……好吧,自己实现罗……希望不会影响到我lua部分的代码……有留言板多好啊 哈哈……
        0回复
      • Oo幻想oO 2013-12-13 10:25:54

        快点看留言功能啦 哈哈……发现老大的魅族4.1.2(貌似)的机子是可以正常裁剪的,可是我的三星4.02的机子是不行的……目测是CCClippingNode对于手机性能上支持的问题了啦,移植的时候选的版本是2.2的……哎,还是要做
        0回复
        • 博主 糟糕_树叶的mut 2013-12-13 16:17:24

          我才没有幸灾乐祸~!留言板,好,会开的~噗哈哈
          0回复
  • Oo幻想oO 2013-10-05 11:07:30

    是不是通过事件分发啊?
    0回复
    • 博主 糟糕_树叶的mut 2013-10-05 12:41:57

      你指的是消息派发(CCNotificationCenter)?我这里用的是一个投机的方法,在层上盖一个层,上面的层有一个全屏的菜单按钮,这样就形成一个遮罩层屏蔽了下层的所有点击事件。当然,那个全屏菜单按钮的优先级要设置得高一些
      0回复
      • Oo幻想oO 2013-10-05 21:30:17

        对啊,虽然我还没看你写的这个,但方法应该是一样的……然后就是你没写的那个如何能不屏蔽对话框,我想的不是对话框,而是一般按钮,所以要在屏蔽层上判断点击的位置是否为按钮,是的话就触发分发到该按钮上的touch上面……今天刚初略的翻了你的书,不好意思啊,老大要求要用2.1.4,但是Lua部分没封装好,要自己花时间去想办法,所以没时间认真看你的书……初步觉得你的书不太适合新手去看,还是要有这方面经验的人看比较好,感觉以后可能会用到里面的知识,初学来讲压力甚大啊……话说这个网站和你csdn上的,看哪个好啊?
        0回复
        • 博主 糟糕_树叶的mut 2013-10-05 22:33:35

          我的做法是,给那些在屏蔽层之上的按钮赋予更高的触摸优先级,不过还真是一言难尽,有不少细节要处理~我的书大部分还是初学的内容,哈哈,。博客的话,如果是看以前的文章,就看csdn那个吧,格式比较好看,新文章的话,基本上都会先在这个博客发布~
          0回复
          • Oo幻想oO 2013-10-05 22:50:25

            那么menuitem的话是用setpriority来设置优先级么,好像默认是-128吧……之前用Unity3D是 层级》优先级的,先判断层级,在上面的先截取信息,所以学Cocos很不习惯,而且看api文档介绍太少,刚学看源码有点痛苦(大四生表示什么都是现在才开始学,压力甚大)……对了,那个编译android的那个,不使用cygin,用你提供的文件复制的问题非常感谢,之前看到网上不使用cygin,可是结果发现还是要安装cygin的时候感到很失望 哈哈
            0回复
            • 博主 糟糕_树叶的mut 2013-10-06 07:59:02

              貌似cocox3.0版本修改了这种优先级的方式(没有研究,不确定)~
              0回复
              • Oo幻想oO 2013-10-06 11:29:05

                别这样子,老大不用2.2,要用2.1.4我都快疯了啦,明明2.2Lua封装好了,如果到时候他们要升级版本,我现在要做的就全白做了……话说好佩服你们哎,家人,女友,动漫,游戏,实习;越来越觉得时间不够用了,怎么你们还有时间写教程神马的
                0回复
                • 博主 糟糕_树叶的mut 2013-10-06 16:50:07

                  如果是项目之前有积累的,那换版本确实有风险 事情什么的都是一件件积累,时间久了就觉得做的事情多了 我最近也比较少写教程了,嘿嘿
                  0回复
发表评论
粤ICP备16043700号

本博客基于 BlazorAnt Design Blazor 开发