You said “touch” in previous points. So the first question is a precision input device being used always with your game? If not then pixel-perfect is overkill.
Are your sprites that you want to check regular shapes? If so they could flag which shape type they are and do circle, rect, polygon based collision checking either using simple regular shapes (parameterized shapes) where you can create the shape with {center, radius} or {center, width, height} or similar. Then testing w/circle, for example, just do a radial distance check to the click.
If you still think you need pixel-perfect (due to shapes with many pixel holes and irregular boundaries) then you might want to look into color-ID rendering for something you can search about with the phrase “opengl color picking glreadpixels” or similar where answers will explain you should render a color per entity, or two colors if you only render a single thing and only need to know a pixel is present or not.
This worked for me. You’re mileage may vary (YMMV)
I prob can’t help much beyond this. So if you still can’t get it working or have questions, probably smart to create a new topic for it (guessing no one else will reply to this one).
cc.log("constructing!");
cc.director.setClearColor(cc.color(0, 0, 128, 64));
if ('opengl' in cc.sys.capabilities) {
var x = winSize.width;
var y = winSize.height;
var blue = new cc.LayerColor(cc.color(0, 0, 255, 128));
var red = new cc.LayerColor(cc.color(255, 0, 0, 128));
var green = new cc.LayerColor(cc.color(0, 255, 0, 128));
var white = new cc.LayerColor(cc.color(255, 255, 255, 128));
cc.log("x,y = " + x + ", " + y);
blue.scale = 0.5;
blue.x = -x / 4;
blue.y = -y / 4;
red.scale = 0.5;
red.x = x / 4;
red.y = -y / 4;
green.scale = 0.5;
green.x = -x / 4;
green.y = y / 4;
white.scale = 0.5;
white.x = x / 4;
white.y = y / 4;
this.addChild(blue, 10);
this.addChild(white, 11);
this.addChild(green, 12);
this.addChild(red, 13);
var node = cc.Sprite.create("res/texture512x512.png");
node.setNormalizedPosition(cc.p(0.5, 0.5));
//node.setTextureRect(cc.rect(0,0,20,20));
node.setColor(cc.color(255, 128, 0));
node.setOpacity(128);
this.addChild(node);
//var renderTexture = cc.RenderTexture.create(5, 5);
//renderTexture.beginWithClear(255, 128, 0, 0);
//node.visit();
//renderTexture.end();
//this.addChild(renderTexture);//.getTexture());
// need to wait a frame before reading (should see 255,128,0,0 in output)
this.scheduleOnce(function() {
var ws = cc.director.getWinSize();
var w = ws.width;
var h = ws.height;
var pixels = new Uint8Array(4);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
for (pixel in pixels) {
cc.log("ret[" + pixel + "] = " + pixels[pixel]);
}
gl.readPixels(w, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
for (pixel in pixels) {
cc.log("ret[" + pixel + "] = " + pixels[pixel]);
}
gl.readPixels(0, h, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
for (pixel in pixels) {
cc.log("ret[" + pixel + "] = " + pixels[pixel]);
}
gl.readPixels(w, h, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
for (pixel in pixels) {
cc.log("ret[" + pixel + "] = " + pixels[pixel]);
}
});
output:
JS: ret[0] = 0
JS: ret[1] = 0
JS: ret[2] = 192
JS: ret[3] = 96
JS: ret[0] = 128
JS: ret[1] = 0
JS: ret[2] = 64
JS: ret[3] = 96
JS: ret[0] = 0
JS: ret[1] = 128
JS: ret[2] = 64
JS: ret[3] = 96
JS: ret[0] = 128
JS: ret[1] = 128
JS: ret[2] = 192
JS: ret[3] = 96