Cocos2d-js通过显示底层来创建着色效果

时间:2014-11-24 01:15:01

标签: cocos2d-x cocos2d-js

我有一个适用于有着色屏幕的孩子的Android应用程序,我正在尝试将其转换为Cocos2d-js。我在Android中实现这一点的方法是将两张图片叠加在一起:底部是彩色图片,顶部是灰度图片。检测到触摸时,顶部的灰度图像会在显示底部图像的位置上被删除。

我正在查看RenderTexture的着色效果,而ClippingNode用于显示底层,但是当我将RenderTexture设置为ClippingNode的模板时,顶部图像是完全透明的(模板是不透明的?)

到目前为止这是我的代码(仅限顶层,因为底层只是一个覆盖整个屏幕的精灵):

var GrayScaleLayer = cc.Layer.extend({

    winsize: null,
    _brushs:null,
    _target:null,
    _lastLocation:null,

    ctor:function () {
        this._super();
        this.init();
    },

    init:function () {

        if ('touches' in cc.sys.capabilities){
            cc.eventManager.addListener({
                event: cc.EventListener.TOUCH_ALL_AT_ONCE,
                onTouchesMoved:function (touches, event) {
                    event.getCurrentTarget().drawInLocation(touches[0].getLocation());
                }
            }, this);
        } else if ('mouse' in cc.sys.capabilities)
            cc.eventManager.addListener({
                event: cc.EventListener.MOUSE,
                onMouseDown: function(event){
                    event.getCurrentTarget()._lastLocation = event.getLocation();
                },
                onMouseMove: function(event){
                    if(event.getButton() == cc.EventMouse.BUTTON_LEFT)
                        event.getCurrentTarget().drawInLocation(event.getLocation());
                }
            }, this);

        // Get the screen size of your game canvas
        this.winsize = cc.director.getWinSize();

        this._brushs = [];
        this._lastLocation = cc.p(this.winsize.width, this.winsize.height);

        // Create the RenderTexture object
        var stencil = this.erase();
        stencil.setPosition(cc.p(this.winsize.width/2, this.winsize.height/2));

        // Create the clippingNode and add the RenderTexture as a stencil
        var clipper = new cc.ClippingNode();
        clipper.setPosition(cc.p(0,0));
        clipper.stencil = stencil;
        clipper.setInverted(true);
        this.addChild(clipper);

        // Create gray scale image and add it to the Clipping node
        var grayItem = new cc.Sprite(res.image_gs_png);
        var grayScale = this.winsize.width/grayItem.width;
        grayItem.setScale(grayScale, grayScale);
        grayItem.setPosition(cc.p(this.winsize.width/2, this.winsize.height/2));
        clipper.addChild(grayItem);

    },

    erase:function () {
        var target = new cc.RenderTexture(this.winsize.width, this.winsize.height);

        this._target = target;

        return target;
    },

    drawInLocation:function (location) {
        var distance = cc.pDistance(location, this._lastLocation);

        if (distance > 1) {
            var locLastLocation = this._lastLocation;
            this._target.begin();
            this._brushs = [];
            for(var i = 0; i < distance; ++i) {
                var diffX = locLastLocation.x - location.x;
                var diffY = locLastLocation.y - location.y;
                var delta = i / distance;
                var sprite = new cc.Sprite(res.brush_png);
                sprite.attr({
                    x: location.x + diffX * delta,
                    y: location.y + diffY * delta,
                    rotation: Math.random() * 360,
                    color: cc.color(Math.random() * 255, 255, 255),
                    scale: Math.random() + 0.25,
                    opacity: 20
                });
                sprite.retain();
                this._brushs.push(sprite);
            }
            for (var i = 0; i < distance; i++) {
                this._brushs[i].visit();
            }
            this._target.end();
        }
        this._lastLocation = location;
    },

    onExit:function () {
        for(var i in this._brushs){
            this._brushs[i].release();
        }
        this._super();
    }
});

我尝试在RenderTexture上使用.clear(rgba)函数无济于事。

我注意到js-tests中的ClippingNode示例是将DrawNode对象添加为模板,有没有办法将RenderTexture“转换”为DrawNode?

1 个答案:

答案 0 :(得分:1)

您不需要使用clippingNode

只需在底部有彩色图层,在顶部有一个灰度的rendertexture

触摸时,通过使用此混合函数{src: gl_ZERO, dst: gl_ONE_MINUS_SRC_ALPHA}

将精灵绘制到rendertexture上来擦除透明度