Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Форсированный MOUSE_OVER (http://www.flasher.ru/forum/showthread.php?t=205192)

Fogflasher 23.11.2013 01:20

Форсированный MOUSE_OVER
 
Есть контейнер для мувиклипов, и две кнопки: B1, B2.
На каждую кнопку повешены три листенера: MOUSE_OVER, MOUSE_OUT, и CLICK.

Нажатие на кнопку запускает проигрывание соответствующего ей мувиклипа: M1 или M2.
Также, есть следующая специфика: пока клип не завершен, текущая кнопка имеет статус нажатости.
То есть текущая кнопка маркируется цветом, и временно отключены все листенеры (интерфейс какбы заморожен).

После того как клип проигрался, маркировка отключается, кнопкам возвращается изначальный функционал.

И вот тут возникает один ньюанс...
После того как функционал возвращен, курсор мыши находится, как правило, над кнопкой.
Но событие MOUSE_OVER не срабатывает, до тех пор, пока курсор не убран с кнопки, и не возвращен обратно.

Каким образом можно сделать так, чтобы по завершению проигрывания клипа происходила проверка:
"Если курсор мыши находится над кнопкой - включить обработчик повешенный на MOUSE_OVER"?

alexandrratush 23.11.2013 01:33

Вот такое решение подойдет?
Код AS3:

B1.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_OVER));


Wolsh 23.11.2013 02:02

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

Fogflasher 23.11.2013 15:39

alexandrratush, Идея генерации системного события интересна.
Как-то сразу не догадался, правда подозревал, что можно сгенерировать кастомное событие.
Однако тут есть проблема: Как узнать, над какой кнопкой зависла мышка?
В вашем примере над B1, но это может быть и B2. Кнопок может быть и штук 10, например.

Wolsh, Хмм... не думал что hitTestObject() можно использовать по отношению к курсору мыши.
Мне правда еще не приходилось на практике с этой темой работать. Да, кстати, а может быть вы имеете ввиду hitTestPoint() ?
Глянул в хэлпе, там про мышь ничего не сказано. Речь идет о "данном объекте", но как указать что это мышь, покамест не соображу.

Mkey 23.11.2013 15:48

Координаты мыши же вам известны. Не уж то размеры кнопок и их координаты вам не известны?

Fogflasher 24.11.2013 04:36

Mkey, Если запускать событие маркировки по условию:
Код AS3:

if (B1.hitTestPoint(mouseX, mouseY) == true)

то условие не срабатывает, так как trace выдает нулевые координаты для B1.

Похоже, это потому, что кнопки находятся в контейнере. А он еще в одном контейнере.
Координаты B1 по отношению к своему контейнеру, это, как я понимаю, точка регистрации, то есть: x = 0, y = 0.
Координаты контейнера по отношению к суперконтейнеру известны из библиотеки (режим редактирования).
Суперконтейнер помещается "на стейдж", но со смещением (лол).

Выходит, hitTestPoint работает по относительным координатам, а не по абсолютным, что странно...

Значит, есть как минимум три варианта:

1. Заставить метод работать в абсолютных координатах... но это наверное невозможно.

2. Использовать матрицы пересчета, упоминание которых приходилось видеть в других камментах.

3. Вводить в хиттест поправки на смещения, ну например:
Код AS3:

B1.hitTestPoint(mouseX + coordExpression1, mouseY + coordExpression2);

Сейчас попробую реализовать по второму варианту...
Если это то, что все делают в подобных случаях - было бы приятно это услышать.
А то может быть это избыточный, "хардкодный" подход.

Wolsh 24.11.2013 04:48

А так не устраивает?
Код AS3:

if (B1.hitTestPoint(B1.mouseX, B1.mouseY))

Добавлено через 3 минуты
Цитата:

1. Заставить метод работать в абсолютных координатах... но это наверное невозможно.
DisplayObject#localToGlobal(),
DisplayObject#globalToLocal() вообще-то.

Fogflasher 25.11.2013 02:15

Вложений: 1
Wolsh,
Цитата:

DisplayObject#localToGlobal(),
DisplayObject#globalToLocal() вообще-то.
С этими функциями всё получилось, грациас!

Выяснилось также, что экземпляр класса, в котором написан код, под mouseX и mouseY подразумевает локальные координаты текущего экземпляра. Поэтому пришлось переводить координаты мыши внутри этого класса функцией localToGlobal().

А вот задумку этого кода,
Код AS3:

if (B1.hitTestPoint(B1.mouseX, B1.mouseY))

я что-то не могу до конца понять.

То есть: "Если для объекта B1 относительные координаты мыши по шкале этого объекта находятся внутри этого объекта"...
Бжжж, как-то это слишком wolshэбно ))

Написал даже отдельный пример, вот такой:
Код AS3:

package
{
 
        import flash.display.Sprite;
        import flash.events.MouseEvent;
        import flash.text.TextField;
        import flash.text.TextFieldAutoSize;
        import flash.text.TextFormat;
        import flash.geom.Point;
 
 
        public class LocalToGlobal extends Sprite
        {
 
                private var square:Sprite = new Sprite();
                private var container:Sprite = new Sprite();
                private var infoPanel:TextField;
                private var statusPanel:TextField;
                private var format1 = new TextFormat();
                private var format2 = new TextFormat();
 
                public function LocalToGlobal()
                {
                        //--- Sprite: container ---//
                        container.graphics.beginFill(0x00CCFF);
                        container.graphics.drawRect(0, 0, 300, 300);
                        container.x = 50;
                        container.y = 50;
                        addChild(container);
 
                        //--- Sprite: square ---//
                        square.graphics.beginFill(0xFFCC00);
                        square.graphics.drawRect(0, 0, 100, 100);
                        square.x = 50;
                        square.y = 50;
                        container.addChild(square);
 
                        //--- TextField: infoPanel ---//
                        format1.color = 0x663366;
                        format1.bold = true;
                        format1.font = "Verdana";
                        format1.size = 12;
                        infoPanel = new TextField();
                        infoPanel.defaultTextFormat = format1;
                        infoPanel.x = 100;
                        infoPanel.y = 300;
                        infoPanel.autoSize = TextFieldAutoSize.LEFT;
                        infoPanel.text = "Waiting for mouse move...";
                        addChild(infoPanel);
 
                        //--- TextField: statusPanel ---//
                        format2.color = 0x336666;
                        format2.bold = true;
                        format2.font = "Verdana";
                        format2.size = 12;
                        statusPanel = new TextField();
                        statusPanel.defaultTextFormat = format2;
                        statusPanel.x = 50;
                        statusPanel.y = 30;
                        statusPanel.autoSize = TextFieldAutoSize.LEFT;
                        statusPanel.text = "Waiting for mouse move...";
                        addChild(statusPanel);
 
                        //--- Mouse Listeners ---//
                        square.addEventListener(MouseEvent.CLICK, traceCoordinates)
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, showCoordinates)
 
                }
 
                private function showCoordinates(event:MouseEvent):void
                {
                        infoPanel.text = " square.mouseX = " + square.mouseX + "\n square.mouseY = " + square.mouseY;
 
                        if (square.hitTestPoint(square.mouseX, square.mouseY) == true)
                        {
                                statusPanel.text = "MOUSE INSIDE!";
                        }
                        else
                        {
                                statusPanel.text = "Mouse outside... " + square.hitTestPoint(square.mouseX, square.mouseY);
                        }
                }
 
                private function traceCoordinates(event:MouseEvent):void
                {
                        var clickPoint:Point = new Point(square.mouseX, square.mouseY);
                        trace("display object coordinates:", clickPoint);
                        trace("stage coordinates:", square.localToGlobal(clickPoint));
                }
 
        }
 
}

localToGlobal.swf   (1.1 Кб)


Видим, что хиттест не срабатывает для самого объекта, но срабатывает для области, где объекта нет.
А вот если заменить square.mouseX, square.mouseY на просто mouseX и mouseY, то работает правильно.

Wolsh 25.11.2013 03:12

Забавно, не правда ли?
Цитата:

Mkey, Если запускать событие маркировки по условию:
if (B1.hitTestPoint(mouseX, mouseY) == true)
то условие не срабатывает
Цитата:

А вот если заменить square.mouseX, square.mouseY на просто mouseX и mouseY, то работает правильно.
Вы понимаете, что "mouseX" и "mouseY" это this.mouseX и this.mouseY, и результат зависит от контекста, в котором Вы пишете это "mouseX"?
Сама функция хиттеста не знает, что за цифры Вы передаете, к какому контексту они относятся. Но объект, у которого Вы вызываете хиттест, известен, и его координаты просто пересчитываются в глобальные и затем сравниваются с переданной точкой так, словно ее координаты тоже глобальные. Только и всего. То есть это на Вашей совести — перевести свою точку в глобал, потому что Вы то знаете, в каком она контексте, в чьей системе координат, а функция понятия не имеет.
Попробуйте stage.mouseX и stage.mouseY.
Я смутил Вас этим В1, да. Всего лишь хотел показать, что нужно определиться с контекстом.

Fogflasher 25.11.2013 09:28

Понятно, спасибо.

Да, в том то и дело, что я как раз и не понимал, что mouseX и mouseY = this.mouseX, this.mouseY.
Думал - раз они подсвечиваются синим цветом, то это нечто системное и тотальное, а значит автоматически stage.mouseX, stage.mouseY.


Часовой пояс GMT +4, время: 05:05.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.