Quick-Cocos2d-x3.3实现橡皮擦效果(刮刮乐)

时间:2023-02-08 18:08:31
参考了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_Proxy2位大神。


最后吐槽一下,第一次写,格式改了好几遍,囧。。。。


补充(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的解决方案消耗太大,不好用

参考:

http://zengrong.net/post/2067.htm

http://blog.csdn.net/ganpengjin1/article/details/46647483

http://blog.csdn.net/dionysos_lai/article/details/39030081?utm_source=tuicool