我有一个var作为碰撞元素:
var $div = $('.container');
然后碰撞:
function test (){ $('.drag') .drag("start",function( ev,dd ){ dd.limit = $div.offset(); dd.limit.bottom = dd.limit.top + $div.outerHeight() - $( this ).outerHeight(); dd.limit.right = dd.limit.left + $div.outerWidth() - $( this ).outerWidth(); }) .drag(function( ev,dd ){ $( this ).css({ top: Math.min( dd.limit.bottom,Math.max( dd.limit.top,dd.offsetY ) ),left: Math.min( dd.limit.right,Math.max( dd.limit.left,dd.offsetX ) ) }); }); }
对于:
<div class="container"></div> <div class="drag xxx" style="left:40px;"></div> <div class="drag xxx" style="left:120px;"></div> <div class="drag xxx" style="left:200px;"></div>
此代码实现了子div与容器div的冲突检测.如何实现碰撞检测以使这3个div相互冲突?
我正在考虑设置另一个div:var $divs = $(‘.xxx’);但我不知道如何在这个例子中使用它.
解决方法
您现在拥有的代码相当容易编写,因为您只有两个要比较的对象(拖动的对象和容器),并且因为您的碰撞响应只是将div的位置限制在容器内.
要完全碰撞所有div,你必须检查拖动的div对容器和所有其他div.您的碰撞响应必须计算运动矢量,并处理复杂的“滑动”逻辑以确保您可以移动其他对象,但确保您的最终位置仍然在容器内.
我建议你首先重新检查你对完全碰撞检测的需求,因为它可能很重且很复杂.也许你只需要overlap detection,ala jQuery UI的droppable
?或者你可能需要jQuery UI的draggable
snapping或jQuery UI的sortable
?
如果你确定你确实需要完全碰撞检测,我建议你抓一个已经处理碰撞检测的库,因为它很难实现.有关一些库选项,请参阅此问题的答案:
> Please recommend a JQuery plugin that handles collision detection for draggable elements
如果你真的想自己实现它,你应该查找Separating Axis定理:
> http://en.wikipedia.org/wiki/Separating_axis_theorem
然后,我将阅读有关实现碰撞检测和响应的文章,如the N
game所示:
> http://www.metanetsoftware.com/technique/tutorialA.html
> http://www.metanetsoftware.com/technique/tutorialB.html
如果您需要搜索更多信息,可以将div视为Axis-Aligned Bounding Boxes
(AABB).这可以为您带来巨大的性能提升和巨大的复杂性降低.检查AABB到AABB碰撞的数学运算与重叠和碰撞检测一样容易(尽管碰撞响应仍然与任何其他类型的碰撞一样难).