我有一个测试应用程序,我正在使用 Raphael.js 在矩形之间创建碰撞检测。
我能够让碰撞检测正常工作,但我必须慢慢拖动它......当我移动鼠标太快时会出现问题。似乎刷新速度不够快,无法检测到可拖动的矩形。
紫色方块是唯一拖拽的方块。
我想我的问题是如何改进检测/解决我的问题?
提前致谢。
我有一个测试应用程序,我正在使用 Raphael.js 在矩形之间创建碰撞检测。
我能够让碰撞检测正常工作,但我必须慢慢拖动它......当我移动鼠标太快时会出现问题。似乎刷新速度不够快,无法检测到可拖动的矩形。
紫色方块是唯一拖拽的方块。
我想我的问题是如何改进检测/解决我的问题?
提前致谢。
由于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});
}
I then added a little bit of extra logic to match the functionality that you had which prevent the user from dragging the rectangle directly through the stationary one. Basically I ended up just seeing if the move would place the moving rectangle directly on the opposite side of the stationary one, and if so, prevent it.
I also cleaned up your checks for the border to get rid of all of the Math.min and Math.max calls since you didn't really need those. That's more of a preference thing though since I doubt there were causing much of the performance issues.
You can see the results at http://jsfiddle.net/X7H9G/3/. I'm not sure if this is the best solution, but it seems to do the job.