点击sprite上的透明区域 无响应问题 像素获取

最近想做 点击到一个建筑的时候,处理某个事件,由于建筑不是规则图像,所有可能点击到控件的透明区域,点击到透明区域时不响应事件。
我用的环境是vs2012+cocos2d_x3.1
网上查了下相关问题,我用的是这样的代码:
void ViewCity::onTouchEnded(Touch touch, Event unused_event)
{
Node
target = static_cast<Node
>(unused_event->getCurrentTarget());

Vec2 locationInNode = target ->convertToNodeSpace(touch->getLocation());
Size s = target ->getContentSize();
Rect rect = Rect(0, 0, s.width, s.height);
if(rect.containsPoint(locationInNode))
{
if(
getOpacityWithPoint(target,locationInNode) > 50)
{
//todo处理事件
//发事件给ViewFight界面监听的,这个界面判定选择的对象应该去攻击谁
}
}
}

int ViewCity::
getOpacityWithPoint(Sprite *pSpr, Point point)
{
point.y = pSpr->getContentSize().height-point.y;

//Sprite* pNewSpr = Sprite::createWithSpriteFrame(pSpr->displayFrame());
Sprite* pNewSpr = Sprite::createWithTexture(pSpr->getTexture());
pNewSpr->setAnchorPoint(CCPointZero);
//+截屏操作
RenderTexture* pRender = RenderTexture::create(pSpr->getContentSize().width, pSpr->getContentSize().height, Texture2D::PixelFormat::RGBA8888);
pRender->begin();
pSpr->visit();
pRender->end();
//-截屏操作

Image * pImage = pRender->newImage();
//getColor4B函数是个人加到Image底层的获取像素点颜色的函数
Color4B c = pImage->getColor4B(point.x, point.y);

return c.a;
}

但是上诉代码中,绿底红字部分,得到的pImage的透明度全部是0。根本得不到正确的像素值

注:我的控件上的图片,我是不知道从哪个路径得到的。有方法是:根据Sprite创建的图片路径,重新创建一个Image,当然这样应该没有问题。但是我不知道sprite创建的图片路径。
这个问题我弄了2天了,没解决,求各位大大们,有什么好的方法。

bool checkPixels(Point pos, Image *image){
int width = image->getWidth();
int height = image->getHeight();
if (pos.x<0 || pos.x>width || pos.y<0 || pos.y>height){
return false;
}
Color4B c = {0, 0, 0, 0};
unsigned int x = pos.x, y = height-pos.y;

unsigned char *data_=image->getData();
unsigned int *pixel = (unsigned int *)data_;
pixel = pixel + (y * width) + x;        //480 是图片的宽
c.r = *pixel & 0xff;
c.g = (*pixel >> 8) & 0xff;
c.b = (*pixel >> 16) & 0xff;
c.a = (*pixel >> 24) & 0xff;        //这个值  就是透明度

return (c.r>0 || c.g>0 || c.b>0) && c.a>0;

}

这个是3.0之后版本的渲染问题,RenderTexture直接saveToFile(3.2以上的版本saveToFile才能保存透明通道,3.0-3.2以前需要修改saveToFile方法)可以成功,实际上也是用了newImage这个方法new个Image。但是RenderTexture执行end之后,马上执行newImage,就跟本获取不到图象,这是bug。还有楼上那货是说怎么获取坐标点的色值,跟你说的不是一回事。总之必须改核心代码,不然再用这种方法是取不到图了,因为3.0以后采用的渲染机制与之前不同了,但是3.0之后的newimage没有改(这里是槽点),翻下之后的版本看下,或者看看3.2版本中RenderTexture的saveToFile方法。

在newImage()之前end()之后加上如下代码
auto renderer = Director::getInstance()->getRenderer();
renderer->render();
这样就有图了,原理不解释,这也是无奈之举,还是希望官方做改进。希望newImage()时可以有选择性的渲染。顺带说一句,这个是3.0以后版本的问题,之前的版本没问题,因为3.0以后渲染机制变了,我使到了3.1.1仍然也是这个问题,我换上最新的3.3得CCRenderTexture.cpp中的部分代码,也是不成。

非常感谢,这个问题也纠结了我2天,共同学习!!

谢谢,可能没说到同一个问题上

像素级的事件点击的判断, 特别的耗性能。 我的解决方法是,建筑是坐在ccb里,在ccb里再设置一些node, 这些node 有大有小 ,大体上是建筑的轮廓,这样判断点击的时候,只要判断 点击点 是否在这些 node里就可以了。

我自己理解 像素级的点击 也就是 像素级 矩形的 点击判断而已。

其实你的代码效率可以提高,首先是
RenderTexture* pRender = RenderTexture::create(pSpr->getContentSize().width, pSpr->getContentSize().height, Texture2D::PixelFormat::RGBA8888);
这行修改为11像素,在此句前增加pNewSpr修改坐标为-point.x,-point.y。如下
RenderTexture
pRender = RenderTexture::create(1, 1, Texture2D::PixelFormat::RGBA8888);
这样pRender其实只渲染了1*1个像素,pRender->end()之后把pNewSpr的坐标回复过来。取点时只需要取坐标的颜色即可。而且需要及时event->stopPropagation();这样可以防止匹配后,继续判断其他精灵的触摸事件

pRender->end();
完得Director::getInstance()->getRenderer()->render()一下,
这个bug太他妈的操蛋了。当初也坑了我好久。

这个你们确定能获取到像素的alpha值???我用的是3.6的引擎,取到的值感觉都有问题。