cc下橡皮擦的实现代码

看了一些有关“橡皮擦”的贴子,但都只是意思,没有代码。而实际以原来cocos2dx的代码来做,又总是出不来,经过一天的试验,得到在CC下实现的代码:

//要盖在某一个节点上,得到这个节点的大小,这里指到另一个节点上,简化的话,就直接指自己也行
let mwidth = self.onode.width;
let mhight = self.onode.height;
let mask = new cc.DrawNode();
//画一个矩形的遮罩层
mask.drawRect(cc.p(0, 0), cc.p(mwidth, mhight), cc.color(0, 255, 255, 255), 1, cc.color(128, 128, 0, 255));
//准备一个相同大小的rendertexture,放到节点下
let rt = new cc.RenderTexture(mwidth, mhight);
self.onode._sgNode.addChild(rt);
//先渲染上遮罩层
rt.begin();
mask.visit();
rt.end();
//准备要橡皮擦
let e1 = new cc.DrawNode();
//触摸监听
cc.eventManager.addListener({
  event: cc.EventListener.TOUCH_ONE_BY_ONE,
  onTouchBegan: function(touch, event) {
    return true;
  },
  onTouchMoved: function(touch, event) {
    //得到当前触点在节点内的坐标
    var pos = touch.getLocation();
    var target = event.getCurrentTarget();
    let pos1 = target.convertToNodeSpaceAR(pos);
    cc.log(pos.x + ":" + pos.y);
    cc.log(pos1.x + ":" + pos1.y);
    //画一个圆,坐标系统由于是cocos2dx的,所以计算一下
    e1.drawDot(cc.p(mwidth/2 + pos1.x, mhight/2 + pos1.y), 30, cc.color(255, 255, 255, 255));
    //这一步最重要,选择透明之外的部分,也就是画的圆,将渲染入的底图,也就是遮罩层,以透明方式
    //融合,形成一个有洞的遮罩层。
    e1.setBlendFunc(cc.ZERO, cc.ONE_MINUS_SRC_ALPHA);
    rt.begin();
    e1.visit();
    rt.end();
  }
}, rt);

有几个问题:
(1)renderTexture和drawnode都不在CC的API里,要看其它的API,而一些参数与之又不一样,看了源码才找到(cc.ONE_MINUS_SRC_ALPHA)
(2)也可以用图片来做遮罩层,_sgNode.visit()就可以了,但需要其显示出来后,visit才有用,也就是一定要把图片挂在某个节点下,但这样就会出现renderTexture不显示问题,还要在最后将其node.parent=null,从节点中去掉,十分麻烦。
(3)新的Graphics也可以画形,并且样数还多,但visit时有问题,看了源码也没研究清楚,它自己有一个renderCMD的东西,不知道与renderTexture有什么关联。
(4)原始的cocos2dx的代码都说要画一个透明的圆cc.color(255, 255, 255, 0),我在这里上了当,后来想想,一个drawNode本来就是空的,再画一个透明的圆,不还是透明的吗?这也是开始我的“橡皮擦”总是矩形的原因,后来才多花了许多时间。
(5)在Web下始终调不过去,只在android下成功了。

5赞

楼主我一直报这个错为啥
加了一段这些

1赞

忘了说了,我在WEB下始终过不去,我是在android和模拟器里的。可能是因为cc.renderTexture的原因

另外研究WEB下发现:

(1)
原来直接指定,这里必需用这种模式setBlendFunc(new cc.BlendFunc(771, 0)),或是cc.BlendFunc下的预定的模式 e1.setBlendFunc(cc.BlendFunc.ADDITIVE);
此方式是android与WEB兼容的,就不会报找不到src那个问题了,但其实没什么用,后面说。那个值跑到了另一个地方(771)cc.BlendFunc.BlendFactor。

(2)
webGL是不行的,会报一个找不到cc.km???什么的错,需要用canvas才行

(3)
在后面再触发时进行beginàvisit-àend会没有效果,原因是默认打开了脏矩形,开始不知道,怎么都没变化,后来灵机一动。。。。。!@#¥,要置一下,cc.renderer.enableDirtyRegion(false);但模拟器会说没定义,用cc.sys自己搞吧

(4)
最后,无论怎么设置blendfunc,都没什么效果,只有附加一种,也就是在已有的上面再画一点什么是可以的,反正是不报错了。

(5)
看了一下如何截屏的那个贴,也用了rendertexture,但是if(CC_JSB),在Web下是不可以的,找不到gl,就是gl.DEPTH24_STENCIL8_OES,它=35056,没用,还是不能融合透明,估计是引擎的哪个地方有错吧。

在模拟器里实现了

引擎团队的人会完善api的文档吗?感觉和渲染有关的api还是用的比较多的。

好像在代码在web调试canvas模式,底图是白色的!!

这个换成图片做遮挡···为什么就不行啊?

可以,就是得先把图片挂到其它节点上再visit,处理完了后再用parentNode=null,把它从界面清出,所以比较麻烦。
可能是因为引擎内部的优化,认为没有在节点上的图片都不进行渲染造成的,这是两难的问题,给了接口后会使引擎条件更多更复杂,不给接口一刀切就会有特别的需求无法实现。只能建议就加一个遮挡方法吧,毕竟有需求嘛。

这功能我已经实现了···谢谢···不过这个只能在原生平台,在web上没法用,所以调试的时候不是很方便···

为什么我使用e1.setBlendFunc(cc.ZERO, cc.ONE_MINUS_SRC_ALPHA)完全没有效果。使用e1.setBlendFunc(cc.BlendFunc.ADDITIVE)的话橡皮擦是圆形的却不能透明(白色的,会遮住底下的图片),使用setBlendFunc(new cc.BlendFunc(771, 0))的话是透明的擦除效果,但是橡皮擦是正方形的。请问已经实现了的个位大神说下到底应该传入哪个值给setBlendFunc()函数?

renderTexture会调用c++那边的 web当然没用 顺便说一下 web端是调用不到jsb的

兄弟,请看清楚,我不是说web,因为如果是web我就不会说后面两句话了,web是全部都不可以的,我后面两句说的是传入其他参数可以,只是效果与我想象的不一样(橡皮擦不是圆形的),我是在模拟器和终端测试的。

换成图片好像不行哇,哪位大神解答一下。
rt.begin();
this.back._sgNode.visit();
//mask.visit();
rt.end();
this.back.active = false;
这样子rendertexture不会被渲染出来

H5我实现过,就是直接自己用JS实现,在游戏上面再盖一层CANVAS,调用JS方法擦除,就是感觉比较蛋疼

图片可以visit,只是不能在尚未渲染的时候visit,自己弄明白了

兄弟,你调用颜色混合函数setBlendFunc的时候传入的是哪个参数呀,我1.6版本,native端测试,使用e1.setBlendFunc(cc.ZERO, cc.ONE_MINUS_SRC_ALPHA)完全没有效果。使用e1.setBlendFunc(cc.BlendFunc.ADDITIVE)的话橡皮擦是圆形的却不能透明(白色的,会遮住底下的图片),使用setBlendFunc(new cc.BlendFunc(771, 0))的话是透明的擦除效果,但是橡皮擦是正方形的,应该是混合后的圆形变成了矩形导致的。

同问。参数多少?

同问,求参数

请问怎么判断蒙板有没有全部擦除完呢???