前言
作为一个刚进入游戏公司的小菜鸟,接到了一个把新手任务成果–flappybird嵌入到项目中去。本以为会是一个轻松加愉快的过程,结果却大坑没有小坑不断。。。(我太菜了,哭了)如何实现遮罩就是其中一个非常值得记录的小坑。
首先来看一下我为什么用到遮罩。。。嵌入到项目中后flappybird的游玩界面是这样子的:
我晕了,这也太丑了把,哭了
思路及解决
首先想到的解决办法就是通过将纯黑的图片作为Sprite、Node等addChild到渲染根结点(公司项目中这里的渲染根节点是panel.res,使用时Node、Scene、Layer等也可以)上,然后调整ZOrder在实现遮罩。方法确实可以,就是有点蠢。于是上网找到了这篇文章(https://blog.csdn.net/u012685888/article/details/79161307),使用遮罩层覆盖,通过剪切图形显示需要显示的内容,原文中剪切函数只有圆形,补充了矩形的切割(三角形、多边形切割迷之不行,待解决)。代码如下:
mainNode = MainNode:create(self)
mainNode:setScale(2)
mainNode:setName("mainNode")
mainNode:setPosition(cc.p(-960, -540))
self.res:addChild(mainNode)
self:HighLightInColoerLayer(display.center)
-- 遮罩层上剪切高亮圆形
function FlappyBirdPanel:HighLightInColoerLayer(pos)
-- 遮罩层上剪切高亮圆形,开始
--self.colorLayer:hide()
self.node = cc.Node:create()
self.clip = cc.ClippingNode:create(self.node)
self.clip:setInverted(true)
self.clip:setAlphaThreshold(0)
self:addChild(self.clip, 4)
self.blackLayer = cc.LayerColor:create(cc.c4b(0,0,0,255),display.width,display.height)
self.clip:addChild(self.blackLayer, 4)
local glNode = cc.GLNode:create()
glNode:setContentSize(cc.size(120, 120))
glNode:setAnchorPoint(cc.p(0.5, 0.5))
local function primitivesDraw()
--剪切圆形
gl.lineWidth(2)
cc.DrawPrimitives.drawColor4B(0, 0, 0, 1)
--圆心,半径,旋转角度(弧度,边数,x轴缩放,y轴缩放
cc.DrawPrimitives.drawSolidCircle(cc.p(1750, 990), 55, 0, 50, 1,1)
--剪切多边形
-- gl.lineWidth(1)
-- local filledVertices = { cc.p(0,120), cc.p(50,120), cc.p(50,170), cc.p(25,200), cc.p(0,170) }
-- --参数:顶点列表,顶点数,颜色
-- cc.DrawPrimitives.ccDrawSolidPoly(filledVertices, 5, cc.c4f(0, 0, 0, 1))
--剪切三角形
-- gl.lineWidth(2)
-- cc.DrawPrimitives.drawColor4B(0, 0, 0, 255)
-- local closePoints= { cc.p(30,130), cc.p(30,230), cc.p(50,200) }
-- cc.DrawPrimitives.drawPoly( closePoints, 3, true)
gl.lineWidth(2)
cc.DrawPrimitives.drawSolidRect(cc.p(display.cx - 260, display.cy - 540 ), cc.p(display.cx + 260, display.cy + 540), cc.c4f(0, 0, 0, 1))
end
glNode:registerScriptDrawHandler(primitivesDraw)
self.node:addChild(glNode, 4)
self.glNode = glNode
-- 遮罩层上剪切高亮图形,结束
end
效果是这样的(感觉还行,不过还是有点丑,不满意):
通过对网上资源的查阅发现对于遮罩的实现大多使用layer或者node等控件实现遮罩层,但是小菜鸡得到了大佬的仙人指路–使用layout实现(吼吼,太舒服了),直接上效果图吧:
诶,舒服~~~
show me the code, please???
self.layout = ccui.Layout:create()
self.layout:setClippingEnabled(true)
self.layout:setContentSize(cc.size(530, 860))
self.layout:setPosition(display.cx-265, 110)
self.res:addChild(self.layout)
mainNode = MainNode:create(self)
mainNode:setPosition(cc.p(-1655, -700))
self.layout:addChild(mainNode)
代码很少,关键思路是:
首先使用ccui.Layout:create()来创建一个layout,setClippingEnabled(true)设置layout可剪切,setContentSize(cc.size(530, 860))设置剪切的矩形的size,这个矩形将是layout的可视区域(菜鸡目前是这样理解的),然后将layout addChild到渲染根结点中(项目中用的是self.res),如果你的渲染根结点是self,那么就直接self:addChild(self.layout)哦。
第二步是将你要展示的node或者sprite等addChild到刚刚创建的layout中就行了,注意通过layout、mainNode的setPosition调整位置,根据情况自己设置。