Каков предпочтительный способ обнаружения переворачивания / разворачивания мыши во Flash с AS3 - PullRequest
0 голосов
/ 04 октября 2011

Предположим, у нас есть сцена с двумя квадратами, например, так: Our example Flash stage

Предположим, мы хотели бы, чтобы желтый квадрат был изначально скрыт, и мы бы хотели, чтобы курсор мыши былвнутри границ красного квадрата - желтый квадрат будет видимым, и пока курсор мыши находится за пределами красного квадрата - желтый квадрат будет скрыт.

Интуитивный подходнаписать что-то вроде этого:

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 для квадрата RED - таким образом, запускается функция sqrOut - исчезает желтый квадрат, а когда желтого квадрата нет - курсор внезапно оказывается в пределах RED снова квадрат - так вызывается функция 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, это создает ненужные накладные расходы и циклы ЦП повторного запуска теста на попадание.Кроме того, если красный квадрат покрывает всю сцену (имеет те же размеры, что и сцена) - это создает проблемы ( не работает ).

Кто-нибудь знает о простом элегантном способе сделать это - тот, который не будет включать слишком громоздкий и длинный код и который не должен будет использовать повторяющийся таймер, который снова и снова проверяет нажатия ...?

Ответы [ 3 ]

2 голосов
/ 04 октября 2011

Поместите желтый квадрат внутри красного квадрата.

outSqr.addChild(inSqr);

Это решит ваши проблемы красиво и просто.Просто убедитесь, что outSqr является экземпляром класса Sprite или MovieClip.

1 голос
/ 04 октября 2011

Не знаю, поможет ли это в вашем случае, но вы также можете отключить действия мыши 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;
}
0 голосов
/ 04 октября 2011

самое простое решение, которое я могу себе представить :

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