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

FieryWall 04.05.2011 20:57

Управление меню как на консолях
 
Очень рад что flesh контент все более догоняет возможности консолей. Задача проста, но из за недостатка материала мне с ней справится за короткое время трудно.
Необходимо реализовать переключение между кнопками меню фокуса и нажатия по ним Enter как альтернативу курсору и кликам. Основные проблемы:

1.Переключатся необходимо в приделах вибронного мувиклипа;
2.Выбрать простейшую схему для вызова события по нажатию Enter над определенной кнопкой;
3.Убрать чудной желтый квадрат, что указывает позицию фокуса;
4.Переключение зависит от клавиш left и right;

Код AS3:

if (interfac.pouse_mc.visible == true) {
                                if (left || right) {
                                        if (stage.focus == interfac.pouse_mc.restart_btn) {
                                                stage.focus = interfac.pouse_mc.gallery_btn;
                                                stage.focus.addEventListener(KeyboardEvent.KEY_DOWN, returnToGallery);
                                        }else {
                                                stage.focus = interfac.pouse_mc.restart_btn;
                                                stage.focus.addEventListener(KeyboardEvent.KEY_DOWN, restartLevel);
                                        }
                                        left = right = false;
                                }
                        }

это, мягко говоря, не правельно =)
И вообще, я прошу только объяснить пару моментов, которые я навел выше
Заранее благодарен:drinks:

КорДум 04.05.2011 21:01

Вам в вакансии, похоже. Если нет - выкладывайте то, что вы уже пробовали.

FieryWall 04.05.2011 21:03

Цитата:

Сообщение от КорДум (Сообщение 993939)
Вам в вакансии, похоже. Если нет - выкладывайте то, что вы уже пробовали.

Пардон, сейчас добавлю :rolleyes:

...или мне разделить это на четыре темы? :(

gloomyBrain 04.05.2011 21:20

Код AS3:

 // отключаем  желтый прямоугольник
super.stage.stageFocusRect = false;
 // отключаем обход объектов по клавише TAB
super.stage.tabChildren = false;

Далее, внутри нашего мувика создаем очередь (массив) из доступных для обхода контролов. Либо предоставляем интерфейс для их обхода извне (типа mc.focusNext(), mc.focusPrev() и в момент вызова делаем super.stage.focus(нужнаяКнопка)). Так же в момент передачи фокуса подсвечиваем кнопку как нам надо.
Соответственно, должен быть какой-то контроллер, который бы переключался между клипами и у нужного клипа вызывал бы focusPrev() и focusNext(), а в момент выхода из клипа - что-то типа unfocusAll()

FieryWall 04.05.2011 21:56

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

private function inPousePanel():void 
                {
                        super.stage.focus = interfac.pouse_mc.restart_btn;
                        addEventListener(KeyboardEvent.KEY_DOWN, keyFocus);
                }
 
private function keyFocus(e:KeyboardEvent):void
{
        if (e.keyCode == 37) {
                switch(super.stage.focus) {
                        case interfac.pouse_mc.restart_btn:super.stage.focus = interfac.pouse_mc.gallery_btn; break;
                        case interfac.pouse_mc.gallery_btn:super.stage.focus = interfac.pouse_mc.help_btn; break;
                        case interfac.pouse_mc.help_btn:super.stage.focus = interfac.pouse_mc.resume_btn; break;
                        case interfac.pouse_mc.resume_btn:super.stage.focus = interfac.pouse_mc.restart_btn; break;
                }
        }
        if (e.keyCode == 39) {
                switch(super.stage.focus) {
                        case interfac.pouse_mc.restart_btn:super.stage.focus = interfac.pouse_mc.resume_btn; break;
                        case interfac.pouse_mc.resume_btn:super.stage.focus = interfac.pouse_mc.help_btn; break;
                        case interfac.pouse_mc.help_btn:super.stage.focus = interfac.pouse_mc.gallery_btn; break;
                        case interfac.pouse_mc.gallery_btn:super.stage.focus = interfac.pouse_mc.restart_btn; break;
                }
        }
        if (e.keyCode == 13) {
                switch(super.stage.focus) {
                        case interfac.pouse_mc.restart_btn:restartLevel(); break;
                        case interfac.pouse_mc.gallery_btn:returnToGallery(); break;
                        case interfac.pouse_mc.help_btn:; break;
                        case interfac.pouse_mc.resume_btn:resumeGame(); break;
                }
        }
}

Смысл:
При открытии окна вызывается функция "inPousePanel", в ней ставится фокус на самую часто-кликуемую кнопку и цепляется событие нажатия на клавиатуру, т.е лево - 37, право - 39 и ентер - 13. Когда мы нажимаем одну из них, меняется фокус или запускается функция кнопки, в зависимости от кнопки над которой фокус.

И оно работает! Теперь осталось только написать то же самое тля окон "Конец игры" и "Уровень пройден" и самое сложное "Меню и галрея" - где 19 кнопок :wacko:
Как думаете, можно упростить?

gloomyBrain 04.05.2011 22:34

Примерно так
Код AS3:

package {
 
        import flash.display.InteractiveObject;
        import flash.display.Sprite;
        import flash.events.KeyboardEvent;
        import flash.utils.Dictionary;
 
        /**
        * @author gloomyBrain
        */

        public class Main extends Sprite {
 
                private const _buttons:Vector.<InteractiveObject> = Vector.<InteractiveObject>([
                        myButton_1,
                        myButton_2,
                        myButton_3, // тут просто список кнопок
                        myButton_4,
                        myButton_5
                ]);
 
                // это текщая выбранная кнопка
                private var _selectedButton:InteractiveObject = null;
 
                // это словарь соответсвий между кнопками и вызываемыми действиями
                private const _handlers:Dictionary = new Dictionary();
 
                public function Main() {
 
                        // задаем соответствия кнопка - функция
                        _handlers[myButton_1] = myFunction_1;
                        _handlers[myButton_2] = myFunction_2;
                        _handlers[myButton_3] = myFunction_3;
                        _handlers[myButton_4] = myFunction_4;
                        _handlers[myButton_5] = myFunction_5;
 
                        // добавляем всем кнопкам слушатели клавиатуры
                        var len:int = _buttons.length;
                        while (len--) {
                                _buttons[len].addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
                        }
 
                }
 
                private function onKeyDown(event:KeyboardEvent):void {
 
                        switch (event.keyCode) {
 
                                case 37:
                                        // выбираем следующую кнопку
                                        this.focusNext(true);
                                break;
 
                                case 37:
                                        // выбираем предыдущую кнопку
                                        this.focusNext(false);
                                break;
 
                                case 13:
 
                                        // ищем в словаре действие для данной кнопки
                                        var handler:Function = _handlers[event.currentTarget];
                                        if (!handler) return;
 
                                        // выполняем действие, если нашли
                                        handler.call();
 
                                break;
 
                        }
 
                }
 
                /**
                * Выделить следующую кнопку
                *
                * @param        forward        true, если двигаемся вперед, false если назад
                */

                public function focusNext(forward:Boolean = true):InteractiveObject {
 
                        // если сейчас никто не выбран, то будет выбрана первая кнопка
                        // этот метод можно вызывать извне
                        if (!_selectedButton) {
 
                                _selectedButton = _buttons[0];
 
                        }else {
 
                                // получаем индекс следующей кнопки (в зависимости от направления движения)
                                var index:int = _buttons.indexOf(_selectedButton);
                                index += (int(forward) * 2) - 1; // -1 или +1
 
                                if (index === _buttons.length) {
                                        index = 0;
                                }else if (index < 0) {
                                        index = _buttons.length - 1;
                                }
 
                                // выбираем нужную кнопку
                                _selectedButton = _buttons[index];
                        }
 
                        super.stage.focus(_selectedButton);
                        return _selectedButton;
 
                }
 
                private function myFunction_1():void {
                        // обработчик кнопки 1
                }
 
                private function myFunction_2():void {
                        // обработчик кнопки 2
                }
 
                private function myFunction_3():void {
                        // обработчик кнопки 3
                }
 
                private function myFunction_4():void {
                        // обработчик кнопки 4
                }
 
                private function myFunction_5():void {
                        // обработчик кнопки 5
                }
 
        }
 
}


Wolsh 04.05.2011 22:36

Для начала сделали бы короткие ссылки на клипы – ладно Вам трудно читать, но и плееру придется бегать по всем закоулкам, проверяя Ваши условия.
Как-то так:
Код AS3:

private function keyFocus(e:KeyboardEvent):void 
{
        var restart:MovieClip = interfac.pouse_mc.restart_btn;
        var gallery:MovieClip = interfac.pouse_mc.gallery_btn;
        var help:MovieClip = interfac.pouse_mc.help_btn;
        var resume:MovieClip = interfac.pouse_mc.resume_btn;
        var focus:InteractiveObject = super.stage.focus;
 
if (e.keyCode == 37) {
                switch(focus) {
                        case restart : focus = gallery; break;
                        case gallery : focus = help; break;
                        case help : focus = resume; break;
                        case resume : focus = restart; break;
                }
        }
        if (e.keyCode == 39) {
                switch(focus) {
                        case restart : focus = resume; break;
                        case resume : focus = help; break;
                        case help : focus = gallery; break;
                        case gallery : focus = restart; break;
                }
        }
        if (e.keyCode == 13) {
                switch(focus) {
                        case restart : restartLevel(); break;
                        case gallery : returnToGallery(); break;
                        case help : ; break;
                        case resume : resumeGame(); break;
                }
        }
        super.stage.focus = focus;
}


FieryWall 04.05.2011 22:36

Спасибо :yahoo:
Wolsh, полезная информация, я дурак всегда пути расписываю, думал плееру не трудно их просматривать.


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

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