没有听众参与。问题是,我可以使用MOUSE_OVER和MOUSE_OUT侦听器,但是如果您将鼠标拖到 MovieClip 上的速度足够快,则其中一个侦听器可能不会被激活。我已经试过好几次了。
4 回答
我从来没有遇到过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 设置得尽可能高。
那就用数学吧。
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;
。
您还可以收听舞台鼠标移动并检查鼠标下的剪辑:
stage.addEventListener(MouseEvent.MOUSE_MOVE , onMouseMove);
function onMouseMove(e:MouseEvent):void {
trace(stage.getObjectsUnderPoint(new Point(e.stageX , e.stageY)));
}
并检查您的 MovieClip 是否在数组中。
如果鼠标“足够快”地经过,那么操作系统可能首先没有将任何鼠标事件发送到屏幕的该部分的 Flash。将鼠标移动得比它的分辨率可以触发(或操作系统可以处理)快得多会产生你所看到的效果(事实是,屏幕的那部分没有处理任何鼠标事件),否则 MOUSE_OVER 肯定会触发(如果鼠标确实在影片剪辑上产生了至少一个移动事件)。
但是,由于各种操作系统或浏览器的安全限制,如果鼠标离开舞台区域(离开 Flash),则MOUSE_OUT 事件可能不会触发。
要解决此问题,请为stage::flash.events.Event.DEACTIVATE和stage::flash.events.Event.MOUSE_LEAVE注册侦听器,在每个 Sprite/MovieClip 中,您也在侦听 MOUSE_OUT,重用相同的处理函数。
mouseLeave 事件(由舞台触发)是专门为您的问题创建的:“当指针移出舞台区域时由舞台对象调度。如果按下鼠标按钮,则不会调度该事件。” 如果它触发,你应该像 MOUSE_OUT 一样处理任何处于 MOUSE_OVER “状态”的影片剪辑(假设你有这样的状态)。如果鼠标按钮在离开舞台区域时被按下,用户可能会在某个时候释放它,而 DEACTIVATE 将在舞台上触发。