Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/actionscript-3/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Actionscript 3 如何检查鼠标是否在MovieClip上?_Actionscript 3_Mouseover_Movieclip - Fatal编程技术网

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

Actionscript 3 如何检查鼠标是否在MovieClip上?,actionscript-3,mouseover,movieclip,Actionscript 3,Mouseover,Movieclip,不涉及任何侦听器。问题是,我可以使用鼠标悬停和鼠标悬停侦听器,但如果您将鼠标足够快地拖动到MovieClip上,其中一个侦听器可能无法激活。我已经试过好几次了。那就用数学吧。 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)){ hover

不涉及任何侦听器。问题是,我可以使用鼠标悬停鼠标悬停侦听器,但如果您将鼠标足够快地拖动到MovieClip上,其中一个侦听器可能无法激活。我已经试过好几次了。

那就用数学吧。

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..
     }
}
if(mouseX>mc.x-(mc.width/2)和&mouseXmc.y-(mc.height/2)和&mouseY则使用数学。

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..
     }
}

if(mouseX>mc.x-(mc.width/2)和&mouseXmc.y-(mc.height/2)和&mouseY

但您可以使用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!=已结束时发送自定义事件。如果在while循环中执行此操作,您将获得高度准确的鼠标悬停检测


但我敢打赌shapeFlag=true的hitTestPoint占用了相当多的CPU,尤其是在一个帧中大量使用时。因此,在这种情况下,您可能希望将此最大距离设置为尽可能高的值。

我从未遇到过鼠标悬停和鼠标悬停的问题

但您可以使用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!=已结束时发送自定义事件。如果在while循环中执行此操作,您将获得高度准确的鼠标悬停检测


但我敢打赌shapeFlag=true的hitTestPoint占用了相当多的CPU,尤其是在一帧中大量使用的情况下。因此,在这种情况下,您可能希望将此最大距离设置为尽可能高。

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

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

并检查您的MovieClip是否位于阵列内。

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

stage.addEventListener(MouseEvent.MOUSE_MOVE , onMouseMove);
function onMouseMove(e:MouseEvent):void {
    trace(stage.getObjectsUnderPoint(new Point(e.stageX , e.stageY)));
}
并检查您的MovieClip是否在阵列中。

如果鼠标“足够快”通过,那么首先可能是操作系统没有发送任何鼠标事件来闪烁屏幕的该部分。移动鼠标的速度远远快于其分辨率可以触发(或操作系统可以处理)将产生您看到的效果(事实是,屏幕的这一部分没有处理鼠标事件),否则肯定会触发鼠标悬停(如果鼠标确实在电影剪辑上生成了至少一个移动事件)

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

要解决这个问题,请为每个Sprite/MovieClip注册侦听器,并且在每个Sprite/MovieClip中,您也在侦听MOUSE\u OUT,重用相同的处理程序函数

mouseLeave事件(由stage触发)是专门为您的问题创建的:“当指针移出stage区域时,由stage对象发送。如果按下鼠标按钮,则事件不会被发送。”如果它触发,您应该像在“状态”上对任何movieclip执行mouse\u out一样处理它(假设您有这样的状态)。如果鼠标按钮在离开舞台区域时被按下,用户可能会在某个点释放鼠标按钮,然后将在舞台上触发。

如果鼠标“足够快”通过舞台那么,首先,操作系统可能没有发送任何鼠标事件来闪烁屏幕的那一部分。移动鼠标的速度远远快于它的分辨率(或者操作系统可以处理)会产生你正在看到的效果(事实是,没有为屏幕的那一部分处理鼠标事件),否则肯定会触发鼠标悬停(如果鼠标确实在电影剪辑上生成了至少一个移动事件)

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

要解决这个问题,请为每个Sprite/MovieClip注册侦听器,并且在每个Sprite/MovieClip中,您也在侦听MOUSE\u OUT,重用相同的处理程序函数


mouseLeave事件(由stage触发)是专门为您的问题创建的:“当指针移出stage区域时,由stage对象发送。如果按下鼠标按钮,则事件不会被发送。”如果它触发,您应该像在“状态”上对任何movieclip执行mouse\u out一样处理它(假设您有这样的状态)。如果鼠标按钮在离开舞台区域时被按下,用户可能会在某个点释放鼠标按钮,然后在舞台上触发。

或者是的,hitTest point是另一种我不认为的方式。:)如果你需要的话,它的优点是像素检测。最好的解决方案实际上取决于这种检测应该用于什么/on。或者是的,hitTest point是我不认为的另一种方式。:)如果需要的话,其优点是像素检测。最佳解决方案实际上取决于此检测应用于什么/on。这仅在形状为矩形时有效。此外,您能否更具体地说明此
hitTestObject()
function?仅当形状为矩形时,此功能才起作用。此外,您能否更具体地说明此
hitTestObject()
函数?正如一些评论员所指出的,最好的解决方案是