#flash #actionscript-3
#flash #actionscript-3
Вопрос:
Итак, вот моя настройка:
Мой класс документа Main.as (это расширяет MovieClip). Следующий код находится в моем Main.as.
Я объявил все эти переменные в своем определении класса:
private var holder:MovieClip;
private var leftButton:SimpleButton;
private var rightButton:SimpleButton;
в конструкторе…
holder = new MovieClip();
addChild(holder);
holder.addEventListener(KeyboardEvent.KEY_UP, handleKeyboardEvent);
leftButton = new Arrow();
rightButton = new Arrow();
holder.addChild(leftButton);
holder.addChild(rightButton);
leftButton.x = 50;
leftButton.rotation = 180;
rightButton.x = 150;
leftButton.y = rightButton.y = 50;
leftButton.addEventListener(MouseEvent.CLICK, handlePaging);
rightButton.addEventListener(MouseEvent.CLICK, handlePaging);
… вне конструктора…
public function handleKeyboardEvent ( e:KeyboardEvent ) {
trace("got a keyboard event");
trace("e.charCode : " e.charCode);
trace("e.keyCode : " e.keyCode);
switch (e.keyCode) {
case 37: //left arrow
showPreviousMoment();
break;
case 39: //right arrow
showNextMoment();
break;
}
}
Эти две кнопки являются экземплярами видеоролика со стрелкой, который у меня есть в библиотеке. Видеоролик со стрелкой содержит только графику (в диалоговом окне свойств для него базовым классом является flash.display.SimpleButton).
Я хочу, чтобы пользователь мог нажимать экранные стрелки или клавиши со стрелками на клавиатуре, чтобы перелистывать страницу вперед и назад.
Итак … когда я тестирую фильм или публикую его как приложение, нажатие левой и правой клавиш клавиатуры ничего не делает. ОДНАКО…ПОСЛЕ того, как я нажму на экранные стрелки, ТОГДА события клавиатуры будут обнаружены!!! Почему мои события клавиатуры не принимаются изначально? Почему при нажатии на экранные кнопки «держатель» начинает получать события?
Обновить
Я также только что закомментировал весь свой код, ЗА исключением создания экземпляра ‘holder’ и добавления прослушивателя. События клавиатуры не прослушиваются владельцем.
Обновить…ОТВЕТИТЬ
Итак, я выяснил, что если я хочу глобально прослушать KeyboardEvent, я должен зарегистрировать stage в качестве слушателя. Итак, это сделало свое дело:
stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyboardEvent);
Информация из книги Колина Мука:
События ввода с клавиатуры, которые запускают команды всего приложения, обычно обрабатываются глобально слушателями, зарегистрированными в экземпляре Stage Flash Player. Напротив, события ввода с клавиатуры, которые запускают определенный ответ элемента интерфейса, обычно обрабатываются слушателями, зарегистрированными в объекте, который в данный момент находится в фокусе клавиатуры.
Итак, я предполагаю, что в моей первоначальной версии, когда я нажимал на экранную кнопку со стрелкой, я каким-то образом фокусировал клавиатуру на ‘holder;.
Комментарии:
1. Вы уверены, что события клавиатуры запускаются при нажатии на стрелки, а не просто при нажатии на что-либо во флэш-ролике? Потому что, похоже, вам нужно сфокусировать окно flash, чтобы события клавиатуры работали. Попробуйте нажать на что-нибудь другое во флэш-ролике (не на стрелки), а затем протестируйте нажатие стрелок на клавиатуре, если это сработает, это означает, что с вашим кодом все в порядке, и все работает так, как должно.
2. Я забыл упомянуть, что это не проблема с фокусом. Я нажимал на разные части окна фильма, и это не «активировало» клавиши. Это происходит только после того, как я нажимаю на экранные кнопки… затем клавиши активны.
3. Не могли бы вы добавить функцию подкачки к вопросу? возможно, там есть что-то, что активирует события клавиатуры. (просто дикое предположение)
4. Я знал, что это как-то связано с фокусом. Возможно, фокус не на окне flash, а на держателе mc. =D И поскольку стрелки находятся внутри держателя, технически вы щелкаете по держателю, когда нажимаете стрелки, фокусируясь на соответствующем mc.
5. Опубликуйте ответ самостоятельно, и отметка принята, вы поняли это законно, и если проблема решена, то вопрос должен показать, что на него был дан ответ. 🙂
Ответ №1:
Обычно объект, на который вы нажимаете, попадает в фокус. Это действительно влияет на слушателей, вот почему это работает, когда вы добавляете его на сцену.
Когда вы нажимали на любой из них, ваш объект «holder» попадал в фокус, поэтому событие запускалось. Теперь вы делаете это хорошо, что добавили это на сцену.
Комментарии:
1. Два основных свойства определяют, вызывает ли взаимодействие изменения фокуса. mouseEnabled (при значении false) останавливает события мыши и клавиатуры. Предполагая, что mouseEnabled имеет значение true, любому подклассу InteractiveObject (текстовые поля, спрайты, видеоролики и т.д.) Можно вручную назначить фокус с помощью stage. свойство фокусировки. ОДНАКО по умолчанию объекты (за исключением текстового поля и SimpleButton) не будут автоматически попадать в фокус при нажатии, если для параметра «tabEnabled» не установлено значение true. Когда buttonMode имеет значение true, tabEnabled становится true. Таким образом, значение tabEnabled определяет, может ли щелчок или вкладка привести к фокусировке объекта.
Ответ №2:
Более динамичным решением (скажем, если вы динамически создаете экземпляр класса, который содержит movieclip) является использование:
stage.focus = this;
Итак, если вы примените прослушиватель событий к экземпляру класса, которому действительно необходимо прослушивать ключевые события, это может сработать лучше для вас.
Для меня предыдущие предложения не сработали, поскольку я добавлял экземпляр моего основного класса во время выполнения. В итоге мой код выглядел следующим образом:
Main.singletron.stage.addEventListener(KeyboardEvent.KEY_UP, checkKeyDown);
Main.singletron.stage.focus = this;
… вам нужно будет настроить синглетрон для работы этих двух строк.
Комментарии:
1. синглетрон, лол. это должно быть одноэлементным en.wikipedia.org/wiki/Singleton_pattern
Ответ №3:
Я публикую ответ на свой собственный вопрос, основанный на рекомендации @Ascension Systems. Я просто копирую из своего обновления на свой вопрос выше.
Обновить…ОТВЕТИТЬ
Итак, я выяснил, что если я хочу глобально прослушать KeyboardEvent, я должен зарегистрировать stage в качестве слушателя. Итак, это сделало свое дело:
stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyboardEvent);
Информация из книги Колина Мука:
События ввода с клавиатуры, которые запускают команды всего приложения, обычно обрабатываются глобально слушателями, зарегистрированными в экземпляре Stage Flash Player. Напротив, события ввода с клавиатуры, которые запускают определенный ответ элемента интерфейса, обычно обрабатываются слушателями, зарегистрированными в объекте, который в данный момент находится в фокусе клавиатуры.
Итак, я предполагаю, что в моей первоначальной версии, когда я нажимал на экранную кнопку со стрелкой, я каким-то образом фокусировал клавиатуру на «держателе».