【已解决】不规则sprite的触摸事件问题

主流处理触摸事件的方法都是用 sprite->getBoundingBox().containsPoint(),

可是BoundingBox都是横平竖直的Rect,我想触摸一个三角形啊,斜着的长条啊,圆环啊之类的东东, 该怎么办呢:778:

解决方法见4L,虽然也是我写的Orz

星期天早晨起来突然发现这个方法不能对sprite进行旋转,放缩和其他改变形状的操作,更完整的解决方法还得继续研究……

你可以看ccimage里的getdata 里面有方法像素级判断是否透明 不过效率比较低 要自己实现

果然没有现成的方法了:12:
有空研究下像素级,暂时只能先做些横平竖直的sprite了

不过对于一些不是非常复杂的图形,如果采用平面几何的方法不知道和像素级相比效率怎么样?比如圆环:判断点是否在外圆内、内圆外 (不过从来没试过这方面,高数也忘光了Orz)
呃,不过这样对每个sprite貌似都要有单独的判断方法,编码难度好像很大……

如果是几何规则的图形,用几何方法绝对效率。但是你想通用,肯定是用像素去判断。之前做个一个接口就是像素判断,效率什么的完全没问题,就是用ccimage里的getdata 做一下处理。

经过饭后三个多小时的努力,像素判断终于被我实现了哇哈哈:14: 而且效率还是常数级哦 ,突然对cocos2dx有了好深一层的理解啊:2: 忍不住要申请加精华啊:908:

下面是实现:

/*  这个实现只是一个思路,真正要用的时候还是会将它实现在触摸对象node中,再加上各种需要的属性  */
void HelloWorld::test(Point touchLocation)  //传入触摸点touchLocation
{
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Point origin = Director::getInstance()->getVisibleOrigin();
    //计算touchLocation相对于mysprite的boundingBox左下角的坐标, 因为一般的锚点都在sprite中心,所以加了半个ContentSize
    auto ps = touchLocation - mysprite->getPosition() + Point(mysprite->getContentSize().width / 2, mysprite->getContentSize().height / 2);
    //加载和mysprite相同的图片,我是实现的png的,alpha通道很好用
    Image *myImage = new Image();
    myImage->initWithImageFile("test.png");
    unsigned char *data = myImage->getData();  //这里就是图片数据了
    //根据刚刚计算的相对坐标值,计算出触摸点代表了哪一个像素点      然后再提取出该像素点的alpha值
    //注意:因为图片坐标(0,0)是在左上角,所以要和触摸点的Y转换一下,也就是“(myImage->getHeight() - (int)(ps.y) - 1)”
    int pa = 4 * ((myImage->getHeight() - (int)(ps.y) - 1) * myImage->getWidth() + (int)(ps.x)) + 3;
    unsigned int ap = data;
    //判断alpha值不为零时,也就是触摸在了不规则sprite的有图像的地方,这时再处理需要的逻辑内容就好了
    if (ap != 0)
    {
        CCLOG("check");
    }
}


```



这个方法的出发条件仍然是触摸点在boundingBox内

bool HelloWorld::onTouchBegan(Touch *touch, Event *event)
{
    Point touchLocation = this->convertTouchToNodeSpace(touch);
    if (mysprite->getBoundingBox().containsPoint(touchLocation))
    {
        this->test(touchLocation);
    }
    return true;
}


```

此贴应该加精!!方法可以用 不规则图形的碰撞 引擎里应该也做个解决方案! 有的类型的游戏 还是需要的!

Image *myImage = new Image();
myImage->initWithImageFile("test.png");
unsigned char *data = myImage->getData();  //这里就是图片数据了

这里是否每次判断都要创建一个image, 无论这个texture之前是否已经加载到内存了,对于使用texture packer 打包的文件就更浪费内存了,取图片数据时候也还要计算sprite在图片的哪个位置,有没有方法直接取到sprite的texture里的data数据

现在想想,当初只为了解决这个问题去考虑,也没考虑到打包,想出来的这个方法确实没什么可行性……连我自己也不打算用了 :12:
还是应该像你说的那样从直接取数据的方向考虑

最近也在研究这个问题,没找到从texture或者spriteFrame获得数据的方法,现在的方向还是使用renderTexture, 只画所需测试的sprite,然后使用opnegl读取所需测试位置的rgba值来判断,如果对opengl熟悉或者对引擎的渲染逻辑比较熟的话确实能解决这个问题,而且也挺快,类似网上介绍的2.x版本的使用renderTexture方法,只是3.2的用起来挺坑的

3.2怎么解决?

LZ怎么解决的?我现在在做一个世界地图,都是不规则图形,策划要求是点哪块区域,就进哪张地图。

如果就是一个地方用的话。。。 可以考虑网格法 。。。 画一个2维数组(看精度)。。 某个地方能点 就把2维数组的位置设置为1

3.x版本因为渲染和逻辑代码分离导致直接将2.x版本的renderTexture像素处理代码拿过来是用不了的,不过rendertexture
使用的是CustonCommond,可以给个callback函数,在这个callback函数里面进行逻辑处理。

请问 我用了你的方法,为什么出现卡顿的情况