События в ActionScript 3. Слушатели и обработчики событий

В предыдущих уроках мини-курса «Основы анимации в ActionScript 3»я уже затрагивал тему событий, которые автоматически генерируются когда что-нибудь происходит в системе или пользователь определенным образом использует клавиатуру или мышь. В AS3 архитектура событий полностью интегрирована во Flash Player.

В этом уроке мы подробно разберем концепцию событий, а также Вы узнаете:

  1. Что такое слушатель события в ActionScript 3 и какова его роль
  2. Что такое обработчик события в ActionScript 3 события и для чего он служит
  3. Какие параметры передаются обработчику события
  4. Познакомитесь с некоторыми событиями мыши и клавиатуры

Чтобы хорошо разобраться в этой теме, Вам нужно усвоить пару дополнительных концепций:

  • слушатели событий
  • обработчики событий.

Эти названия говорят сами за себя. Слушатель — это объект, который слушает или ожидает когда произойдет определенное событие. Обработчик — это функция, которая описывает все, что должно случиться после того, как это событие произойдет.

Слушатели событий в ActionScript 3

Как было сказано выше, слушатель — это объект, который слушает или ожидает, когда совершится определенное событие. Вы можете сделать Ваш класс слушателем определенного события, вызвав функцию addEventListener. Этой функции Вы должны передать в качестве аргументов:

  • имя события, которое слушает объект
  • имя функции-обработчика этого события
addEventListener("enterFrame", onEnterFrame);

Вы можете использовать дополнительные параметры при добавлении слушателей событий, но в этом курсе «Основы анимации в ActionScript 3» мы не будем их рассматривать. Синтаксис, показанный выше, обеспечит Ваши потребности при работе с событиями в 99% случаев.

Обратите внимание на то, что имя события "enterFrame" — это строка (как Вам уже хорошо известно, все строки мы заключаем в кавычки). Понятно, что возможны ошибки при записи — забыли поставить кавычки, например. В результате обработчик события не сработает, но и сообщения от компайлера об этой ошибке Вы не получите!

Для того, чтобы избежать подобных ситуаций в AS3 существует другой, равноценный способ записи имен событий. Когда Вы имеете дело с функцией addEventListener, Вы можете использовать для этого свойства класса Event. Давайте перепишем код, приведенный выше, следующим образом:

addEventListener(Event.ENTER_FRAME, onEnterFrame);

Если Вы решите узнать, какое же значение присвоено свойству ENTER_FRAME, то обнаружите, что это "enterFrame", являющееся строкой.

Теперь Вы могли бы предположить, что и здесь при записи кода возможны ошибки. Правильно. Но если такое случится, то программа откажется компилировать Ваш код и сообщит об этом. Например, у Вас появится сообщение о том, что такого свойства у класса Event нет. Кроме того в нем будет указана не только строчка, на которой эта ошибка сделана, но и первый «проблемный» символ на этой строчке. Это очень хорошая система подсказок.

В дополнение к типам событий в классе Event существуют другие типы событий в других классах, как, например, MouseEvent.MOUSE_DOWN, KeyboardEvent.KEY_DOWN, TimerEvent.TIMER и т.д. Все эти события можно было бы записать с помощью строк: "mouseDown", "keyDown", "timer", но я бы Вам советовал привыкать сразу к записи свойств, а не строк.

Вот еще одна важная для запоминания вещь. Иногда, как например, в предыдущем примере, Вы можете вызывать функцию addEventListener непосредственно в классе. В этом случае Вы как бы говорите классу, чтобы он слушал свое собственное событие enterFrame. В других случаях Вам, возможно, понадобиться слушать события сгенерированные другими объектами. Например, у Вас есть кнопка с именем myButton. Когда пользователь кликает на ней — она генерирует событие mouseDown. Для того чтобы слушать это событие, Вы должны вызвать метод addEventListener следующим образом:

myButton.addEventListener(MouseEvent.MOUSE_DOWN, onButtonPress);

Последнее, о чем хотелось бы здесь сказать. Вы можете давать любые имена функциям-обработчикам событий. Например, я назвал свою функцию onEnterFrame. Это было сделано просто потому, что это имя хорошо описывает событие, а также я привык именно к такой записи. Вы могли бы дать этой функции другое имя, понятное Вам. Например, doCoolThing.

Разбирая код, написанный другими программистами, Вы заметите, что имена обработчиков событий очень часто записываются с on в начале. Затем идет описательное имя, говорящее о том, откуда пришло событие, например, onStartButtonClick или onSpaceshipCrash.

Как Вы будете записывать имена — это дело Вашего личного вкуса и предпочтений. Главное, будьте в этом постоянны, чтобы с одного взгляда на код было понятно, что обработчик события — это обработчик события.

Идем дальше. Я уже говорил, что слушатель слушает события, но более точным было бы следующее определение: слушателю сообщается о том, что событие произошло.

Объект, генерирующий события, хранит внутри себя список всех объектов, которые добавили себя в него в качестве слушателей. Если объект способен генерировать события различного типа, как, например, mouseDown, mouseUp и mouseMove, то он будет хранить отдельный список слушателей для каждого события. Когда одно из событий происходит, объект проходит по соответствующему списку и сообщает каждому объекту-слушателю о том, что событие случилось.

Еще один способ описания событий — это сказать, что объект, который становится слушателем, подписывается на соответствующее событие. А объект, который генерирует события — транслирует событие всем своим подписчикам.

Если Вы хотите чтобы объект перестал слушать событие, то Вы можете прямо указать ему на это, вызвав метод removeEventListener:

removeEventListener(Event.ENTER_FRAME, onEnterFrame);

Этот код говорит объекту о том, чтобы он исключил из своего списка слушателей определенный слушатель. Таким образом, он перестанет получать соответствующие уведомления в дальнейшем.

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

package {
    import flash.display.Sprite;
    import flash.events.MouseEvent;
    
    public class EventDemo extends Sprite {
        private var eventSprite:Sprite;
        public function EventDemo() {
            init();
        }
        private function init():void {
            eventSprite = new Sprite();
            addChild(eventSprite);
            eventSprite.graphics.beginFill(0xff0000);
            eventSprite.graphics.drawCircle(0, 0, 100);
            eventSprite.graphics.endFill();
            eventSprite.x = stage.stageWidth / 2;
            eventSprite.y = stage.stageHeight / 2;
            eventSprite.addEventListener(MouseEvent.MOUSE_DOWN, 
onMouseDown);
            eventSprite.addEventListener(MouseEvent.MOUSE_UP,
onMouseUp);
        }
        private function onMouseDown(event:MouseEvent):void {
            trace("кнопка нажата");
        }
        private function onMouseUp(event:MouseEvent):void {
            trace("кнопка отпущена");
        }
    }
}

Что все это значит? Большая часть функции init просто создает sprite, рисует в нем круг и размещает его в центре сцены. Для нас наиболее важны последние две строчки.

Здесь класс добавляет себя как слушатель событий MOUSE_DOWN и MOUSE_UP. Заметьте, что это свойства класса MouseEvent, а для того, чтобы все работало корректно, этот класс должен быть импортирован. В качестве обработчиков событий передаются две функции onMouseDown и onMouseUp.

Обычно, обработчику события в качестве параметра передается объект события, в котором хранится соответствующая информация о нем (событии). Как минимум, это будет информация об объекте, сгенерировавшем событие.

В случае событий мыши, этой информацией будет:

  • местоположение курсора мыши в момент события
  • какая кнопка мыши была нажата
  • и т.д.

В случае событий клавиатуры, этой информацией будет:

  • какая клавиша была нажата в момент события
  • состояние других клавиш, например, Ctrl, Alt и Shift в этот момент

Более подробно о том, какая информация передается, Вы можете узнать из файлов помощи (Help) программы Flash Professional или в Cправочнике по ActionScript 3.0 для платформы Adobe Flash.

Сохраните предыдущий пример как EventDemo.as и запустите Flash Player. Теперь в панели Output Вы можете наблюдать, как выводятся надписи каждый раз при нажатии и отпускании левой кнопки мыши на красном круге (объект — eventSprite) .

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

Если Вы новичок в ActionScript 3, но у Вас все получилось и Вы действительно поняли, как это работает — примите мои поздравления! Вы только что перешли с начального уровня на средний.

Обработчики событий в ActionScript 3

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

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

В действительности, все что он делает — это вызывает функцию с определенным именем. В предыдущем примере класс EvenDemo добавлил себя как слушатель двух событий, которые генерирует красный круг (eventSprite). Внутри себя он хранит списки слушателей для каждого события. Это значит, что у него есть один список для события mouseDown и другой список для события mouseUp. Эти списки — не что иное как простые массивы. И у каждого списка есть ссылка на главный объект, которым является экземпляр класса EventDemo.

Когда пользователь нажимает левую кнопку мыши на красном круге (в нашем примере — это eventSprite), то он реагирует примерно так «Кнопка нажата! Я должен оповестить своих слушателей!» (или что-то в этом роде). Затем он проходит по списку слушателей события mouseDown и смотрит, кто в нем находится. Затем он находит ссылки на главный объект и функцию, которая определена как обработчик события (в нашем примере — это onMouseDown). Затем он просто вызывает эту функцию и применяет ее к этому слушателю. Если другие объекты зарегистрировались как слушатели события mouseDown, то они будут тоже в списке. И соответственно, какие бы обработчики они ни определили — они тоже будут вызваны.

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

Итоги

Итак, из этого урока Вы многое узнали о событиях в ActionScript 3, а также слушателях и обработчиках событий. Для того чтобы проверить хорошо ли усвоена информация ответьте на следующие вопросы:

Контрольные вопросы по материалу урока

  1. Что такое событие?
  2. Какие типы событий Вы знаете?
  3. Какой метод вызывается для того, чтобы сделать объект слушателем события?
  4. Какие параметры передаются этому методу?
  5. Какие свойства класса MouseEvent Вам известны?
  6. Какие свойства класса KeyboardEvent Вам известны?

Жду от Вас вопросов, если что-то осталось непонятным. Задавайте их в комментариях.

В следующем уроке мы разберем тему событий в анимации.