1

没有听众参与。问题是,我可以使用MOUSE_OVERMOUSE_OUT侦听器,但是如果您将鼠标拖到 MovieClip 上的速度足够快,则其中一个侦听器可能不会被激活。我已经试过好几次了。

4

4 回答 4

11

我从来没有遇到过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 设置得尽可能高。

于 2012-08-26T20:17:21.403 回答
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..
     }
}

请注意,它取决于movieclip reg point...在这种情况下,reg point 位于movieclip 的中间。

另一种方法是hitTestObject()内置函数 with shapeFlag = true;

于 2012-08-26T20:16:55.253 回答
1

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

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

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

于 2012-08-27T07:08:03.433 回答
1

如果鼠标“足够快”地经过,那么操作系统可能首先没有将任何鼠标事件发送到屏幕的该部分的 Flash。将鼠标移动得比它的分辨率可以触发(或操作系统可以处理)快得多会产生你所看到的效果(事实是,屏幕的那部分没有处理任何鼠标事件),否则 MOUSE_OVER 肯定会触发(如果鼠标确实在影片剪辑上产生了至少一个移动事件)。

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

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

mouseLeave 事件(由舞台触发)是专门为您的问题创建的:“当指针移出舞台区域时由舞台对象调度。如果按下鼠标按钮,则不会调度该事件。” 如果它触发,你应该像 MOUSE_OUT 一样处理任何处于 MOUSE_OVER “状态”的影片剪辑(假设你有这样的状态)。如果鼠标按钮在离开舞台区域时被按下,用户可能会在某个时候释放它,而 DEACTIVATE 将在舞台上触发。

于 2012-09-29T21:37:43.533 回答