游戏里面的战争迷雾或者刮刮乐效果可以用下面的方法实现
function MainScene:onCreate()
local strVertSource =
"attribute vec4 a_position;\n"..
"attribute vec2 a_texCoord;\n"..
"attribute vec4 a_color;\n"..
"\n#ifdef GL_ES\n\n"..
"varying lowp vec4 v_fragmentColor;\n"..
"varying mediump vec2 v_texCoord;\n"..
"varying lowp vec2 v_fragPosition;\n"..
"\n#else\n\n"..
"varying vec4 v_fragmentColor;\n"..
"varying vec2 v_texCoord;\n"..
"\n#endif\n\n"..
"void main()\n"..
"{\n"..
" gl_Position = CC_PMatrix * a_position;\n"..
" v_fragmentColor = a_color;\n"..
" v_texCoord = a_texCoord;\n"..
"}"
local strFragSource =
"\n#ifdef GL_ES\n\n"..
"precision lowp float;\n"..
"\n#endif\n\n"..
"varying vec4 v_fragmentColor;\n"..
"varying vec2 v_texCoord;\n"..
"uniform vec2 center;\n"..
"void main()\n"..
"{\n"..
"float distance = length(v_texCoord.xy - vec2(0.5,0.5));\n"..
"float a = 0.0;\n"..
"if(distance < 0.05) a = 1.0;\n"..
"if(distance > 0.05 && distance < 0.3) a = 1-(distance-0.05)/0.25;\n"..
"gl_FragColor = vec4(0.0, 0.0, 0.0, a);\n"..
"}\n"
local bgPic = cc.Sprite:create("beijing.png")
self:addChild(bgPic)
bgPic:setPosition(display.cx, display.cy)
local glProgram = cc.GLProgram:createWithByteArrays(strVertSource, strFragSource)
glProgram:retain()
local holePic = cc.Sprite:create("rectPic.png")
holePic:retain()
holePic:setGLProgram(glProgram)
holePic:setPosition(display.cx, display.cy)
holePic:setBlendFunc(gl.ZERO, gl.ONE_MINUS_SRC_ALPHA)
local renderTexture = cc.RenderTexture:create(display.width,display.height)
renderTexture:retain()
renderTexture:beginWithClear(0.0, 0.0, 0.0, 1.0)
renderTexture:endToLua()
local renderPic = cc.Sprite:createWithTexture(renderTexture:getSprite():getTexture())
renderPic:setScaleY(-1)
self:addChild(renderPic,2)
renderPic:setPosition(display.cx, display.cy)
local function erase(location)
renderTexture:begin()
holePic:setPosition(location.x, location.y)
holePic:visit()
renderTexture:endToLua()
end
--创建触摸回调
local function touchBegin(touch, event)
erase(touch:getLocation())
return true
end
local function touchMove(touch, event)
erase(touch:getLocation())
return true
end
local function touchEnd(touch, event)
return true
end
local layer = cc.Layer:create()
self:addChild(layer, 10)
local listener = cc.EventListenerTouchOneByOne:create()
listener:registerScriptHandler(touchBegin, cc.Handler.EVENT_TOUCH_BEGAN )
listener:registerScriptHandler(touchMove, cc.Handler.EVENT_TOUCH_MOVED )
listener:registerScriptHandler(touchEnd, cc.Handler.EVENT_TOUCH_ENDED )
local eventDispatcher = layer:getEventDispatcher()
eventDispatcher:addEventListenerWithSceneGraphPriority(listener, layer)
end
原理就是先用renderTexture渲染一张纯黑的纹理,然后每次点击或者移动的时候,根据当前位置,用
rectPic.png(任意一张图片)和renderTexture之前渲染的纹理混合,让点击区域的透明度成圆形的渐变效果。
用这个方法出现一个问题,多次渲染纹理四周出现拉伸效果。应该是cocos的投影矩阵计算有问题,Director::getZEye计算有问题。改成如下就好了:
效果如下: