cocos2d-x 制作透明遮罩

来源:互联网 发布:知错老师 编辑:程序博客网 时间:2024/04/30 14:48

在新公司的游戏项目中做新手引导..其中指定某些范围是亮的 其余地方都是暗的示意玩家去点击这个区域...

在网上找到

CCRenderTexture

很方便的就能实现 记录下这段学习历程
效果图:

遮罩图

  我们将使用这张图片来给我们的日历图片添加一个边框,是那种带有波纹效果的边框,而不是四边形的。这张图片透明的部分,就是遮罩效果的部分,而白色区域则是日历图片会显示的区域。

    为了实现这个效果,我们将使用OpenGL的混合模式。

    如果你回过头去看《如何使用CCRenderTexture来动态创建纹理》这篇教程的话,我们在那里讨论过OpenGL的混合模式。我在那里提到过一个非常方便的在线工具可以用来可见化调节混合模式的效果。

    为了完成我们想要的效果,我们需要采取下面的策略:

  1. 我们首先渲染mask精灵,把src color(就是mask精灵)设置为GL_ONE,并且把destination color(一个空的buffer)设置为GL_ZERO。所以,效果就是简单的把mask图片显示来。
  2. 接下来,我们渲染日历图片精灵。把src color(日历)设置为GL_DST_ALPHA。意思是,看看mask图片的当前alpha值是多少,如果是0(完全透明),,那么就显示日历图片。如果是1(完全不透明)那么就显示mask的。(译者注:如果大家对此不明白,可以参考这个链接)。然后把dst color(the mask)设计成GL_ZERO,这样的话,之前渲染上去的mask就消失了。

建立一个干净的“黑板”,然后在那执行1,2步来制作一个遮罩纹理。很幸运的是,用CCRenderTexture非常方便。

Masking and CCRenderTexture

    CCRenderTexture是一个这样的类,它可以让你在屏幕之外的buffer里面渲染。

    它用起来非常方便,主要有以下原因---你可以使用它来给你的游戏截屏,可以高效地缓存用户渲染的内容,可以在运行时动态地创建sprite sheet,或者,就像本教程中一样,可以制作一个mask sprite。

    为了使用CCRenderTexture,你需要采取以下4步:

  1. 创建CCRenderTexture类,以像素为单位,指定你想要绘制的纹理的宽度和高度.
  2. 调用CCRenderTexture的begin方法来初始化渲染操作。
  3. 调用OpenGL函数来绘制实际的内容--但是,这些OpenGL调用最终都会绘制到屏幕之外去,而不会影响游戏中现在渲染的图像。
  4. 调用CCRenderTexture的end方法来结束绘制操作。一旦你完成之后,CCRenderTexture有一个sprite属性,你可以把它当用CCSprite来用。

  不要觉得第3步很奇怪---因为你正在使用cocos2d,90%的情况你是不需要手动直接调用OpenGL函数的。但是,如果你想渲染一个节点的话,你可以直接调用某一个节点的visit方法,如[sprite visit],然后这个函数会自动为你发射一些OpenGL函数指针给图形硬件去显示。

  这里有一点需要注意的就是坐标问题。(0,0)点是渲染的纹理的左下角位置,所以,你在使用CCRenderTexture的时候,一定要把坐标设置对。

    好了,你可能听得有些烦了,程序员还是喜欢看代码的。好,让我们开始coding吧!


bool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if (!CCLayer::init() )    {        return false;    }    CCSize s = CCDirector::sharedDirector()->getWinSize();    int calendarNum = 0;    do     {        calendarNum = CCRANDOM_0_1() * 2;    } while(calendarNum == mLastCalendar);    mLastCalendar = calendarNum;    //     std::string name = "Calendar";        std::stringstream ss;    ss << mLastCalendar;    name += ss.str();    name += ".png";    // 加载sprite并置为全屏    CCSprite* sprite = CCSprite::create(name.c_str());    sprite->setScaleX((float)SCREEN_WIDTH / sprite->getContentSize().width);    sprite->setScaleY((float)SCREEN_HEIGHT / sprite->getContentSize().height);    sprite->setPosition(ccp(s.width/2, s.height/2));    //加载掩码图片    CCSprite* maskSprite = CCSprite::create("CalendarMask.png");    maskSprite->setScaleX((float)SCREEN_WIDTH / maskSprite->getContentSize().width);    maskSprite->setScaleY((float)SCREEN_HEIGHT / maskSprite->getContentSize().height);    maskSprite->setPosition(ccp(s.width/2, s.height/2));    CCSprite* maskCal = maskedSpriteWithSprite(sprite, maskSprite);    maskCal->setPosition( ccp(s.width/2, s.height/2) );    addChild(maskCal);        setTouchEnabled(true);    return true;}cocos2d::CCSprite* HelloWorld::maskedSpriteWithSprite(cocos2d::CCSprite* textureSprite, cocos2d::CCSprite* maskSprite){    // 1    int w = maskSprite->getContentSize().width * maskSprite->getScaleX();    int h = maskSprite->getContentSize().height * maskSprite->getScaleY();    CCRenderTexture* rt = CCRenderTexture::renderTextureWithWidthAndHeight(w, h);    // 2    maskSprite->setPosition( ccp(maskSprite->getContentSize().width *  maskSprite->getScaleX()/2,         maskSprite->getContentSize().height * maskSprite->getScaleY()/2));    textureSprite->setPosition( ccp(textureSprite->getContentSize().width *  textureSprite->getScaleX() /2,         textureSprite->getContentSize().height * textureSprite->getScaleY()/2));    // 3    ccBlendFunc blendFunc;    blendFunc.src = GL_ONE;    blendFunc.dst = GL_ZERO;    maskSprite->setBlendFunc(blendFunc);    blendFunc.src = GL_DST_ALPHA;            // mask图片的当前alpha值是多少,如果是0(完全透明),那么就显示mask的。如果是1(完全不透明)    blendFunc.dst = GL_ZERO;                // maskSprite不可见    textureSprite->setBlendFunc(blendFunc);    // 4    rt->begin();    maskSprite->visit();    textureSprite->visit();    rt->end();    // 5    CCSprite* retval = CCSprite::spriteWithTexture(rt->getSprite()->getTexture());    retval->setFlipY(true);    return retval;}

 让我们一步步来分解下面的操作:

  1. 使用mask精灵的大小来创建CCRenderTexture
  2. 重新设置mask精灵和texture精灵的位置,使它们的左下角是(0,0)
  3. 按照我们之前讨论的,设置每个精灵的blendFunc。
  4. 调用CCRenderTexture的begin方法来开始渲染操作,然后依次渲染mask和texture精灵,最后调用end方法。
  5. 基于CCRenderTexture的sprite属性的texture创建一个新的精灵,同时翻转y,因为纹理创建出来是倒的。

    好了,接下来,我们可以使用上面的函数来制作遮罩的效果了:


免责申明(必读!):本博客提供的所有教程的翻译原稿均来自于互联网,仅供学习交流之用,切勿进行商业传播。同时,转载时不要移除本申明。如产生任何纠纷,均与本博客所有人、发表该翻译稿之人无任何关系。谢谢合作!

原文链接地址:http://www.raywenderlich.com/4421/how-to-mask-a-sprite-with-cocos2d-1-0

同类文章:http://www.cnblogs.com/dingwenjie/archive/2012/04/02/2429576.html 





原创粉丝点击