![]() |
|
||||||||||
|
|||||||
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | Опции просмотра |
|
![]() |
![]() |
|
|||||
|
Всем привет.
Какой-то странный баг и даже и не знаю как его убрать. Управление главным героем сделано с помощью слушателей событий: public function gameKeysDown(e:KeyboardEvent):void { if (! gameMenuPaused) { if (e.keyCode == 65 || e.keyCode == 37) { leftBln = true; } if (e.keyCode == 68 || e.keyCode == 39) { rightBln = true; } if (e.keyCode == 87 || e.keyCode == 38) { upBln = true; } if (e.keyCode == 83 || e.keyCode == 40) { downBln = true; } } } public function gameKeysUp(e:KeyboardEvent):void { if(!gameMenuPaused) { if (e.keyCode == 65 || e.keyCode == 37) { leftBln = false; } if (e.keyCode == 68 || e.keyCode == 39) { rightBln = false; } if (e.keyCode == 87 || e.keyCode == 38) { upBln = false; } if (e.keyCode == 83 || e.keyCode == 40) { downBln = false; } } } Но постоянно, при возрастании нагрузки на флешку, особенно на считыватели событий, кнопки начинают "залипать". Например управляю я героем и при этом постоянно клацаю кнопкой мыши - всё. Слушатель событий не успевает считать что кнопка была поднята и в результате герой начинает сам двигаться в какую-то сторону, что сильно портит игровой процесс. Может кто сталкивался? Почему такое происходит? И эту проблему можно решить с помощью dispatchEvent? (или idispatchEvent, я не разбирался ещё) Если я правильно понял - есть функции управления событиями. Хочу чтоб флеш больше ресурсов уделял на слушатели событий управления. Или как можно эту проблему решить? |
|
|||||
|
Попробуй повесить слушатель события на stage.
А вообще (ничего, что я на ты?) – сложно ты всё придумал. Заведи хэш Слушатели сделай элегантными private function gameKeysUp(e:KeyboardEvent):void{ _pressedKeys[e.keyCode] = false; } private function gameKeysDown(e:KeyboardEvent):void{ _pressedKeys[e.keyCode] = true; } private static const ALIASES:Object = { } /* я неуверен, можно ли сразу создать значения из чисел прямо в определении, поэтому определю ниже */ { ALIASES[65] = 37; ALIASES[68] = 39; ALIASES[87] = 38; ALIASES[83] = 40; }; private function isKeyDown(keyCode:int):Boolean{ //Все понятно, если кнопка зажата if (_pressedKeys[keyCode]) return true; //проверяем, есть ли такая кнопка в таблице алиасов. Если есть, то мы должны проверить ещё и её алиас if (keyCode in ALIASES) return(_pressedKeys(ALIASES[keyCode])); return false; //здесь если совсем ничего не зажато } QA-секция: Q: но ты совсем забыл про !gameMenuPaused условие! Я вставлю его сам. A: конечно, отсюда не слишком понятна цель этого условия, но мне кажется, это чтобы персонаж не воспринимал кнопки во время паузы. Это неправильно представь ситуацию, что игрок зажал "вправо" и включил меню паузы, а потом отжал вправо. Убрав паузу игрок продолжит бежать вправо, потому что флаг правой клавиши не снялся как раз из за этого условия. P.S. фигачил код прямо с форума, за работоспособность не ручаюсь.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Psycho Tiger, сначала я не очень понял твой код. Подумал - о! Это, наверное, решение!
Но когда разобрался... Это, по сути, тот же метод, что использую я. Нужны будут те же слушатели событий KeyboardEvent.KEY_DOWN и KeyboardEvent.KEY_UP и по EnterFrame - проверка зажата ли кнопка или нет. Только будут не переменные, а массив с переменными. Да, это чуть изящней, но по сути - ничего не меняет. Вот привязывание слушателя к stage - вроде как помогло. Ещё проверяю, но вроде - не залипает больше. |
|
|||||
|
Цитата:
Идея в том, что кликая на какой-нибудь другой элемент прочие перестают иметь фокус (ну, грубо говоря). А так как по факту любой клик всегда будет кликом на stage (конкретней - на его ребёнка, не суть) – то фокус не потеряется. Тадаам!
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Цитата:
stage.focus = this; stage.removeEventListener(KeyboardEvent.KEY_DOWN,workScreen[0].gameKeysDown); stage.removeEventListener(KeyboardEvent.KEY_UP,workScreen[0].gameKeysUp); ![]() |
|
|||||
|
Цитата:
Тут сам подход кривой. Вот так workScreen[0].gameKeysDown делать не нужно. 99% что именно в этом месте и проблема |
|
|||||
|
Цитата:
Чем криво? |
|
|||||
|
Цитата:
Это значит что workScreen[0] указывает на разные места в разные моменты времени. Другими словами, workScreen[0] во время подписки !== workScreen[0] во время отписки.
__________________
Тут мужик танцует и поёт про флэш |
|
|||||
|
Я не совсем понял, что ты написал Psycho Tiger
Я постараюсь просто описать что происходит, чтоб прояснить ситуацию. Если присваивать и снимать слушатели с workScreen[0] (там находится мувик с игрой), то всё работает. Ссылка в массиве - на один и тот же мувик. Всё прекрасно вешается и снимается. Если же я вешаю и снимаю со stage, то со stage слушатели не снимаются. Во время игры stage меняется, там приходится stage обновлять, чтоб слушатели работали. Так вот, если вешать слушатели на stage, после завершения игры мувик с игрой gc не удаляется, потому что на нём висят эти два слушателя (на помогает даже weak reference). А потом, когда создаётся новый мувик с игрой, его слушают уже два слушателя. И игра начинает жутко глючить. И если бы придумать как найти эти слушатели и всё таки их снять со stage, то это очень бы помогло, потому что при вызове слушателей на stage кнопки не залипают, или залипают намного меньше, чем при присвоении workScreen[0]. |
|
|||||
|
Регистрация: Feb 2012
Сообщений: 1,540
|
Ну так храни стейдж, на который повесил слушатель.
|
![]() |
![]() |
Часовой пояс GMT +4, время: 06:41. |
|
|
« Предыдущая тема | Следующая тема » |
| Опции темы | |
| Опции просмотра | |
|
|