В первом посте все четко было сказано:
"Сразу пример, чтобы легче представить: в игре слушает нажатия различных кнопок, отфильтровывает из них кнопки 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);
}
}
}
Что касается игры, то события должен слушать класс (или его буфер), описывающий определенные догмы поведения - такая гибкость позволяет на различные отображаемые объекты вариативно накладывать различные схемы поведения и различные контроллеры, а не лепить все в одном классе.
Если есть вопросы по коду, спрашивайте - охотно отвечу, почему там так, а не иначе)))