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

Appleman 06.11.2017 02:19

Цитата:

Сообщение от Wolsh (Сообщение 1202754)
1) У тебя же эти Меню создаются и уничтожаются по пять штук в минуту, КАК контроллер должен на них подписываться? Вью будет говорить контроллеру событием "я тут новое меню забабахала, подписывайся, лайкай"?

Я контроллер подписал на событие от _view. Ведь он должен всегда быть готовым поймать выбор пользователя... Но если имя события совпадает (как и получилось при отправке события MenuEvent), но контроллер его тоже ловит. Всплыло? Чтобы не путать события от меню во вью с событием от вью в контроллер, я создал ещё одну константу типа события в классе MenuEvent: MENU_COMMAND.

Сам ещё поразмыслил и переделал по классике. Но у меня ещё такой вопрос по ходу родился. Если у нас в одном методе меню создаётся, а в другом обрабатывается и убирается, то область видимости переменной, в которую записывается экземпляр меню, ограничена методом-создателем, и её не получается передать в метод, принимающий события от меню. В общем, вот так я выкрутился. Ниже кусок кода View. Это нормально?

Код AS3:

                private function showMenuHandler(event:Event) : void 
                {
                        var options : Array = MinigameModel(event.target).menuOptions;
                        var simpleMenu:SimpleMenu = new SimpleMenu(stage.width, stage.height - MAIN_TEXT_AREA_HEIGHT, options);
                        this.addChild(simpleMenu);
                        simpleMenu.addEventListener(MenuEvent.MENU_SELECT, menuSelectHandler);
                }
 
                private function menuSelectHandler (event: MenuEvent):void
                {
                        dispatchEvent (new MenuEvent(MenuEvent.MENU_COMMAND, event.id));
                        event.target.removeEventListener(MenuEvent.MENU_SELECT, menuSelectHandler);
                        this.removeChild(event.target as SimpleMenu);       
                }


Wolsh 06.11.2017 17:00

Цитата:

Это нормально?
В целом неплохо. Единственное, и ты сам чувствуешь что это костыль — иметь два типа для по сути одного события.. И проблема тут немного в другом месте — лучше бы иметь события класса ViewEvent и диспатчить из Вью именно их. Тогда и контроллеру не нужно будет импортить в себя ("знать") класс событий, которые распространяются внутри Вью. Безжалостная инкапсуляция не позволит контроллеру иметь доступ к внутренностям Вью через event.target.
Второй момент касается безопасности некоторых операций. Например, надо буквально завести себе привычку перед removeChild() ВСЕГДА проверять, есть ли парент и есть ли чайлд. Общепринятая конструкция выглядит так:
Код AS3:

if (displayObject.parent == this) this.removeChild(displayObject);

Даже когда тебе кажется что ну никак не может возникнуть ситуация, что меню не дитя Вью, иногда случаются совершенно волшебные казусы, вызванные особой очередностью выполнения обработчиков и кода текущего фрейма.

Ну и совсем в порядке ворчания — если начал писать this. то пиши его везде. Одинокий, висящий в воздухе "dispatchEvent" смотрится каким-то робким и неуверенным в себе. К слову, олдскульные холиварщики подняли бы тебя на смех, убеждая что здесь вообще не this., а строго super. Потому что писать this. надо исключительно перед твоими кастомными методами данного наследника, которых нет в супер-классе. А если вызываешь унаследованный от суперкласса метод, будь добр так и писать: super.addChild(), super.dispatchEvent() ;)

Appleman 06.11.2017 18:37

Цитата:

Сообщение от Wolsh (Сообщение 1202764)
В целом неплохо. Единственное, и ты сам чувствуешь что это костыль — иметь два типа для по сути одного события.. И проблема тут немного в другом месте — лучше бы иметь события класса ViewEvent и диспатчить из Вью именно их. Тогда и контроллеру не нужно будет импортить в себя ("знать") класс событий, которые распространяются внутри Вью. Безжалостная инкапсуляция не позволит контроллеру иметь доступ к внутренностям Вью через event.target.

Гы-гы. Я хотел одно событие в двух местах использовать и типа оптимизировать, а в итоге пришли к тому, что аж два разных класса наворотить пришлось. Забавно. Но логику я уловил, спасибо. Сейчас перепишем чуть-чуть. Получается, из модели во вью идут события одного класса, а из вью в контроллер - другого...

Цитата:

Ну и совсем в порядке ворчания — если начал писать this. то пиши его везде. Одинокий, висящий в воздухе "dispatchEvent" смотрится каким-то робким и неуверенным в себе. К слову, олдскульные холиварщики подняли бы тебя на смех, убеждая что здесь вообще не this., а строго super. Потому что писать this. надо исключительно перед твоими кастомными методами данного наследника, которых нет в супер-классе. А если вызываешь унаследованный от суперкласса метод, будь добр так и писать: super.addChild(), super.dispatchEvent() ;)
Если честно, я не до конца чувствую логику этих обращений: this, super. Во многих туториалах чуть ли не перед каждым выражением этот this прилеплен. Насколько я понял из того-же Мука, с т.з. корректной компиляции и выполнения, это в большинстве случаев не критично (где критично, компилятор скажет). Некоторые фишки без this не прокатывают, например, при установке экранных координат я не могу написать x=10 без this. Плюс для себя я пишу, например, в меню this.addChild(button), потому что меню буквально добавляет кнопки "в себя". Наивно, но я так лучше собственный код читаю.

Wolsh 06.11.2017 20:47

Когда-нибудь тебе доведется впервые написать не dispatchEvent() и даже не this.dispatchEvent(), а какой-нибудь stepper.buttonPlus.dispatchEvent(), и тогда ты прочувствуешь, что может быть и такое, и что у метода должен быть хозяин (ну, не всегда, но то отдельный разговор), а вызов метода без объекта-хозяина делает код похожим на функциональное программирование, а не на ООП. Когда ты привыкнешь мыслить объектами, умеющими делать то-то и то-то, а не функциями, тебе самому захочется всегда указывать, КТО делает вот ЭТО.

По поводу событий я уже говорил, что Меню не обязательно иметь собственный класс события, можно обойтись коробочным DataEvent, заведя пару констант для различения типов прямо в классе Меню.
То есть: new DataEvent(Menu.SELECT, ..., button.id);
Для Вью же, с его РАЗНООБРАЗИЕМ событий, иметь собственный класс событий положено по рангу.

Appleman 08.11.2017 10:02

Цитата:

Сообщение от Wolsh (Сообщение 1202764)
Например, надо буквально завести себе привычку перед removeChild() ВСЕГДА проверять, есть ли парент и есть ли чайлд. Общепринятая конструкция выглядит так:
Код AS3:

if (displayObject.parent == this) this.removeChild(displayObject);

Даже когда тебе кажется что ну никак не может возникнуть ситуация, что меню не дитя Вью, иногда случаются совершенно волшебные казусы, вызванные особой очередностью выполнения обработчиков и кода текущего фрейма.

Я вот что хотел по этому поводу уточнить... Какой кайф в использовании такой конструкции? Например, произошёл вот такой волшебный казус, и меню случайно осиротело и перестало считаться ребёнком Вью. Если не писать условий, то, я подозреваю, схватишь ошибку, что заставит сесть и разобраться, в чём косяк. А в твоём случае объект просто не удалится из списка отображения. И ищи-свищи, в чём проблема. Или я неправильно понимаю?

Wolsh 08.11.2017 12:55

Цитата:

что заставит сесть и разобраться, в чём косяк.
Не заставит. Ошибка будет в рантайме.
Цитата:

А в твоём случае объект просто не удалится из списка отображения.
Мой случай — это когда объект УЖЕ удалился из списка отображения на момент вызова removeChild(). В 99% случаев проблема не в том, что у него другой парент)) а в том что его удалили раньше или еще не добавляли в отображение.

Appleman 15.11.2017 16:17

Цитата:

Сообщение от Wolsh (Сообщение 1202244)
Шит в смысле "таблица", "сетка". Допустим у тебя 12 иконок для какого-то тулбара, все одного размера 24х24 пикселя.
Собираешь их на одной картинке вплотную друг к другу, допустим 4 иконки в ряду, 3 ряда. Шит.
Теперь тебе не надо 12 раз писать [Embed] и создавать 12 классов, эмбедишь только эту картинку.
В рантайме создаешь ее экземпляр и получаешь ссылку на битмапдату. В цикле как по двумерному массиву "нарезаешь" ее обратно на 12 картинок, каждую битмапдату 24х24 сохраняешь в массив. И когда надо отобразить, создаешь Битмап и передаешь ему нужную битмапдату из массива.

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

Пока имеем скачанный ShoeBox (с ним вроде всё понятно) и простенький ассет-менеджер, который умеет выдавать предварительно за-[embed]-женный Bitmap по строковому идентификатору. Понятно, что загруженный спрайтшит нарезаем на кусочки, BitmapData каждого помещаем в массив. В моём понимании это будет делать отдельный класс (или нет?). И главный вопрос, как наиболее удобно организовывать выбор нужного элемента? У меня пока модель выдаёт строковые идентификаторы (например, для нужной картинки с портретом). Как от них перейти к нужной битмапдате?

caseyryan 15.11.2017 16:57

Храни битмабы в Object или Dictionary. У них обоих допустимы строковые ключи. Я бы даже сказал, если ключи только строковые, то вполне хватит простого Object, в качестве ассоциативного массива


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

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