如何在一组Div元素之间实现碰撞检测?

时间:2011-12-25 05:31:45

标签: jquery collision-detection

我在jsfiddle

中有这个例子

我有一个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');但我不确定如何在此示例中使用它。

1 个答案:

答案 0 :(得分:8)

完整的collision detection和正确的collision response不是一个需要解决的小问题,除非是特殊情况。

您现在拥有的代码相当容易编写,因为您只有两个要比较的对象(拖动的对象和容器),并且因为您的碰撞响应只是将div的位置限制在容器内。

对于所有div的完全碰撞,你必须检查拖动的div对容器和所有其他div。您的碰撞响应必须计算运动矢量,并处理复杂的“滑动”逻辑以确保您可以移动其他对象,但确保您的最终位置仍然在容器内。

我建议你首先重新检查你对完全碰撞检测的需求,因为它可能很重且很复杂。也许你只需要overlap detection,ala jQuery UI的droppable?或者你可能需要像jQuery UI draggable snapping或jQuery UI sortable这样的东西?

如果你确定你确实需要完全碰撞检测,我建议你抓一个已经处理碰撞检测的库,因为它很难实现。有关一些库选项,请参阅此问题的答案:

如果你真的想自己实现它,你应该查找分离轴定理:

然后我会阅读有关实施碰撞检测和响应的文章,如the N game所示:

如果您需要搜索更多信息,可以将div视为Axis-Aligned Bounding BoxesAABB s)。这可以为您带来巨大的性能提升和巨大的复杂性降低。检查AABB到 - AABB碰撞的数学运算与重叠和碰撞检测一样简单(尽管碰撞响应仍然与任何其他类型的碰撞一样困难)。