|
|
« Предыдущая тема | Следующая тема » |
Опции темы | Опции просмотра |
|
|
|||||
Регистрация: Feb 2012
Сообщений: 3
|
Оптимизация обработки событий клавиатуры
Делаю многопользовательскую игрушку, клиент пишу на AS3. Передвижение персонажа осуществляется с клавиатуры. Все вроде бы банально, но дело в том, что при нажатии и удержании клавиши после небольшой задержки начинают имитироваться быстрые повторные нажатия. И, что интересно, Firefox имитирует только нажатие (событие KEY_DOWN), а вот Opera "гоняет" клавишу туда-сюда (KEY_DOWN - KEY_UP). Это в Ubuntu, в других ОС не проверял еще.
Вся проблема в том, что мне необходимо отправлять на сервер сообщения о том, что пользователь нажал какую-либо клавишу, и что он отпустил ее (по нажатию/отпусканию клавиши меняется состояние объекта). Так вот в случае с Оперой клиент начинает безумно "засорять эфир" потоком сообщений о событиях, которые на самом деле не происходят (имитируемые нажатия клавиши). Мне это очень не нравится, т.к. повышает нагрузку на сервер и сеть. Есть какие-то готовые решения этой проблемы? У меня есть одна идея, но для ее реализации надо быть уверенным, что у всех клиентов скорость повторных нажатия примерно одинакова, а уверенности такой нет. А может, под виндой такой проблемы нет? |
|
|||||
Регистрация: May 2010
Адрес: пространство в положении
Сообщений: 219
|
поставте булевый флаг (true/false) и от него "прыгайте".
|
|
|||||
Регистрация: Feb 2012
Сообщений: 3
|
Это работает в Firefox, но Opera будет менять флаг туда-сюда, т.к. она имитирует и отпускание клавиши.
Хочу попробовать такой способ: в событии KEY_DOWN устанавливать некий счетчик в значение, скажем, 10. По событию KEY_UP для этого счетчика будет устанавливаться коэффициент 0.9 (до события он равен единице). А в EnterFrame перемножать коэффициент на счетчик, и если коэффициент уменьшился, скажем, ниже 3, только тогда отсылать в сокет сообщение о том, что клавиша отпущена. Если имитируются быстрые нажатия и отпускания, то счетчик не будет опускаться ниже определенной величины (зависит от скорости нажатий). Мне это кажется костылем, но если другого способа не найду, буду делать так. |
|
|||||
У Вас наверняка есть игровой цикл (по таймеру или ENTER_FRAME).
Создаете поле В этом цикле проверяете, нажата ли клавиша: var newIsNeededKeyDown:Boolean = inp.code[код нужной клавиши]; if (newIsNeededKeyDown != isNeededKeyDown) { isNeededKeyDown = newIsNeededKeyDown; if (isNeededKeyDown) { dispatchEvent(new Event("neededKeyDown")); } else { dispatchEvent(new Event("neededKeyUp")); } } |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
expl Уже второй раз вижу отсылку к этому классу как панацее от всего, хотя автор ясно выразился, о чем он:
Цитата:
__________________
Reality.getBounds(this); |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Вы класс-то смотрели?
//Обработка событий клавиатуры root.stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown); root.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); private function onKeyDown(event:KeyboardEvent):void { code[event.keyCode] = true; //Если хотите узнать код клавиши - просто раскомментируйте код ниже //trace(event.keyCode); } private function onKeyUp(event:KeyboardEvent):void { code[event.keyCode]=false; } И у топикстартера вроде была одна задача.
__________________
Reality.getBounds(this); |
|
|||||
Цитата:
Вобщем проверка нажатости/отжатости по таймеру/ентерфрейму сработает и для Оперы, только если события отжатия/нажатия "фактически одновременно". Не знаю вот хуже это или лучше, чем ваш подход с таймерами для Оперы (последняя версия на винде никаких повторов не делает). Но, по крайней мере надежнее для остальных бравзеров. |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Ну возможно. Однако вероятность, что состояние false и его смена на true таки распределятся в разные блоки фреймов – не нулевая. Здесь конечно можно поискать баланс между вероятностью такого бага и громоздким его решением с помощью таймера (которое тоже не видится мне 100% надёжным, поскольку также основано на временном диапазоне, а он не гарантирован).
__________________
Reality.getBounds(this); |
|
|||||
Регистрация: Feb 2012
Сообщений: 3
|
Всем спасибо за рекомендации, буду пробовать. Потом отпишу, что получилось.
|
Часовой пояс GMT +4, время: 00:04. |
|
« Предыдущая тема | Следующая тема » |
|
|