如何使用Cocos2d-x3.0来给Sprite添加遮罩
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用Cocos2d-x3.0来给Sprite添加遮罩相关的知识,希望对你有一定的参考价值。
参考技术A //a static methodSprite* HelloWorld::maskedSpriteWithSprite(Sprite* textureSprite, Sprite* maskSprite)
// 1
RenderTexture * rt = RenderTexture::create( maskSprite->getContentSize().width,
maskSprite->getContentSize().height );
// 2
maskSprite->setPosition(maskSprite->getContentSize().width/2,
maskSprite->getContentSize().height/2);
textureSprite->setPosition(textureSprite->getContentSize().width/2,
textureSprite->getContentSize().height/2);
// 3
maskSprite->setBlendFunc( BlendFuncGL_ONE, GL_ZERO );
textureSprite->setBlendFunc( BlendFuncGL_DST_ALPHA, GL_ZERO );
// 4
rt->begin();
maskSprite->visit();
textureSprite->visit();
rt->end();
// 5
Sprite *retval = Sprite::createWithTexture(rt->getSprite()->getTexture());
retval->setFlippedY(true);
return retval;
..本回答被提问者和网友采纳 参考技术B 我们将使用这张图片来给我们的日历图片添加一个边框,是那种带有波纹效果的边框,而不是四边形的。这张图片透明的部分,就是遮罩效果的部分,而白色区域则是日历图片会显示的区域。
为了实现这个效果,我们将使用OpenGL的混合模式。
如果你回过头去看《如何使用CCRenderTexture来动态创建纹理》这篇教程的话,我们在那里讨论过OpenGL的混合模式。我在那里提到过一个非常方便的在线工具可以用来可见化调节混合模式的效果。
为了完成我们想要的效果,我们需要采取下面的策略:
我们首先渲染mask精灵,把src color(就是mask精灵)设置为GL_ONE,并且把destination
color(一个空的buffer)设置为GL_ZERO。所以,效果就是简单的把mask图片显示来。
接下来,我们渲染日历图片精灵。把src
color(日历)设置为GL_DST_ALPHA。意思是,看看mask图片的当前alpha值是多少,如果是0(完全透明),那么就显示mask的。如果是1(完全不透明),那么就显示日历图片。(译者注:如果大家对此不明白,可以参考这个链接)。然后把dst
color(the mask)设计成GL_ZERO,这样的话,之前渲染上去的mask就消失了。
很酷吧!你可能会觉得我们只需要先把mask精灵渲染上去,然后再渲染日历精灵,并且指定这两个精灵的blendFunc就行了。可是,实际上这样是行不通的!
上面所提到的混合算法,当精灵下面还有一些精灵在渲染的时候就会出问题---比如背景图片上面有一个精灵。这是因为,这里作了一个假设,在上面做完1那个步骤之后,imgae
buffer里面只存在唯一一张图片,那就是mask。(这个假设当然是不正确的啦,因为你要切换日历图片对不对?)
因此,我们需要一种方式,可以建立一个干净的“黑板”,然后在那执行1,2步来制作一个遮罩纹理。很幸运的是,用RenderTexture非常方便。
Masking
and CCRenderTexture]
RenderTexture是一个这样的类,它可以让你在屏幕之外的buffer里面渲染。
它用起来非常方便,主要有以下原因---你可以使用它来给你的游戏截屏,可以高效地缓存用户渲染的内容,可以在运行时动态地创建sprite
sheet,或者,就像本教程中一样,可以制作一个mask sprite。
为了使用RenderTexture,你需要采取以下4步:
创建RenderTexture类,以像素为单位,指定你想要绘制的纹理的宽度和高度。
调用RenderTexture的begin方法来初始化渲染操作。
调用OpenGL函数来绘制实际的内容--但是,这些OpenGL调用最终都会绘制到屏幕之外去,而不会影响游戏中现在渲染的图像。
调用RenderTexture的end方法来结束绘制操作。一旦你完成之后,RenderTexture有一个sprite属性,你可以把它当用Sprite来用。
不要觉得第3步很奇怪---因为你正在使用Cocos2d,90%的情况你是不需要手动直接调用OpenGL函数的。但是,如果你想渲染一个节点的话,你可以直接调用某一个节点的visit方法,如sprite->visit,然后这个函数会自动为你发射一些OpenGL函数指针给图形硬件去显示。
这里有一点需要注意的就是坐标问题。(0,0)点是渲染的纹理的左下角位置,所以,你在使用RenderTexture的时候,一定要把坐标设置对。
好了,你可能听得有些烦了,程序员还是喜欢看代码的。好,让我们开始coding吧!
给精灵添加遮罩: 最终实现
打开HelloWorldScene.m,然后在init方法上面添加下面的方法,注意这个方法是静态的,在头文件声明时需要注意:
//a static method
Sprite* HelloWorld::maskedSpriteWithSprite(Sprite* textureSprite, Sprite* maskSprite)
// 1
RenderTexture * rt = RenderTexture::create( maskSprite->getContentSize().width,
maskSprite->getContentSize().height );
// 2
maskSprite->setPosition(maskSprite->getContentSize().width/2,
maskSprite->getContentSize().height/2);
textureSprite->setPosition(textureSprite->getContentSize().width/2,
textureSprite->getContentSize().height/2);
// 3
maskSprite->setBlendFunc( BlendFuncGL_ONE, GL_ZERO );
textureSprite->setBlendFunc( BlendFuncGL_DST_ALPHA, GL_ZERO );
// 4
rt->begin();
maskSprite->visit();
textureSprite->visit();
rt->end();
// 5
Sprite *retval = Sprite::createWithTexture(rt->getSprite()->getTexture());
retval->setFlippedY(true);
return retval;
让我们一步步来分解下面的操作:
使用mask精灵的大小来创建CCRenderTexture
重新设置mask精灵和texture精灵的位置,使它们的左下角是(0,0)
按照我们之前讨论的,设置每个精灵的blendFunc。
调用CCRenderTexture的begin方法来开始渲染操作,然后依次渲染mask和texture精灵,最后调用end方法。
基于CCRenderTexture的sprite属性的texture创建一个新的精灵,同时翻转y,因为纹理创建出来是倒的。
好了,接下来,我们可以使用上面的函数来制作遮罩的效果了:
//cal->setPosition(visibleSize.width/2, visibleSize.height/2);
Sprite * mask = Sprite::create("CalendarMask.png");
Sprite * maskedCal = maskedSpriteWithSprite(cal, mask);
maskedCal->setPosition(visibleSize.width/2, visibleSize.height/2);
//pRet->addChild(cal);
pRet->addChild(maskedCal);
编译并运行
如何使用 Javascript 键盘事件触发 CSS Sprite 动画
【中文标题】如何使用 Javascript 键盘事件触发 CSS Sprite 动画【英文标题】:How to Trigger CSS Sprite Animation Using Javascript Keyboard Event [duplicate] 【发布时间】:2018-08-27 11:16:29 【问题描述】:我有一个空 div 的闪烁精灵 css 动画。
#flashIt
width: 50%;
height: 100px;
background: blue;
margin: 10px auto;
border: solid 2px black;
left: 25%;
animation: flash 1s linear infinite;
@keyframes flash
0% opacity: 1;
50% opacity: .1
100% opacity: 1;
所以这个动画按原样工作。但是我希望动画在用户在键盘上按下一个键时开始。我怎样才能使用 JS 做到这一点?对此的帮助将不胜感激。谢谢
【问题讨论】:
【参考方案1】:一个简单的方法是监听按键,然后,当按键被按下时,将一个类应用于适当的 DOM 元素。此类将包含您的动画样式,然后按照您的需要为元素设置动画。
var elementToAnimate = document.findElementById("flashIt");
document.addEventListener('keypress', function(event)
elementToAnimate.classList.add('your-animation-class');
);
【讨论】:
【参考方案2】:这是你可以做的一个例子。
$(document).keypress('keypress',function(e)
if(e.which==13)
$('div').toggleClass('animation');
);
这将在您按下回车键时激活动画类。
【讨论】:
虽然这可行,但 OP 从未说明他们是否使用 jQuery。 只是向他们展示了解决问题的另一种方法。对不起。 根本不是问题,只是想确保 OP 不会尝试实施您的解决方案并在它不起作用时感到困惑甚至卡住。 (假设他没有在幕后使用 jQuery)以上是关于如何使用Cocos2d-x3.0来给Sprite添加遮罩的主要内容,如果未能解决你的问题,请参考以下文章
Cocos2d-x 3.0 基础系列一 各类回调函数写法汇总
Cocos2d-x 3.0 基础系列一 各类回调函数写法汇总
基于Cocos2d-x-1.0.1的飞机大战游戏迁移到Cocos2d-x-3.0版本,并移植到Android平台成功运行