Форум 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=211792)

WaldeMar1321 07.11.2015 19:22

Клавиатура, мышь, слушатели событий.
 
Приятно времени суток всем. есть такой вопрос, внутри приложения должны быть непрекращающиеся события привязанные к клавиатуре и мыши. Но, при вызове "KeyboardEvent.KEY_DOWN", при удержании клавиши, сначала дергается объект в нужном направлении, потом замирает, а только потом едет как надо. Движение с комбинированными клавишами работает только в первом рывке. В чем проблема, кто-то знает как это решается?? С мышью еще хуже, событие "MouseEvent.MOUSE_DOWN" должно выполнятся пока кнопка нажата, и удерживается. но оно выполняется только в момент единичного нажатия. типа "CLICK".

udaaff 07.11.2015 19:28

К сожалению в AS3 нету такого свойства, которое бы позволяло получить состояние клавиши нажата/ненажата. Запоминайте состояние: нажали - едем (больше не слушаем событие), отпустили - не едем.

undefined 07.11.2015 19:30

В таких случаях при первом нажатии вешается слушатель ENTER_FRAME. и в нем события KEY_PRESSED/CLICK повторяются циклически и по KEY_RELEASED/MOUSE_UP удаляем ENTER_FRAME

ZackMercury 07.11.2015 19:35

Вот готовый класс by caseyryan для клавиатуры.
Код 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 = {};
 
                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 = {};
                }
        }
}

Пользоваться
Код AS3:

Key.initialize(stage);
//В обработчике ENTER_FRAME:
if(Key.isDown(Keyboard.W) || Key.isDown(Keyboard.UP))
obj.y -= 1;

Насчёт мыши вы неправы. Логически верно, что нажатие один раз, и отпускание один раз. Или вы не согласны?

EndoCrinologist 07.11.2015 19:52

Видел решение у одного разработчика:
Код AS3:

stage.addEventListener(Event.ENTER_FRAME, onStage);
stage.addEventListener(KeyboardEvent.KEY_DOWN, onDown);
stage.addEventListener(KeyboardEvent.KEY_UP, onUp);
 
function onDown(e:KeyboardEvent)
{
        keypressed[e.keyCode] = true;
}
function onUp(e:KeyboardEvent)
{
        keypressed[e.keyCode] = false;
}
function onStage(e:Event)
{
        var hero_dx = stage.mouseX - hero.x;
        var hero_dy = stage.mouseY - hero.y;
        var hero_grad = Math.atan2(hero_dy,hero_dx) * 180 / Math.PI;
        hero.rotation = hero_grad;
 
        if (keypressed[37] || keypressed[65]) hero.x -= speed;
        if (keypressed[38] || keypressed[87]) hero.y -= speed;
        if (keypressed[39] || keypressed[68]) hero.x += speed;
        if (keypressed[40] || keypressed[83]) hero.y += speed;
 
        if (hero.x > 800 + hero.width) hero.x = 0 - hero.width;
        if (hero.y > 600 + hero.width) hero.y = 0 - hero.width;
        if (hero.x < 0 - hero.width) hero.x = 800 + hero.width;
        if (hero.y < 0 - hero.width) hero.y = 600 + hero.width;
}


WaldeMar1321 08.11.2015 15:33

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

illuzor 08.11.2015 16:43

WaldeMar1321, найдите любое поле ввода, и зажмите любую буквенную клавишу на клавиатуре. Что происходит? Сначала появляется один символ, а через секунду символы появляются один за другим быстро. Вот и флешплеер обрабатывает нажатия так же.

ZackMercury 08.11.2015 17:08

WaldeMar1321, все события с устройств ввода делятся на 2 части - это начало и конец.
Например, событие клавиатуры KeyboardEvent.KEY_DOWN - это событие начала нажатия, а
KeyboardEvent.KEY_UP - это отпускание клавиши. То, что при длительном нажатии клавиши он
посылает событие многократно - неправильно с точки зрения логики, но с этим ничего не сделаешь.
MouseEvent.MOUSE_DOWN же работает исключительно правильно с точки зрения логики, он отсылается один раз при нажатии левой кнопки мыши, и соответствующее событие ловится при отпускании -
MouseEvent.MOUSE_UP.

Представьте, какие трудности ждали бы программиста, если бы всё работало не так.
Нужно, допустим, при нажатии на кнопку у клипа запустить анимацию, а при отпускании мыши - останавливать.

Пишем
Код AS3:

var clip:MovieClip = new MovieClip();//допустим, это наш клип.
var button:Button = new Button(); //допустим, это наша кнопка.
 
button.addEventListener(MouseEvent.MOUSE_DOWN, function(e:Event):void
{
  clip.gotoAndPlay(1);
});
button.addEventListener(MouseEvent.MOUSE_UP, function(e:Event):void
{
  clip.gotoAndStop(1);
});

Тут всё будет работать как надо, но что если бы вместо этого MOUSE_DOWN посылал бы событие каждый кадр? Ничего бы не работало.
Логика этих событий такова, что есть MOUSE_DOWN - начало нажатия, и есть MOUSE_UP - конец нажатия, и всё, что между ними можно делать в обработчике ENTER_FRAME.
Есть TouchEvent.TOUCH_BEGIN, а есть TouchEvent.TOUCH_END, что вызывается при нажатии на экран на сенсорном экране, и при отжатии.
Есть KeyboardEvent.KEY_DOWN, а есть KeyboardEvent.KEY_UP.

EndoCrinologist 08.11.2015 19:50

WaldeMar1321, а чем вам не угодило решение с добавлением полученного keyCode в массив?

WaldeMar1321 08.11.2015 23:09

наличие массива, там где он в принципе не нужен.

Zebestov 08.11.2015 23:33

Hello, Keyboard!


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

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