cocos2d-x 精灵的多边形精确触摸

在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;
}

你可能感兴趣的:(cocos2d-x 精灵的多边形精确触摸)