Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Класс нажатия клавиш (http://www.flasher.ru/forum/showthread.php?t=208164)

Dmitriy154 10.06.2014 18:26

Класс нажатия клавиш
 
Подскажите! Вообще мозги отрофировались. Хочу сделать класс отслеживающий какие клавиши нажаты, а какие отпущены. Но каким образом другие классы могут получать эти данные? Посмотрите мой код для одной клавиши:
Код AS3:

package 
{
        import flash.display.DisplayObject;
        import flash.events.Event;
        import flash.events.KeyboardEvent;
        import flash.ui.Keyboard;
 
        public class MyKey extends DisplayObject
        {
                public var downKey:Boolean;
 
                public function MyKey()
                {
                        this.addEventListener(KeyboardEvent.KEY_DOWN,downK);
                }
 
                public function downK(e:KeyboardEvent):void
                {
                        trace("нажата клавиша");
                }
 
        }
 
}

Класс, который пытается узнать какая клавиша нажата
Код AS3:

package 
{
        import flash.display.MovieClip;
 
        public class ClassA extends MovieClip
        {
                public function ClassA()
                {
                        var myKey:MyKey = new MyKey();
                        trace(myKey.downKey);
                }
        }
}

В итоге мне приходит ответ: ArgumentError: Error #2012: Класс MyKey не может быть создан.
at ClassA()

А вообще, хочу сделать типа таблицу флагов нажатых клавиш, но как к ним обращаться из других классов??

silin 10.06.2014 22:27

такой, например, вариант: в 'статическом' классе держим список нажатых клавиш, ну и соответственно всегда можем узнать нажата та или иная клавиша
сам класс
Код AS3:

/*
 
  The MIT License,
 
  Copyright (c) 2011. silin (http://silin.su#AS3)
 
*/

package  silin.utils
{
        import flash.display.*;
        import flash.events.*;
 
        /**
        * отслеживание нажатых клавиш; <br/>
        * перед использованием обязателен вызов Key.register()
        * @author silin
        */

        public class Key
        {
                private static var _keys:Array = [];
                private static var _stage:Stage;
                private static var _enabled:Boolean = true;
 
                /**
                * не конструктор, экземпляры не создаем
                */

                public function Key()
                {
                        throw(new Error("Key is a static class and should not be instantiated."))
                }
                /**
                * привязка к stage <br/>
                * обязательный метод
                * @param        stage        ссылка на stage
                */

                public static function register(stage:Stage):void
                {
 
                        _stage = stage;
                        if (_enabled)
                        {
                                _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
                                _stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
 
                        }
 
 
                }
 
                private static function keyUpHandler(evnt:KeyboardEvent):void
                {
                        for (var i:int = 0; i < _keys.length; i++)
                        {
                                if (_keys[i] == evnt.keyCode) _keys.splice(i, 1);
                        }
                }
 
                private static function keyDownHandler(evnt:KeyboardEvent):void
                {
 
                        var key:int = evnt.keyCode;
 
                        for (var i:int = 0; i < _keys.length; i++)
                        {
                                if (_keys[i] == key) return;
                        }
                        _keys.push(key);
                }
 
                /**
                * нажата ли клавиша с кодом key
                * @param        key
                * @return
                */

                public static function isKeyDown(key:int):Boolean
                {
 
                        for (var i:int = 0; i < _keys.length; i++)
                        {
                                if (_keys[i] == key) return true;
                        }
                        return false;
                }
                /**
                * последняя нажатая клавиша, если все отпущены, то 0
                */

                public static function get lastPressed():int
                {
                        return _keys.length ? _keys[_keys.length - 1] : 0;
                }
 
                /**
                * включает/выключает прослушивание/сохранение нажатий клавиш
                */

                public static function get enabled():Boolean { return _enabled; }
                public static function set enabled(value:Boolean):void
                {
                        if (_enabled == value) return;
                        _enabled = value;
                        _keys = [];
                        if (_enabled)
                        {
                                _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
                                _stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
                        }else
                        {
                                _stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
                                _stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
                        }
                }
 
        }
 
}

пример использования
Код AS3:

package 
{
        import flash.display.Sprite;
        import flash.events.KeyboardEvent;
        import flash.ui.Keyboard;
        import flash.utils.describeType;
        import silin.utils.Key;
 
 
        public class Main extends Sprite
        {
                private var keyList:XMLList;
 
                public function Main():void
                {
 
                        // cписок клавиш
                        keyList = describeType(Keyboard).descendants("constant").(@type == "uint").@name;
 
                        Key.register(stage);
 
                        // при нажатии и отпусканиии смотрим
                        stage.addEventListener(KeyboardEvent.KEY_UP, stage_keyEvent);
                        stage.addEventListener(KeyboardEvent.KEY_DOWN, stage_keyEvent);
 
                }
 
 
                private function stage_keyEvent(e:KeyboardEvent):void
                {
 
                        var res:Array = [];
                        for ( var i:String in keyList )
                        {
                                var keyName:String = keyList[i];
                                if (Key.isKeyDown(Keyboard[keyName]))
                                {
                                        res.push(keyName);
                                }
                        }
                        if(res.length)trace(res + " is pressed");
                }
 
 
        }
 
}

зы. больше 3..4 нажатых клавиш не получится отслеживать, но это проблема не флеша, а клавиатуры

ObOs 11.06.2014 10:35

Не понятен смысл вот этой проверки в слушателе keyDownHandler
Цитата:

Сообщение от silin (Сообщение 1167677)
Код AS3:

 
        for (var i:int = 0; i < _keys.length; i++)
        {
                if (_keys[i] == key) return;
        }


Как код нажатой в данный момент клавиши может находится в списке нажатых клавиш(_keys), если при отпускании клавиши он у вас из этого списка удаляется.

Код AS3:

 
private static function keyUpHandler(evnt:KeyboardEvent):void
{
        for (var i:int = 0; i < _keys.length; i++)
        {
                if (_keys[i] == evnt.keyCode) _keys.splice(i, 1);
        }
}

Получается что клавишу можно нажать повторно еще не отпустив:wacko:

silin 11.06.2014 16:49

дада, скорее всего вы правы и проверка лишняя
а может и не лишняя, я сейчас не могу вспомнить откуда она взялась, но клавиатуры при нажатии сразу нескольких клавиш не всегда понятно что выдают, может отсюда. а может тупо перестраховался

caseyryan 11.06.2014 19:08

Есть вариант по-проще
Код AS3:

package {
 
        import flash.display.Stage;
        import flash.events.Event;
        import flash.events.KeyboardEvent;
 
        public class Key {
 
                private static var initialized:Boolean = false;               
                private static var keysDown:Object = new Object();       
 
                public static function initialize(stage:Stage):void {
                        if (!initialized) {
                                stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
                                stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
                                stage.addEventListener(Event.DEACTIVATE, clearKeys);
                                initialized = true;
                        }
                }
 
                public static function isDown(keyCode:uint):Boolean {
                        if (!initialized) {
                                throw new Error("Key class has not yet been initialized.");
                        }
                        return Boolean(keyCode in keysDown);
                }
                private static function keyPressed(event:KeyboardEvent):void {
                        keysDown[event.keyCode] = true;
                }
                private static function keyReleased(event:KeyboardEvent):void {
                        if (event.keyCode in keysDown) {
                                delete keysDown[event.keyCode];
                        }
                }
 
                private static function clearKeys(event:Event):void {
                        keysDown = new Object();
                }
        }
}

Используется так:
Код AS3:

// в документ классе
Key.initialize(stage);
 
// а в любом другом месте проверяем
trace(Key.isDown(Keyboard.SPACE));

Цитата:

Как код нажатой в данный момент клавиши может находится в списке нажатых клавиш(_keys), если при отпускании клавиши он у вас из этого списка удаляется.
Могу предположить, что при потере фокуса с флешки. И второй вариант, который постоянно происходит в хроме, залипание клавиши

LifeIsRhythm 11.06.2014 20:52

Мне вот всегда интересно, почему используют Object, который переводит keyCode в String,
когда можно использовать более подходящий для этого Dictionary.

Dmitriy154 11.06.2014 21:37

спасибо вам!

caseyryan 12.06.2014 15:34

Цитата:

Сообщение от LifeIsRhythm (Сообщение 1167712)
Мне вот всегда интересно, почему используют Object, который переводит keyCode в String,
когда можно использовать более подходящий для этого Dictionary.

Здесь это не принципиально, явно этот класс не самое слабое место в программе). Но если быть совсем дотошным, и пытаться выжать максимум везде, то да, лучше заменить на Dictionary

Wolsh 12.06.2014 16:09

Цитата:

Получается что клавишу можно нажать повторно еще не отпустив
Естественно. Нажмите и не отпускайте. Через секунду событие нажатия начнет генерироваться автоматически.
Как Вы делаете, когда надо получить ----------------------------------------------------

Dmitriy154 12.06.2014 17:29

caseyryan - не получается trace(Key.isDown(Keyboard.SPACE)); пишет ошибку - Обращение несуществующего свойства Keyboard.


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

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