我有一个带有彩色屏幕的儿童 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?