Форум Flasher.ru

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

goodguy 24.11.2010 11:51

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

К главному контейнеру, в котором происходят все боевые действия добавлены слуаштели KEY_UP и KEY_DOWN, ну и естественно обработчики событий.
Раньше игровая техника, солдаты и пр. управлялись мышкой, недавно добавил так же WASD управление + стрелки, ну и естественно контрол, шифт и т.п.
Чтобы не загромаждать классы транспорта обработчиками событий и не вешать лишних слушателей, все они обрабатываются в специальном классе-конструкторе, а в каждом транспортном средстве есть метод:
Код AS3:

public function setKeys(up:Boolean = false, down:Boolean = false, right:Boolean = false, 
                                                left:Boolean = false, space:Boolean = false, shift:Boolean = false, control:Boolean = false)

Действует такая конструкция отлично, за исключением клавишь shift и control.

Вот так обрабатываются нажатия клавишь в классе конструкторе:
Код AS3:

if (e.kif (e.keyCode == Keyboard.CONTROL) {
        _controlPressed = true;
        keyCheckTimer.start();
        pointer.pointer.gotoAndStop(2);// превращает курсор в прицел
        if (objectToMove.length >= 1) {
                if (objectToMove[0] is PlayerHeli) {
                        if (mouseDown) {
                                objectToMove[0].launchRocket();
                        }
                } else if (objectToMove[0] is PlayerTank) {
                        if (mouseDown) {
                                objectToMove[0].shoot();
                        }
                } else if (objectToMove[0] is PCN) {
                        if (mouseDown) {
                                objectToMove[0].shoot();
                        }
                } else if (objectToMove[0] is PSU) {
                        for (var i in objectToMove) {
                                if (mouseDown) {
                                        objectToMove[i].shoot();
                                }
                        }
                } else {
                        if (mouseDown) {
                                objectToMove[0].shoot();
                        }
                }
        }
} else {
        if (objectToMove[0] is PSU) {
                stopFire();
        }
}
if (e.keyCode == Keyboard.SHIFT) {
        _shiftPressed = true;
        keyCheckTimer.start();
}
if (e.keyCode == Keyboard.SPACE) {
        _spacePressed = true;
}
// ДО СЮДА ВЫПОЛНЕНИЕ КОНЕЧНО ДОХОДИТ, НО ЕСЛИ КОНТРОЛ НАЖАТ, ТО ПРОГРАММА НЕ ПОНИМАЕТ КОДА ДЛЯ КЛАВИШИ ВВЕРХ
if (e.keyCode == Keyboard.UP || e.keyCode == 87) {
        _upPressed = true;
}
if (e.keyCode == Keyboard.DOWN || e.keyCode == 83) {
        _downPressed = true;
}
if (e.keyCode == Keyboard.RIGHT || e.keyCode == 68) {
        _rightPressed = true;
}
if (e.keyCode == Keyboard.LEFT || e.keyCode == 65) {
        _leftPressed = true;
}
// посылание значений клавишь в транспортные средства. Остальное обрабатывается уже в их классах
if (!(objectToMove[0] is PSU)) {
        try {
                objectToMove[0].setKeys(_upPressed, _downPressed, _rightPressed,
                _leftPressed, _spacePressed, _shiftPressed, _controlPressed);
        } catch (e:Error) {
        }
}

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


Как ни старался, обойти этот косяк пока не удалось.
Если кто-то подскажет какое-то решение, буду безмерно благодарен.

И кстати, это происходит в дебаговом плеере. Если запустить в отдельном, то не работают стрелки влево и вправо, а вверх вниз начинат работать. Уже и не знаю куда копать..

iNils 24.11.2010 12:28

В обработчике у event может быть только одно значение keyCode, поэтому проверять на равность кода к контролу, а потом к другому коду - бесполезно.
Код:

KeyboardEvent(type:String, bubbles:Boolean = true, cancelable:Boolean = false, charCode:uint = 0, keyCode:uint = 0, keyLocation:uint = 0, [COLOR="rgb(0, 191, 255)"]ctrlKey:Boolean = false[/color], altKey:Boolean = false, shiftKey:Boolean = false)
Вам нужно проверять не код клавиши contrl, а зажата ли она, то есть ctrlKey = true.

Цитата:

Вот так обрабатываются нажатия клавишь в классе конструкторе:
Вот эта фраза вообще лишена всякого смысла.

И еще, не надо писать кучу отдельных if, надо писать if - else, иначе после первого же совпадения, вы в холостую будете продолжать сравнивать коды. А еще лучше для такого подойдет switch-case

goodguy 24.11.2010 12:56

iNils, не внимательно читаете ;)
Цитата:

иначе после первого же совпадения, вы в холостую будете продолжать сравнивать коды
Мне это и нужно. Пишу if, else if и при нажатии пробела джип останавливается, хотя должен начать стрелять из пулемета на ходу. if, if, if.. здесь - единственное верное решение. Управление происходит не в этом методе, и даже не в этом классе. Здесь лишь задается значение перменных ctrlPressd, upPressed и т.п. которые потом передаются в классы техники

Цитата:

поэтому проверять на равность кода к контролу, а потом к другому коду - бесполезно.
Допустим это так. Почему тогда работают зажатия, скажем стрелки вверх и влево одновременно, ну или вправо? Так же при нажатии шифта пробела стрелки продолжают нормально работать. Да и если обработку контрола поместить в самый последний блок, или вообще убрать, ничего не меняется.


Цитата:

А еще лучше для такого подойдет switch-case
Не лучше. Делал свитч, всё так же. Это чисто дело вкуса, на работу кода никак не влияет.


Цитата:

Вот эта фраза вообще лишена всякого смысла.
Фраза абсолютно не лишена смысла. Начало поста как раз это поясняет.


Цитата:

Вам нужно проверять не код клавиши contrl, а зажата ли она, то есть ctrlKey = true.
А вот это уже кое что. Спасибо за совет. Ушел испытывать :)

------------------ позже ------------
Нет, ничего не меняется :( Похоже это косяк флеш плеера, а не моего кода. Так как убираю из кода вообще все, что связано с контролом, и все равно клавиши перестают работать при нажатии ктрл

Добавлено через 50 минут
Проблема найдена! :)

Это действительно косяк флеш плеера, который исправлен в новой версии. Скачал с офсайта новый плеер и вуаля. Всё пашет!

Тему можно закрыть.

iNils 24.11.2010 14:00

goodguy, для того что бы внимательно читать, нужно код с нормальным форматирование выкладывать. Когда я вижу, что код смещен табуляций относительно первой строчки, то он автоматически считается вложенным.
Цитата:

Не лучше. Делал и свитч, ничего не меняется.
Лучше, потому обрабатывается быстрее и читается лучше. Но если есть ошибка, то конечно работать не будет.

Когда возникают подобные ошибки в большом коде, открываете новый проект и выносите туда проблемную часть в упрощенном виде. То есть вам нужно просто проверить реакцию на клавиши. Типа этого
Код AS3:

function down (e:KeyboardEvent):void {
        if (e.keyCode == Keyboard.CONTROL) {
                trace ("ctrl")
        } else {
                trace ("no ctrl")
        }
        switch (e.keyCode) {
                case Keyboard.SHIFT:
                        trace ("shift")
                        break;
                case Keyboard.SPACE:
                        trace ("space")
                        break;
                case Keyboard.UP:
                case 87:
                        trace ("up")
                        break;
                case Keyboard.DOWN:
                case 83:
                        trace ("down")
                        break;
                case Keyboard.RIGHT:
                case 68:
                        trace ("right")
                        break;
                case Keyboard.LEFT:
                case 65:
                        trace ("left")
                        break;
        }
}
stage.addEventListener (KeyboardEvent.KEY_DOWN, down);


Но я кажется понял в чем проблема. Вы наверно в Flash IDE разрабатываете, а там комбинация ctrl+стрелки перехватывается интерфейсом плеера. Вам нужно в меню плеера отключить это: Control > Disable Keyboard Shortcuts

goodguy 24.11.2010 15:13

Цитата:

Но я кажется понял в чем проблема. Вы наверно в Flash IDE разрабатываете, а там комбинация ctrl+стрелки перехватывается интерфейсом плеера.
Да, но это я знаю. Так же WASD управление не работает. Поэтому тестировал в standalone плеере.

Цитата:

То есть вам нужно просто проверить реакцию на клавиши. Типа этого
По отдельности все реагировало, всё портил только контрол.

Цитата:

goodguy, для того что бы внимательно читать, нужно код с нормальным форматирование выкладывать. Когда я вижу, что код смещен табуляций относительно первой строчки, то он автоматически считается вложенным.
Извиняюсь. Просто это копипаст из флеш девелоп :)

Цитата:

Вам нужно в меню плеера отключить это: Control > Disable Keyboard Shortcuts
Что-то не могу найти... (Flash CS4)
---- позже----
аа, так это в самом плеере, а я в ide ищу :D


Помогло! Спасибо! :) Теперь и в дебаговом плеере все работает

iNils 24.11.2010 15:25

standalone должны работать up и down, а left и right зарезервированы для управления.
попробуйте добавить
Код AS3:

flash.system.fscommand("trapallkeys", "true");



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

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