如何改进此JavaScript碰撞检测?

时间:2012-09-23 07:51:30

标签: javascript raphael collision-detection collision

我有一个测试应用程序,我使用Raphael.js在矩形之间创建了碰撞检测。

我能够让collison检测工作正常,但是我必须将它拖到懒散的地方......当我快速移动鼠标时会出现问题。看起来它的刷新速度不够快,无法检测到可拖动的矩形。

紫色方块是唯一一个拖拉的方块。

JS Fiddle

我想我的问题是如何改进检测/修复我的问题?

提前致谢。

1 个答案:

答案 0 :(得分:7)

由于move在每个像素移动时被调用,因此您没有时间在计算方式上做太多工作以保持平滑。首先,我替换了你用于确定与更标准的重叠的功能:

var rect_collision = function (x1, y1, size1, x2, y2, size2) {
  var a = {top: y1, bottom: y1+size1, left: x1, right: x1+size1};
  var b = {top: y2, bottom: y2+size2, left: x2, right: x2+size2};

  // this is the general way to figure out if two rects are overlapping
  return !(a.left >= b.right || a.right <= b.left ||                           
           a.top >= b.bottom || a.bottom <= b.top);
};

这只是检查一个矩形是否完全位于另一个矩形的左侧,右侧,顶部或底部。如果不是,那么它们必须重叠。由于这只是给出了真值或假值,我仍然需要弄清楚碰撞发生在哪一侧。

为了解决这个问题,我将碰撞分为两个组成部分:x碰撞和y碰撞,假装只改变了dx,只改变了dy 。一旦我知道哪个方向导致重叠,我就可以使用方向的变化来确定重叠发生在哪一侧。例如,如果x导致了碰撞而前一个dx大于当前dx,那么碰撞就在右侧。

  // check the x and y directions separately                                        
  var x_collide = rect_collision(r2_x, r2_y, rectSize, x, r1_y, rectSize);

  // see if we are currently overlapping
  if (!x_collide) {
    // not colliding, update our x position normally
    this.attr({x:x});
    this.pdx = dx;                          
  }
  else {
    // we are, stick the moving rect to the correct side of the stationary one
    // based on the drag direction that got us stuck
    this.attr({x: this.pdx > dx ? r2_x + rectSize + 1 : r2_x - rectSize - 1});                       
  }

然后我添加了一些额外的逻辑来匹配您所使用的功能,这些功能阻止用户直接将矩形拖过固定的矩形。基本上我最后只是看到移动是否会将移动的矩形直接放在固定矩形的另一侧,如果是这样,就防止它。

我还清理了你的边界检查,以摆脱所有的Math.min和Math.max调用,因为你并不真的需要它们。这更像是一种偏好,因为我怀疑是否会导致很多性能问题。

您可以在http://jsfiddle.net/X7H9G/3/看到结果。我不确定这是否是最佳解决方案,但它似乎可以完成这项工作。