0

假设我们有一个有两个正方形的舞台,如下所示: 我们的示例 Flash 阶段

假设我们希望黄色方块最初是隐藏的,并且只要鼠标光标在红色方块的边界内,我们希望这样 - 黄色方块将是可见的,并且只要鼠标光标在外面红色方块的边界 - 黄色方块将被隐藏。

直观的方法是这样写:

inSqr.visible = false;
outSqr.addEventListener (MouseEvent.ROLL_OVER,sqrOver);
outSqr.addEventListener (MouseEvent.ROLL_OUT,sqrOut);

function sqrOver(e:MouseEvent) {
    inSqr.visible = true;
}

function sqrOut (e:MouseEvent) {
    inSqr.visible = false;
}

但是,使用此代码 - 任何时候将鼠标光标移动到黄色方块内- 显然,它都算作红色方块的ROLL_OUT - 因此触发 sqrOut 函数 - 使黄色方块消失,一旦黄色方块不存在 - 光标突然再次在红色方块的范围内 - 所以调用了 sqrOver 函数 - 恢复黄色方块的可见性 - 触发 sqrOut 等等,因此当鼠标光标在他身上:黄色方块消失并一遍又一遍地再次出现。

一个可能的“修复”是在光标位于黄色内部时移除红色滚动事件的侦听器(如果它在黄色内部,它肯定也在红色内部),并在它出来时将其带回来,通过将其添加到上面的代码中:

 inSqr.addEventListener (MouseEvent.ROLL_OVER,insqrOver);
 inSqr.addEventListener (MouseEvent.ROLL_OUT,insqrOut);
 function insqrOver(e:MouseEvent) {
     if (outSqr.hasEventListener (MouseEvent.ROLL_OUT)) {
         outSqr.removeEventListener(MouseEvent.ROLL_OUT,sqrOut);
     }
     inSqr.visible = true;
 }
 function insqrOut(e:MouseEvent) {
     if (!outSqr.hasEventListener (MouseEvent.ROLL_OUT)) {
         outSqr.addEventListener(MouseEvent.ROLL_OUT,sqrOut);
     }
 }

这行得通。但这很麻烦。您必须为红色方块范围内的每个对象执行此操作 - 导致代码长、事件侦听器和持续的侦听器注册和注销。


几年前有人向我建议了这种技术:

 outSqr.addEventListener (Event.ENTER_FRAME,hoverCheck);

 function hoverCheck (e:Event) {
     if (e.currentTarget.hitTestPoint(stage.mouseX,stage.mouseY,true)) {
         inSqr.visible = true;
     }
     else {
         inSqr.visible = false;
     }
 }

这是一个有效的简单短代码。但是,如果您的项目真的不需要使用 ENTER_FRAME 事件,它会产生不必要的开销和重复运行命中测试的 CPU 周期。此外,如果红色方块覆盖整个舞台(与舞台具有相同的尺寸) - 它会产生问题(它不起作用)。


有没有人知道一种简单而优雅的方法来实现这一点 - 一种不会涉及太繁琐和冗长的代码,并且不必使用重复的计时器来一遍又一遍地进行命中测试......?

4

3 回答 3

2

把黄色方块放在红色方块里面。

outSqr.addChild(inSqr);

这将很好而简单地解决您的问题。只要确保 outSqr 是SpriteorMovieClip类的一个实例。

于 2011-10-03T23:22:29.143 回答
1

我不知道这对您的情况是否有帮助,但您也可以禁用 inSqr 的鼠标操作,然后您可以将鼠标悬停在不会触发 ROLL_OUT 的黄色方块上

inSqr.mouseEnabled = false

..那么你可以使用这个:

inSqr.visible = false;
outSqr.addEventListener (MouseEvent.ROLL_OVER,sqrOver);
outSqr.addEventListener (MouseEvent.ROLL_OUT,sqrOut);

function sqrOver(e:MouseEvent) {
    inSqr.visible = true;
}

function sqrOut (e:MouseEvent) {
    inSqr.visible = false;
}
于 2011-10-04T13:16:55.200 回答
0

我能想象的最简单的解决方案

package {
    import flash.events.MouseEvent;
    import flash.display.Sprite;
    public class FlashTest extends Sprite {
        private var inner:Sprite;
        private var outer:Sprite;
        public function FlashTest() {
            outer = giveRect(200, 200, 0xff0000);
            addChild(outer);
            inner = giveRect(50, 50, 0xffff00);
            addChild(inner);
            inner.x = inner.y = 75;
            stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);       
        }

        private function giveRect(w:int, h:int, color:int):Sprite{
            var spr:Sprite =  new Sprite();
            spr.graphics.beginFill(color);
            spr.graphics.drawRect(0, 0, w, h);
            spr.graphics.endFill();
            return spr;            
        }

        private function onMove(e:MouseEvent):void{
            inner.visible = stage.mouseX > outer.x &&
                            stage.mouseX < outer.x + outer.width &&
                            stage.mouseY > outer.y &&
                            stage.mouseY < outer.y + outer.height;
        }
    }
}
于 2011-10-04T09:06:29.400 回答