如何检查鼠标是否在MovieClip上?

时间:2012-08-26 19:30:21

标签: actionscript-3 mouseover movieclip

没有听众参与。问题是,我可以使用 MOUSE_OVER MOUSE_OUT 听众,但是如果您将鼠标快速拖到MovieClip上够了,其中一个听众可能无法激活。我已经好几次尝试了。

4 个答案:

答案 0 :(得分:10)

我从未遇到过mouseOver和mouseOut的问题。

但你可以使用hitTestPoint:

function detectMouseOver(d:DisplayObject):Boolean
{
    var mousePoint:Point = d.localToGlobal(new Point(d.mouseX,d.mouseY));
    return d.hitTestPoint(mousePoint.x,mousePoint.y,true);
}

如果您确定该属性可用并且从您调用的位置进行设置,您还可以使用stage.mouseX和stage.mouseY(而不是localToGlobal)。

我没有测试过代码,但我认为它应该可行。

(编辑)

但是如果你想要绝对确定鼠标越过一个物体 - 即使你走得太快以至于完全跳过它,你也必须检查两帧鼠标点之间的点。

这样就可以了,例如:

d.addEventListener(Event.ENTER_FRAME, checkMouseOver);

var lastPoint:Point;
const MAX_DIST:Number = 10;

function checkMouseOver(e:Event):void
{
    var isOver:Boolean = false;

    var d:DisplayObject = e.currentTarget as DisplayObject;
    var thisPoint:Point = d.localToGlobal(new Point(d.mouseX,d.mouseY))

    if (lastPoint)
    while (Point.distance(thisPoint,lastPoint) > MAX_DIST)
    {
        var diff:Point = thisPoint.subtract(lastPoint);
        diff.normalize(MAX_DIST);
        lastPoint = lastPoint.add(diff);

        if (d.hitTestPoint(lastPoint.x,lastPoint.y,true))
        {
            isOver = true;
            break;
        }
    }
    if (d.hitTestPoint(thisPoint.x,thisPoint.y,true))
    isOver = true;

    lastPoint = thisPoint;

    //do whatever you want with isOver here
}

您可以记住上次状态是否结束并在isOver!= wasOver时调度自定义事件。如果你在while循环中执行此操作,则可以获得高度准确的鼠标过度检测。

但我敢打赌,使用shapeFlag = true的hitTestPoint相当CPU重,特别是如果在一帧中使用了很多。因此,在这种情况下,您可能希望将此MAX_DIST设置为尽可能高。

答案 1 :(得分:2)

然后使用数学。

if(mouseX>mc.x-(mc.width/2) && mouseX<mc.x+(mc.width/2) && mouseY>mc.y-(mc.height/2) && mouseY<mc.y+(mc.height/2)){
     hovered = true;
     //do stuff..
}else{
     if(hovered){
           hovered=false;
           //do rollout stuff..
     }
}

请注意,它取决于动画片段注册点...在这种情况下,注册点位于动画片段的中间。

另一种方法hitTestObject()shapeFlag = true;一起构建。

答案 2 :(得分:1)

您还可以收听舞台鼠标移动并检查鼠标下的剪辑:

stage.addEventListener(MouseEvent.MOUSE_MOVE , onMouseMove);
function onMouseMove(e:MouseEvent):void {
    trace(stage.getObjectsUnderPoint(new Point(e.stageX , e.stageY)));
}

并检查您的MovieClip是否在数组内部。

答案 3 :(得分:1)

如果鼠标“足够快”通过,那么操作系统可能首先不会向屏幕的该部分发送任何鼠标事件到Flash。移动鼠标的速度比其分辨率可以发射的速度快(或操作系统可以处理)将产生您正在目击的效果(事实上,没有处理屏幕的那部分鼠标事件),否则MOUSE_OVER肯定会触发(如果鼠标确实在影片剪辑上产生了至少一个移动事件。)

但是,由于各种操作系统或浏览器安全限制,如果鼠标离开舞台区域(离开Flash),则MOUSE_OUT事件可能不会触发。

要解决此问题,请在您正在侦听MOUSE_OUT的每个Sprite / MovieClip中注册stage::flash.events.Event.DEACTIVATEstage::flash.events.Event.MOUSE_LEAVE的侦听器,重用相同的处理函数。

mouseLeave事件(由stage触发)特别针对您的问题创建:“当指针移出舞台区域时由Stage对象调度。如果按下鼠标按钮,则不调度该事件。”如果它触发,你应该像MOUSE_OUT一样处理MOUSE_OVER“状态”中的任何动画片段(假设你有这种状态)。如果在离开舞台区域时按下鼠标按钮,用户可能会在某个时刻释放它,而DEACTIVATE将在舞台上发射。