1. 程式人生 > >Quick-Cocos2d-x3.3實現橡皮擦效果(刮刮樂)

Quick-Cocos2d-x3.3實現橡皮擦效果(刮刮樂)

參考了zrong_Proxy的部落格,他們的程式碼我沒成功,各種改之後實現了,可是橡皮擦是矩形的,我想要圓形的,再看看。。。
已解決(其實就是一個多邊形,但是有個新問題,橡皮擦變成黑色了。。。)
,程式碼在下面,見補充(1)

原理

先將要被擦除的畫素渲染到 FrameBuffer 中,然後使用 Alpha 為 0 的畫素塊與已有畫素做混合,將已有的畫素替換成 Alpha 為 0 的畫素即可完成擦除。(拷貝自zrong大神)

下面放程式碼:

--要把這個圖片刮出來
    local dataSprite = cc.Sprite:create("showImg.png")
    dataSprite:setAnchorPoint(cc.p(0.5, 0.5));
    dataSprite:setPosition(display.cx,display.cy)
    self:addChild(dataSprite)

    -- pEarse = cc.DrawNode:create()
    -- pEarse:drawDot(cc.p(0, 0), 25, cc.c4f(0, 0, 0, 0));
    pEarse = display.newSolidCircle(5, {x = 0, y = 0, color = cc.c4f(0, 0, 0, 0)})
    pEarse:retain()

    self.pRTex = cc.RenderTexture:create(display.width, display.height)
    self.pRTex:retain()
    self.pRTex:setPosition(cc.p(display.cx, display.cy))
    self.pRTex:addTo(self)
    
--油漆層
    local pBg = cc.Sprite:create("youqi.png")
    pBg:retain()--必須retain,不然會被釋放,塗層無法顯示
    pBg:setAnchorPoint(cc.p(0.5, 0.5))
    pBg:setPosition(display.cx,display.cy)

    self.pRTex:begin()
    dataSprite:visit()
    pBg:visit()
    self.pRTex:endToLua()

    self:setTouchEnabled(true)
    self:addNodeEventListener(cc.NODE_TOUCH_EVENT,function(event)
        if event.name == "began" then
            	self:erasure(event)
                return true
        elseif event.name == "moved" then
            self:erasure(event)
        end

    end)
擦除程式碼:
function DrawRenderScene:erasure(event)

    pEarse:setPosition(event.x, event.y);
    -- 設定混合模式
    -- local blendFunc = { GL_ONE, GL_ZERO };
    -- pEarse:setBlendFunc(blendFunc);
    pEarse:setBlendFunc(gl.ONE,gl.ZERO);
    -- 將橡皮擦的畫素渲染到畫布上,與原來的畫素進行混合
    self.pRTex:begin();
    pEarse:visit();
    self.pRTex:endToLua();
    
end

unknown command in renderQueue錯誤是因為油漆層沒有retain。
over!特此記錄,以備將來使用。再次感謝 zrong_Proxy 2位大神。

最後吐槽一下,第一次寫,格式改了好幾遍,囧。。。。

補充(1)圓形橡皮擦

pEarse = cc.DrawNode:create()
	 pEarse:retain()
	--繪製圓形區域 
	local fRadius = 8.0-- 圓的半徑 
	local nCount = 100; --用正100邊型來模擬圓
	local coef = 2.0 * math.pi/nCount-- 計算每兩個相鄰頂點與中心的夾角 
	local circle = {}--頂點陣列 
	for i=1,nCount do
		local rads = (i-1)*coef; --弧度 
	  	circle[i] = {fRadius * math.cos(rads),fRadius * math.sin(rads)}-- 對應頂點的xy 
	  	print("circle[i] x="..fRadius * math.cos(rads)..",y="..fRadius * math.sin(rads))
	end
	
	--繪製這個多邊形! 
	display.newPolygon(circle,{fillColor = cc.c4f(1, 0, 1, 0),borderColor = cc.c4f(1, 0, 0, 0)},pEarse)
	pEarse:addTo(self,100)

抹除太快出現斷層和鋸齒的問題還沒解決,Dionysos_lai的解決方案消耗太大,不好用

參考: