cocos2dx 实现战争迷雾效果

游戏里面的战争迷雾或者刮刮乐效果可以用下面的方法实现

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计算有问题。改成如下就好了:

效果如下:


猜你喜欢

转载自blog.csdn.net/pengchengo/article/details/78227575