cocos2d-x 精灵的多边形精确触摸
2016-06-10 本文已影响0人
xuanhr
在cocos2d-x中,精灵的触摸一般都是用sprite的rect判断。这是一个矩形范围,一般判断按钮和一些规则性的精灵是足够使用了。但是要实现精确触摸那就是不够的。
要实现精确触摸可以使用cocos2dx物理引擎中的精确碰撞检测。
而我选择用另一种方法,判断点向左的射线和多边形相交的点有几个。
如果是奇数则点在多边形中,如果是偶数(包括0)点就不在多边形中。
童鞋们可以在纸上画一画需要的多边形是否和点的多种情况,看看是否是这样的。
然后直接上代码,使用了两个静态方法。onLine方法是判断点是否正好是在多边形的边上,调用就直接使用pointInPolygon就可以了,三个参数分别是1传入点的数组2触摸的点3多边形有多少条边。
#define POLYGON_EPS 1.0e-5
bool MapEdit::onLine(const Point & p1, const Point & p2, const Point & p3) {
using namespace std;
if (p2.x >= min(p1.x, p3.x) && p2.x <= max(p1.x, p3.x)
&& p2.y >= min(p1.y, p3.y) && p2.y <= max(p1.y, p3.y)) {
if (fabs((p2.x - p1.x)*(p3.y - p1.y) - (p3.x - p1.x)*(p2.y - p1.y)) <= POLYGON_EPS)
return true;
}
return false;
}
bool MapEdit::pointInPolygon(const Point * poly,Point p,int count) {
using namespace std;
int counter = 0;
double xinters;
Point p1, p2;
p1 = poly[0];
for (int i = 1;i <= count;i++) {
p2 = poly[i%count];
if (MapEdit::onLine(p1, p, p2)) {
log("----touch in polygon");
return true;
}
if (p.y > min(p1.y, p2.y)) {
if (p.y <= max(p1.y, p2.y)) {
if (p.x <= max(p1.x, p2.x)) {
if (p1.y != p2.y) {
xinters = (p.y - p1.y)*(p2.x - p1.x) / (p2.y - p1.y) + p1.x;
if (p1.x == p2.x || p.x <= xinters) counter++;
}
}
}
}
p1 = p2;
}
if (counter % 2 == 0)
return false;
log("----touch in polygon");
return true;
}