Показать сообщение отдельно
Старый 30.04.2010, 21:33
orcpochta вне форума Посмотреть профиль Отправить личное сообщение для orcpochta Найти все сообщения от orcpochta
  № 7  
Ответить с цитированием
orcpochta

Регистрация: Feb 2008
Сообщений: 890
Цитата:
Что хотите Вы?
В первом посте все четко было сказано:
"Сразу пример, чтобы легче представить: в игре слушает нажатия различных кнопок, отфильтровывает из них кнопки LEFT, RIGHT, UP, DOWN (и дубляж A, D, W, S), режет повторения, если кнопка уже нажата, и рассылает соответствующие события "leftPressed"/"leftReleased", "rightPressed"/"rightReleased" и т.д..." - куда уж яснее?

Цитата:
А, класс, рассылающий события... Для игры... кхм. Здорово. Что имеем?
Подписываемся на 4 события, (влево-вправо-вверх-вниз), а то и на больше - не во всех играх 4 кнопки. 4 обработчика, ну ладно, так удобней, ок.
Ну во первых каждая кнопка - это не одно событие, а два: "нажата", "отжата". Это можно использовать к примеру так: "нажата" - запускает действо, "отжата" - запускает плавное затухание вызванного действа.

Цитата:
Но мы заводим ради этого ещё один класс, который диспатчит событие... чтобы было удобней.
Считаем строчки кода:
4 подписка на событие.
4 описание заголовка методов
4 отписка от методов
12 строк кода.
Мы заводим удобный контроллер клавиатуры, который если надо поддерживает несколько групп клавиш для однотипных действий (W-A-S-D и стрелки UP-LEFT-DOWN-RIGHT), проверяет, чтобы не вызывалось событие уже нажатой клавиши, проверяет, чтобы не запускалось событие от дублирующей клавиши, если нажата клавиша идентичного действия, и не запускает событие от отжатой клавиши, если до этого была нажата другая клавиша идентичного действия, а эта не нажалась по той же причине. - И все это делает легко и просто, а мы об этом даже не думаем. И уж конечно не считаем строчки кода.

Цитата:
Или если инлайново:
1 подписка
1 отписка
1 заголовок метода
4 ифа (или 8 кейсов+свич)

7-12 строк против 12. То есть, проще говоря, проще и дешевле по производительности писать код ЗАНОВО, чем использовать методы своего же класса. Это стоит того?
Вы плохо понимаете принципы ООП - именно это того и стоит, что я имею простой, легко настраиваемый на любые кнопки класс, который могу использовать везде, где надо слушать события клавиатуры, а не мешу все в одно кучу. То, что вы предлагаете, называется процедурное программирование в классах - вы должны были об этом недавно читать во флейме, тем более, что вроде сами тему эту и поднимали...)))

Цитата:
Теперь по вопросу зачем мне этот класс: всегда, когда нужно узнать, нажата ли клавиша в данный момент. Не очень важна, когда кнопка нажата одна, но если должна быть нажата комбинация 2 клавиш - класс отлично выручает.
знаете, для таких простых действий мне как-то совершенно не взбрело бы в голову пользоваться чужим классом, тем более, что это:
1) не входило в рамки моего вопроса;
2) все это легко настраивается в том же классе клавиатурного контроллера или его расширениях.

----------------------------------

Вот, собственно, мой контроллер:
Код AS3:
package
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.KeyboardEvent;
 
	/**
	 * ...
	 * @author Andrey Polkanov - andrey@polkanov.com - www.polkanov.com
	 */
	public class KeyboardController extends EventDispatcher
	{
 
		//----- Public static constants -----
		public static const UP_PRESSED:String 		= "upPressed";
		public static const DOWN_PRESSED:String 	= "downPressed";
		public static const LEFT_PRESSED:String 	= "leftPressed";
		public static const RIGHT_PRESSED:String	= "rightPressed";
 
		public static const UP_RELEASED:String 		= "upReleased";
		public static const DOWN_RELEASED:String 	= "downReleased";
		public static const LEFT_RELEASED:String 	= "leftReleased";
		public static const RIGHT_RELEASED:String	= "rightReleased";
 
 
 
		//----- Private static constants -----
		//Arrows: UP - 38, DOWN - 40, LEFT - 37, RIGHT - 39
		//Chars: W - 87, S - 83, A - 65, D - 68
		private static const DEFAULT_LEGAL_KEYS:Object = 
		{	
			38: [KeyboardController.UP_PRESSED, 	KeyboardController.UP_RELEASED],
			40: [KeyboardController.DOWN_PRESSED, 	KeyboardController.DOWN_RELEASED],
			37: [KeyboardController.LEFT_PRESSED, 	KeyboardController.LEFT_RELEASED],
			39: [KeyboardController.RIGHT_PRESSED, 	KeyboardController.RIGHT_RELEASED],
 
			87: [KeyboardController.UP_PRESSED, 	KeyboardController.UP_RELEASED],
			83: [KeyboardController.DOWN_PRESSED,	KeyboardController.DOWN_RELEASED],
			65: [KeyboardController.LEFT_PRESSED, 	KeyboardController.LEFT_RELEASED],
			68: [KeyboardController.RIGHT_PRESSED, 	KeyboardController.RIGHT_RELEASED]
		};
 
 
 
		//----- Private variables -----
		private var stage:Stage;
 
		private var legalKeys:Object;
		private var keyCache:Object;
 
 
 
		//----- Constructor -----
		public function KeyboardController (stage:Stage, legalKeys:Object = null) 
		{
			super( );
 
			this.stage = stage;
			this.legalKeys = legalKeys;
 
			init( );
		}
 
 
 
		//----- Public functions -----
		public function destroy ( ):void
		{
			stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
			stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpListener);
		}
 
 
 
		//----- Private functions -----
		private function init ( ):void
		{
			if (!legalKeys) legalKeys = KeyboardController.DEFAULT_LEGAL_KEYS;
 
			keyCache = new Object( );
 
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
			stage.addEventListener(KeyboardEvent.KEY_UP, keyUpListener);
		}
 
		private function keyDownListener (e:KeyboardEvent):void
		{
			var key:String = String(e.keyCode);
 
			if (legalKeys.hasOwnProperty(key) && !keyCache.hasOwnProperty(legalKeys[key][0]))
			{
				keyCache[legalKeys[key][0]] = key;
 
				dispatchEvent(new Event(legalKeys[key][0]));
			}
		}
 
		private function keyUpListener (e:KeyboardEvent):void
		{
			var key:String = String(e.keyCode);
 
			for (var i:String in keyCache)
			{
				if (keyCache[i] == key)
				{
					delete keyCache[i];
 
					dispatchEvent(new Event(legalKeys[key][1]));
				}
			}
		}
 
	}
 
}
вот мэйн, чтобы можно было потрейсить:
Код AS3:
package 
{
 
	import flash.display.Sprite;
	import flash.events.Event;
 
	/**
	 * ...
	 * @author Andrey Polkanov - andrey@polkanov.com - www.polkanov.com
	 */
	public class Main extends Sprite 
	{
 
		public function Main ( ):void 
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		private function init(e:Event = null):void 
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);
			// entry point
 
			/**
			 *@usage Если надо определить свои кнопки, отличные от умолчания (курсоры и W-A-S-D),
			 * то можно расширить класс или прям в том месте, где будет создаваться контроллер,
			 * задать ему описательный объект доступных клавиш и событийных констант.
			 * 
			 * Определяет только стрелки UP и DOWN: 
			 *var legalKeys:Object = {	38: [KeyboardController.UP_PRESSED, KeyboardController.UP_RELEASED],
			 * 							40: [KeyboardController.DOWN_PRESSED, KeyboardController.DOWN_RELEASED]}
			 * Каждый элемент - это:
			 * (поле) код клавиши: (значение массив)["константа, определяющая событие нажатия", "константа, определяющая событие отпускания для этой кнопки"]
			 * 
			 * Передаем этот описательный объект в конструктор:
			 *var keyboard:KeyboardController = new KeyboardController(stage, legalKeys);
			*/
 
			var keyboard:KeyboardController = new KeyboardController(stage);
 
			keyboard.addEventListener(KeyboardController.UP_PRESSED, upPressedListener);
			keyboard.addEventListener(KeyboardController.UP_RELEASED, upReleasedListener);
 
			keyboard.addEventListener(KeyboardController.DOWN_PRESSED, downPressedListener);
			keyboard.addEventListener(KeyboardController.DOWN_RELEASED, downReleasedListener);
 
			keyboard.addEventListener(KeyboardController.LEFT_PRESSED, leftPressedListener);
			keyboard.addEventListener(KeyboardController.LEFT_RELEASED, leftReleasedListener);
 
			keyboard.addEventListener(KeyboardController.RIGHT_PRESSED, rightPressedListener);
			keyboard.addEventListener(KeyboardController.RIGHT_RELEASED, rightReleasedListener);			
		}
 
		private function upPressedListener (e:Event):void
		{
			trace(e.type);
		}		
		private function upReleasedListener (e:Event):void
		{
			trace(e.type);
		}
 
		private function downPressedListener (e:Event):void
		{
			trace(e.type);
		}		
		private function downReleasedListener (e:Event):void
		{
			trace(e.type);
		}
 
		private function leftPressedListener (e:Event):void
		{
			trace(e.type);
		}		
		private function leftReleasedListener (e:Event):void
		{
			trace(e.type);
		}
 
		private function rightPressedListener (e:Event):void
		{
			trace(e.type);
		}		
		private function rightReleasedListener (e:Event):void
		{
			trace(e.type);
		}		
 
	}
 
}
Что касается игры, то события должен слушать класс (или его буфер), описывающий определенные догмы поведения - такая гибкость позволяет на различные отображаемые объекты вариативно накладывать различные схемы поведения и различные контроллеры, а не лепить все в одном классе.

Если есть вопросы по коду, спрашивайте - охотно отвечу, почему там так, а не иначе)))
__________________
скриптограф


Последний раз редактировалось orcpochta; 01.05.2010 в 00:49.