Actionscript 3 AS3-检测您是否在未按下鼠标按钮的情况下单击对象

Actionscript 3 AS3-检测您是否在未按下鼠标按钮的情况下单击对象,actionscript-3,object,click,point,hittest,Actionscript 3,Object,Click,Point,Hittest,好的,在as3中,当您单击时,最高层上的对象将被单击。我希望有人按下空格键,让屏幕上的对象检查它是否接触到一个点 所以我首先尝试了hittest 如果(此.hitTest(myPoint)){ play(); } 现在的问题是,其他对象后面的对象认为它们被“点击”了 然后,在感到沮丧之后,我使用谷歌,找不到任何东西,所以请提供任何帮助。问得好。。我会四处看看,但现在我所能想到的就是拥有一个包含所有对象的数组(以与显示列表相同的顺序添加),然后向后迭代以找到第一个冲突 (对于这个非常懒惰的例子,我

好的,在as3中,当您单击时,最高层上的对象将被单击。我希望有人按下空格键,让屏幕上的对象检查它是否接触到一个点

所以我首先尝试了hittest

如果(此.hitTest(myPoint)){ play(); }

现在的问题是,其他对象后面的对象认为它们被“点击”了


然后,在感到沮丧之后,我使用谷歌,找不到任何东西,所以请提供任何帮助。

问得好。。我会四处看看,但现在我所能想到的就是拥有一个包含所有对象的数组(以与显示列表相同的顺序添加),然后向后迭代以找到第一个冲突

(对于这个非常懒惰的例子,我很抱歉):


找到的第一个DisplayObject将是DisplayList中最高的。

这是一个很好的问题,我没有现成的编码解决方案。当你把它作为MouseeEvent目标免费获得时,你会想当然地认为前台的哪些东西会被点击。简单的部分是设置所有显示对象,以侦听与按下空格键对应的键盘事件,并在此时使用鼠标位置点击test

在我看来,你剩下的问题,真正的问题,似乎可以归结为你需要做出的一个决定:A和B占据相同的屏幕空间,哪个在前面。换句话说,一旦你有了一个命中测试的所有显示对象的列表,你需要这个比较函数来前后排序。以下是我如何看待这一点:

要确定DisplayObject A是在DisplayObject B的前面还是后面,您需要追溯他们的显示列表祖先到他们的共同祖先,然后再往下看下一代,看看在他们祖先的分歧点上,对象A的祖先是在对象B的前面还是后面(即它们在共同祖先容器中的相对深度)考虑这样的显示树:

       E
      / \
     C   D
    /     \
   A       B
E是公共祖先。要确定A是否在B之后,您需要检查C是否在D之后,这意味着您需要检查E容器中C和D的深度(使用DisplayObjectContainer.getChildIndex(child))。显然,在复杂的UI中,公共祖先可以追溯到很多代,但即使是在后台,也总会有一个

编辑:


我怎么会忽略这个明显的问题?!你不想点击鼠标按钮,但没有说你根本不能使用MouseEvents,对吗?使用ROLL\u OVER或mouse\u OVER事件来跟踪你滚动的内容,并用该对象进行hitTest[羞愧地拍打额头]。

我想这就是你要寻找的代码:

stage.addEventListener(KeyboardEvent.KEY_DOWN, function(e : KeyboardEvent) : void {
    if(e.keyCode == Keyboard.SPACE) {
        var objects : Array = stage.getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
        if (objects.length > 0) {
            var topmost : DisplayObject = objects[objects.length-1];
            trace(topmost.name);
        }
    }
});
关键是flash的方法

请注意
getObjectsUnderPoint
不会返回DisplayObjectContainers,如下所示:

var mc:MovieClip = new MovieClip();
var shape:Shape = new Shape();
    shape.graphics.beginFill(0);
    shape.graphics.drawRect(0,0,5,5);
mc.addChild(shape);
var shape2:Shape = new Shape();
    shape2.graphics.beginFill(0);
    shape2.graphics.drawRect(0,0,5,5);
mc.addChild(shape2);
addChild(mc);
getObjectsUnderPoint(new Point(1,1)); // returns [object Shape],[object Shape]
您可以使用返回的DisplayObjects的
parent
属性来查找DisplayObjectContainer

var containerBeingLocated:Sprite;

for each (var obj:DisplayObject in objectsUnderPoint) {
    if (isWithin(obj, containerBeingLocated)) {
        trace('container located');
    }
}

function isWithin ($obj:DisplayObject, $container:DisplayObjectContainer):Boolean {
    while ($obj) {
        if ($obj === $container) {
            return true;
        } else {
            $obj = $obj.parent;
        }
    }
    return false;
}

在那些不相关的对象上禁用鼠标事件会有帮助吗?
mouseEnabled=false
并且可能
mouseChildren=false
我也这么认为,但我不确定问题是否表明点始终在鼠标位置。事实上,我不清楚“点”是否在问题是鼠标的位置,或者是任意点。显然,只有当我们谈论鼠标下的东西,并且像使用鼠标按钮一样使用空格键时,滚动方法才有效。是的,想法不错。+1
var mc:MovieClip = new MovieClip();
var shape:Shape = new Shape();
    shape.graphics.beginFill(0);
    shape.graphics.drawRect(0,0,5,5);
mc.addChild(shape);
var shape2:Shape = new Shape();
    shape2.graphics.beginFill(0);
    shape2.graphics.drawRect(0,0,5,5);
mc.addChild(shape2);
addChild(mc);
getObjectsUnderPoint(new Point(1,1)); // returns [object Shape],[object Shape]
var containerBeingLocated:Sprite;

for each (var obj:DisplayObject in objectsUnderPoint) {
    if (isWithin(obj, containerBeingLocated)) {
        trace('container located');
    }
}

function isWithin ($obj:DisplayObject, $container:DisplayObjectContainer):Boolean {
    while ($obj) {
        if ($obj === $container) {
            return true;
        } else {
            $obj = $obj.parent;
        }
    }
    return false;
}