如何通过碰撞检测拖动对象?

时间:2011-11-11 07:31:15

标签: actionscript-3

我想创建一个函数,我可以在其中拖动一个MovieClip,它将撞到舞台上的其他MovieClip而不会重叠它们。 (即不能将对象拖过或通过其他MovieClip)。

function dragHolder01(event:Event):void{
    if (mouseDownHolder01 == true) {
        for(var m:int = 0;m<blockHolder.numChildren; m++){
            var hitBlock:DisplayObject = blockHolder.getChildAt(m);
            if(movaHolder01.hitTestObject(hitBlock)){
                movaHolder01.x = movaHolder01x;
                movaHolder01.y = movaHolder01y;
                break;
            }
        }
        movaHolder01.startDrag();
        movaHolder01x = movaHolder01.x;
        movaHolder01y = movaHolder01.y;
    }
}

我想我可能有一个概念性的解决方案,但我需要你的帮助。 我想也许我可以限制“startDrag”以允许根据帧进展拖动,即玩家将无法为每个帧拖动对象超过一个像素(因此无法将对象拖入另一个不止一个像素)。

关于如何做到这一点的任何想法?

3 个答案:

答案 0 :(得分:2)

将此问题拆分为多个部分。我认为,部分是:

    左键单击
  • 对象,在其上调用startDrag()并准备好enterFrame()侦听器。
  • 每个帧上的
  • 检查拖动对象和所需场景对象之间的碰撞。
  • 假设你有碰撞。接下来是什么 - 你如何处理它?您可以将它捕捉到以前的位置 - 这样物体就会卡在最轻微的接触上。或者你可以通过一些向量移动碰撞的对象。它可能是从障碍物中心到碰撞物体中心的矢量(如果它们都很小的话。)
  • 释放左键时,调用stopDrag()。

如果您更喜欢Box2D,还有其他步骤:

  • 将您的影片剪辑变为实际形状。不要问我怎么做 - 这不会是自动的。
  • 而不是startDrag()对拖动的对象应用一些力。鼠标光标越远离物体,力就越大。 Box2D将自动解决碰撞和碰撞对象。

更新:如何存储以前的位置

var positions:Dictionary = new Dictionary();
var clip:MovieClip = ...; //load your clip somehow

//store position
position[clip] = new Point(clip.x, clip.y);

//read position
var pos:Point = position[clip];

//update position - reuses Point objects to make things somewhat faster
var pos:Point = position[clip];
pos.x = clip.x;
pos.y = clip.y;
//that's all, reference to Point is already in the Dictionary.

还有其他方法。 MovieClip不是最终类,因此可以使用以前的位置继承和扩展。它也是动态的,这意味着您只需在其上插入数据:

clip.prevX = clip.x; //prevX will be created if not exist
clip.prevY = clip.y;
//move clip

答案 1 :(得分:1)

如果你想要物理行为(也就是遇到弹跳的东西),不要自己实现它并使用物理引擎,比如Box2D。他们有几个MouseDragged对象的例子(参见Test类http://box2dflash.svn.sourceforge.net/viewvc/box2dflash/Examples/TestBed/Test.as?revision=158&content-type=text%2Fplain的MouseDrag)。

如果您只想要非重叠对象(取决于您想要的碰撞检测程度),您可以使用MovieClip.hitTest()作为碰撞检测并验证被拖动的对象(在鼠标位置)是否没有打任何东西,如果确实如此,你将它恢复到以前的位置。但请注意,鼠标可以在一个时间范围内以任何速度移动,因此如果鼠标移动得太快,拖动的对象可以通过另一个对象(您可以执行固定大小的连续插值以避免这种情况)。

物理行为和碰撞检测是严重的数学和计算机问题,不应掉以轻心。如果你想要体面的碰撞和物理行为,那么熟悉物理引擎(已经多次使用和测试和优化)比编写自己的代码来执行该行为要少得多。

如果您仍然不想使用物理引擎,请向我展示您的代码,我可能会根据您的喜好进行更多操作(可能需要一些计算时间)。

答案 2 :(得分:0)

您可能希望查看一个物理引擎,例如Box2D:http://box2dflash.sourceforge.net/