AS3, подключая ваши события - PullRequest
0 голосов
/ 17 марта 2009

Есть ли у кого-нибудь опыт в подключении событий. так что мы можем изменить там поведение, не меняя его начальное.

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

Я работаю над проектом, который создаст слой поверх существующего приложения Air, который позволит Manage строить таким образом, чтобы микроплатежи могли обеспечить полный доступ к определенным функциям.

И я предполагал использовать перехват для захвата ваших событий, поэтому нам не нужно редактировать наше приложение, а просто расширять его. (поправьте меня, если я ошибаюсь :-)) Я

Ответы [ 3 ]

3 голосов
/ 23 марта 2009

Да, это должно быть возможно с некоторой модификацией.

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

Если вы не знаете, как события работают в списке отображения (что-либо, что вы видите) во флэш-памяти, позвольте мне сначала объяснить это.

Когда вы нажимаете кнопку, вызывается событие MouseEvent, оно начинается в фазе захвата, где начинается на сцене, вызывая все списки событий, зарегистрированные для события «CLICK», в порядке приоритета, установленного при регистрации слушателей. Если листеры имеют одинаковый приоритет (по умолчанию 0), они вызываются в случайном порядке (в том порядке, в котором они были зарегистрированы). Как только все слушатели для этапа были вызваны, вызывается следующий displayObject в списке кнопок-предков, и то же самое происходит снова. Это продолжается вплоть до самого внутреннего отображаемого объекта, который допускает события мыши (это может быть метка текстового поля внутри кнопки). Здесь фаза захвата заканчивается и начинается целевая фаза. Все слушатели на самом внутреннем объекте вызваны в целевой фазе. Затем начинается пузырчатая фаза, когда все листеры обращаются к родителям, бабушкам и дедушкам вплоть до самой сцены так же, как и раньше (но изнутри).

Следует отметить, что во вспышке целевая фаза обрабатывается как часть фазы барботирования.

А как мы можем это использовать?

Хорошо, когда вы регистрируетесь и слушатель событий вы указываете фазу и приоритет. По умолчанию это фаза восходящего потока и приоритет 0. Поэтому, если мы зарегистрируем прослушиватель события щелчка на этапе для фазы захвата с приоритетом int.MAX_VALUE, мы получим событие перед любым другим листером, за исключением, возможно, другого идентичного слушателя. Следующий код предотвратит события щелчка, зарегистрированные другими слушателями.

stage.addEventListener(MouseEvent.CLICK, stageClick, true, int.MAX_VALUE);

function stageClick(e:MouseEvent):void
{
    e.stopImmediatePropagation();
}

Это поднимает некоторые другие проблемы, во-первых, вы не хотите делать это для всего.

  • Одним из решений было бы иметь список всех кнопок, которые должны иметь их события изменены, и проверка против этого с e.target.
  • Другим решением было бы иметь все кнопки, требующие задержки реализовать интерфейс (давайте назовем его IButtonDelay). А потом простая проверка если e.target - IButtondelay.
  • Третье решение было бы только слушать события на контакте родитель (как menubar), так как это маловероятно, что вы будете использовать событие прежде чем он достигнет этого родителя в любом случае.

Для первых двух решений вы должны предотвратить взаимодействие мыши с дочерними элементами кнопок, чтобы упростить обнаружение (DisplayObjectContainer.mouseChildren = false). Неважно, что вы выберете здесь, затем вам придется отложить простой таймер. А затем снова запустите событие после задержки.

e.target.dispatchEvent(e.clone());

Это поднимает проблему не задержки отложенного события. Мое предложение было бы вместо этого запустить объект события, который наследуется от MouseEvent вместо простого клона. MouseEvent очень просто скопировать, у него есть только несколько свойств. Поэтому, когда вы захватываете его во второй раз, вы можете проверить, является ли он обычным щелчком мыши или вашим дублированием.

Используя решение с inface на кнопках, это будет что-то вроде:

stage.addEventListener(MouseEvent.CLICK, stageClick, true, int.MAX_VALUE);

function stageClick(e:MouseEvent):void
{
    if(e.target is IDelayButton && !e is DelayedMouseEvent)
    {
        e.stopImmediatePropagation();
        DelayEvent(e);
    }
}

function DelayEvent(e:MouseEvent):void
{
    //You code for the delaying, cloning and refiring the event here
}

Возможно, вам придется прослушивать больше типов событий (событий клавиатуры), но большая часть кода может быть сделана достаточно общей, чтобы включать их.

Надеюсь, это поможет, и извините за долгое чтение.

2 голосов
/ 17 марта 2009

Я не думаю, что вы сможете изменить систему событий таким образом, фактически не меняя приложение (если вы можете изменить приложение, не так сложно создать пользовательскую кнопку, которая активирует такое поведение)

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

0 голосов
/ 17 марта 2009

Сверх того, я думаю, что вы можете сделать это: используйте обработчик событий для события click и используйте Timer, чтобы ждать столько времени, сколько вы хотите, или вызовите некоторую обработку, а затем по завершении из последних, назовите действие, соответствующее click.

Или я что-то упускаю?

...