Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Поиск рулит! Сообщения за день Все разделы прочитаны
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 31.08.2013, 02:29
ndiezel вне форума Посмотреть профиль Отправить личное сообщение для ndiezel Посетить домашнюю страницу ndiezel Найти все сообщения от ndiezel
  № 1  
Ответить с цитированием
ndiezel
 
Аватар для ndiezel

Регистрация: Mar 2009
Адрес: Из города на Ингуле
Сообщений: 116
Отправить сообщение для ndiezel с помощью ICQ
По умолчанию "Залипают" клавиши управления у главного героя

Всем привет.

Какой-то странный баг и даже и не знаю как его убрать. Управление главным героем сделано с помощью слушателей событий:
Код AS3:
		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;
				}
			}
		}
Ну и соотв, если true - двигаем, если false - не двигаем.
Но постоянно, при возрастании нагрузки на флешку, особенно на считыватели событий, кнопки начинают "залипать". Например управляю я героем и при этом постоянно клацаю кнопкой мыши - всё. Слушатель событий не успевает считать что кнопка была поднята и в результате герой начинает сам двигаться в какую-то сторону, что сильно портит игровой процесс.

Может кто сталкивался? Почему такое происходит?
И эту проблему можно решить с помощью dispatchEvent? (или idispatchEvent, я не разбирался ещё) Если я правильно понял - есть функции управления событиями. Хочу чтоб флеш больше ресурсов уделял на слушатели событий управления.

Или как можно эту проблему решить?

Старый 31.08.2013, 13:43
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 2  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Toronto
Сообщений: 6,600
Записей в блоге: 17
Попробуй повесить слушатель события на stage.

А вообще (ничего, что я на ты?) – сложно ты всё придумал.
Заведи хэш
Код AS3:
private var _pressedKeys:Object = {}
Слушатели сделай элегантными
Код AS3:
private function gameKeysUp(e:KeyboardEvent):void{
  _pressedKeys[e.keyCode] = false;
}
private function gameKeysDown(e:KeyboardEvent):void{
  _pressedKeys[e.keyCode] = true;
}
Заведи метод для определения, нажата ли клавиша. Раз у тебя клавиши дублируются, не стесняйся создать "таблицу алиасов".
Код AS3:
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; //здесь если совсем ничего не зажато
}
Теперь тебе стоит работать только с клавишами 65, 68, 87 и 83. Запросив isKeyDown(65) метод вернёт истину, если нажата клавиша с кодом 65 или с кодом 37.

QA-секция:
Q: но ты совсем забыл про !gameMenuPaused условие! Я вставлю его сам.
A: конечно, отсюда не слишком понятна цель этого условия, но мне кажется, это чтобы персонаж не воспринимал кнопки во время паузы. Это неправильно представь ситуацию, что игрок зажал "вправо" и включил меню паузы, а потом отжал вправо. Убрав паузу игрок продолжит бежать вправо, потому что флаг правой клавиши не снялся как раз из за этого условия.

P.S. фигачил код прямо с форума, за работоспособность не ручаюсь.

Старый 31.08.2013, 15:53
ndiezel вне форума Посмотреть профиль Отправить личное сообщение для ndiezel Посетить домашнюю страницу ndiezel Найти все сообщения от ndiezel
  № 3  
Ответить с цитированием
ndiezel
 
Аватар для ndiezel

Регистрация: Mar 2009
Адрес: Из города на Ингуле
Сообщений: 116
Отправить сообщение для ndiezel с помощью ICQ
Psycho Tiger, сначала я не очень понял твой код. Подумал - о! Это, наверное, решение!
Но когда разобрался... Это, по сути, тот же метод, что использую я. Нужны будут те же слушатели событий KeyboardEvent.KEY_DOWN и KeyboardEvent.KEY_UP и по EnterFrame - проверка зажата ли кнопка или нет. Только будут не переменные, а массив с переменными. Да, это чуть изящней, но по сути - ничего не меняет.

Вот привязывание слушателя к stage - вроде как помогло.
Ещё проверяю, но вроде - не залипает больше.

Старый 31.08.2013, 23:44
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 4  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Toronto
Сообщений: 6,600
Записей в блоге: 17
Цитата:
Вот привязывание слушателя к stage - вроде как помогло.
Ещё проверяю, но вроде - не залипает больше.
Есть такая штука - stage.focus. Указывает на то, что сейчас "в фокусе". Например, если это текстовое поле – то символы будут туда вводиться, а если не текстовое поле – соответственно, не будут.
Идея в том, что кликая на какой-нибудь другой элемент прочие перестают иметь фокус (ну, грубо говоря). А так как по факту любой клик всегда будет кликом на stage (конкретней - на его ребёнка, не суть) – то фокус не потеряется. Тадаам!

Старый 01.09.2013, 04:32
ndiezel вне форума Посмотреть профиль Отправить личное сообщение для ndiezel Посетить домашнюю страницу ndiezel Найти все сообщения от ndiezel
  № 5  
Ответить с цитированием
ndiezel
 
Аватар для ndiezel

Регистрация: Mar 2009
Адрес: Из города на Ингуле
Сообщений: 116
Отправить сообщение для ndiezel с помощью ICQ
Цитата:
Сообщение от Psycho Tiger Посмотреть сообщение
Есть такая штука - stage.focus. Указывает на то, что сейчас "в фокусе". Например, если это текстовое поле – то символы будут туда вводиться, а если не текстовое поле – соответственно, не будут.
Идея в том, что кликая на какой-нибудь другой элемент прочие перестают иметь фокус (ну, грубо говоря). А так как по факту любой клик всегда будет кликом на stage (конкретней - на его ребёнка, не суть) – то фокус не потеряется. Тадаам!
Всё бы ничего, да только, как оказалось, если повесить слушатели на stage, то они потом не убираются. Даже если сделать вот так:
Код AS3:
			stage.focus = this;
			stage.removeEventListener(KeyboardEvent.KEY_DOWN,workScreen[0].gameKeysDown);
			stage.removeEventListener(KeyboardEvent.KEY_UP,workScreen[0].gameKeysUp);
И остаётся в памяти слушатели, которые потом повторяются и, в общем - жуть какая-то получается...

Старый 01.09.2013, 10:59
caseyryan вне форума Посмотреть профиль Отправить личное сообщение для caseyryan Найти все сообщения от caseyryan
  № 6  
Ответить с цитированием
caseyryan
 
Аватар для caseyryan

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Всё бы ничего, да только, как оказалось, если повесить слушатели на stage, то они потом не убираются.
Не правда.
Тут сам подход кривой. Вот так workScreen[0].gameKeysDown делать не нужно. 99% что именно в этом месте и проблема

Старый 02.09.2013, 01:03
ndiezel вне форума Посмотреть профиль Отправить личное сообщение для ndiezel Посетить домашнюю страницу ndiezel Найти все сообщения от ndiezel
  № 7  
Ответить с цитированием
ndiezel
 
Аватар для ndiezel

Регистрация: Mar 2009
Адрес: Из города на Ингуле
Сообщений: 116
Отправить сообщение для ndiezel с помощью ICQ
Цитата:
Сообщение от caseyryan Посмотреть сообщение
Не правда.
Тут сам подход кривой. Вот так workScreen[0].gameKeysDown делать не нужно. 99% что именно в этом месте и проблема
Вот так у меня сделано:
Код AS3:
workScreen[0].addEventListener(KeyboardEvent.KEY_DOWN,workScreen[0].gameKeysDown,false,0,true);
workScreen[0].addEventListener(KeyboardEvent.KEY_UP,workScreen[0].gameKeysUp,false,0,true);
Чем криво?

Старый 02.09.2013, 10:21
Psycho Tiger вне форума Посмотреть профиль Отправить личное сообщение для Psycho Tiger Найти все сообщения от Psycho Tiger
  № 8  
Ответить с цитированием
Psycho Tiger
 
Аватар для Psycho Tiger

блогер
Регистрация: Jun 2005
Адрес: Toronto
Сообщений: 6,600
Записей в блоге: 17
Цитата:
И остаётся в памяти слушатели, которые потом повторяются
Один слушатель на один тип события на один метод. Нельзя повесить его дважды.

Это значит что workScreen[0] указывает на разные места в разные моменты времени.
Другими словами, workScreen[0] во время подписки !== workScreen[0] во время отписки.

Старый 02.09.2013, 15:10
ndiezel вне форума Посмотреть профиль Отправить личное сообщение для ndiezel Посетить домашнюю страницу ndiezel Найти все сообщения от ndiezel
  № 9  
Ответить с цитированием
ndiezel
 
Аватар для ndiezel

Регистрация: Mar 2009
Адрес: Из города на Ингуле
Сообщений: 116
Отправить сообщение для ndiezel с помощью ICQ
Я не совсем понял, что ты написал Psycho Tiger

Я постараюсь просто описать что происходит, чтоб прояснить ситуацию.
Если присваивать и снимать слушатели с workScreen[0] (там находится мувик с игрой), то всё работает. Ссылка в массиве - на один и тот же мувик. Всё прекрасно вешается и снимается.
Если же я вешаю и снимаю со stage, то со stage слушатели не снимаются. Во время игры stage меняется, там приходится stage обновлять, чтоб слушатели работали.

Так вот, если вешать слушатели на stage, после завершения игры мувик с игрой gc не удаляется, потому что на нём висят эти два слушателя (на помогает даже weak reference). А потом, когда создаётся новый мувик с игрой, его слушают уже два слушателя. И игра начинает жутко глючить.

И если бы придумать как найти эти слушатели и всё таки их снять со stage, то это очень бы помогло, потому что при вызове слушателей на stage кнопки не залипают, или залипают намного меньше, чем при присвоении workScreen[0].

Старый 02.09.2013, 15:14
MikroAcse вне форума Посмотреть профиль Отправить личное сообщение для MikroAcse Найти все сообщения от MikroAcse
  № 10  
Ответить с цитированием
MikroAcse
 
Аватар для MikroAcse

Регистрация: Feb 2012
Сообщений: 1,540
Ну так храни стейдж, на который повесил слушатель.

Создать новую тему Ответ Часовой пояс GMT +4, время: 06:41.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 06:41.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.