Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 29.01.2015, 01:10
djken вне форума Посмотреть профиль Отправить личное сообщение для djken Посетить домашнюю страницу djken Найти все сообщения от djken
  № 1  
Ответить с цитированием
djken
 
Аватар для djken

Регистрация: May 2010
Адрес: Краснодар
Сообщений: 182
Отправить сообщение для djken с помощью ICQ Отправить сообщение для djken с помощью Skype™
Question Вопрос об архитектуре приложения

Всем привет.

Например, у меня есть основной класс документа Main, где пишу весь основной скрипт.
В него вложена некая панель BlackList.
В панель вложено множество кнопок ItemBlackList.

Вопросы такие:
1. Правильно ли, что я в классе ItemBlackList подписываюсь на события MOUSE_OVER и MOUSE_OUT, а CLICK слушаю в его родительском классе BlackList ? Как я понимаю - дочерний объект не должен влиять на родителя. Как правильно разграничить действия между родителем и дочерними объектами - что должен знать родитель, а что его ребенок?

2. По нажатию на любой из ItemBlackList, в файл blacklist.xml должны записываться некие данные. Но этот XML файл подгружен в классе Main. Как правильнее делать - передавать данные через всю цепочку ItemBlackList -> BlackList -> Main ?? Или же Main не обязан знать что нужно делать с файлом, а всю работу с файлом должен брать на себя класс BlackList ??

Не знаю - правильно ли делать так?
И как в данном случае, например, узнать, какая из множества кнопок была нажата?

Класс Main:
Код AS3:
blackList = new BlackList();
addChild(blackList);
blackList.addEventListener("ITEM_BLACKLIST_CLICK", itemBlackListClick);
 
private function itemBlackListClick(e:Event):void {
	trace("ITEM CLICK");
}
Класс BlackList:
Код AS3:
itemBlackList = new ItemBlackList();
itemBlackList.addEventListener(MouseEvent.CLICK, itemClick);
 
private function itemClick(e:MouseEvent):void {
	dispatchEvent(new Event("ITEM_BLACKLIST_CLICK"));
}
__________________
кто не отвечает, того garbage collector забирает

Старый 29.01.2015, 03:22
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 2  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,922
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Вам не обязательно думать, что должен знать родитель, а что ребёнок.
Достаточно просто представить проект как список объектов/компонентов. Вы пользуетесь ихними методами и свойствами и вас абсолютно не интересует, как они устроены внутри.

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

Код AS3:
var checkBox:CheckBox = new CheckBox(true, true); //(активен, значение флажка)
checkBox.state = false; //снимаем галочку
checkBox.enabled = false; //делаем чекбокс неактивным
addChild(checkBox); //добавляем его в дисплейлист
 
trace(checkBox.state);
То же со скроллбаром, или к примеру кнопкой, слайдером, хп-мана-exp-барами,
Да, вполне логично, что
Цитата:
1. Правильно ли, что я в классе ItemBlackList подписываюсь на события MOUSE_OVER и MOUSE_OUT, а CLICK слушаю в его родительском классе BlackList ?
Но при этом приведённый выше чекбокс должен сам знать, что при клике по нему он должен менять свой state и визуальное отображение. При этом родитель может выполнять свои действия при клике на него, или наведении, подписываясь на клик снаружи.

PHP код:
2. По нажатию на любой из ItemBlackListв файл blacklist.xml должны записываться некие данныеНо этот XML файл подгружен в классе MainКак правильнее делать передавать данные через всю цепочку ItemBlackList -> BlackList -> Main ?? Или же Main не обязан знать что нужно делать с файлома всю работу с файлом должен брать на себя класс BlackList ?? 
В таком случае, слушать нажатие должен только класс, в котором хранятся ссылки на ItemBlackList.
Можно в BlackList отправлять событие, что была нажата кнопка и сохранять какая именно кнопка в публичную переменную.
Main пусть слушает BlackList и изменяет xml.
__________________
There is no thing in this world that is not simple.


Последний раз редактировалось ZackMercury; 29.01.2015 в 03:47.
Старый 29.01.2015, 10:50
callme вне форума Посмотреть профиль Отправить личное сообщение для callme Найти все сообщения от callme
  № 3  
Ответить с цитированием
callme
 
Аватар для callme

Регистрация: Dec 2014
Сообщений: 312
Допустим есть три кнопки. По нажатию на первую рисуем квадрат, на вторую - треугольник, на третью - круг.

На Main addChild спрайт. А уже на этот спрайт addChild панель.

Спрайт подписывается на события панели и рисует фигуры.
PanelEvents.DRAW_SQUARE
PanelEvents.DRAW_TRIANGLE
PanelEvents.DRAW_CIRCLE

Кнопка сама себя подписывает на CLICK. При клике диспатчит одно из событий панели.

Либо панель подписывает конкретную кнопку на CLICK (но не себя). При клике диспатчит одно из событий панели.

P.S.
Но если вам нужно в xml гнать просто текст на кнопке. То можно и саму панель подписать на клик.
Код AS3:
function onClick(e:MouseEvent):void
{
    dispatchEvent( new Event( MyButton(e.target).text ) );
}


Последний раз редактировалось callme; 29.01.2015 в 11:10.
Старый 29.01.2015, 14:59
djken вне форума Посмотреть профиль Отправить личное сообщение для djken Посетить домашнюю страницу djken Найти все сообщения от djken
  № 4  
Ответить с цитированием
djken
 
Аватар для djken

Регистрация: May 2010
Адрес: Краснодар
Сообщений: 182
Отправить сообщение для djken с помощью ICQ Отправить сообщение для djken с помощью Skype™
Как быть, если, например, вложенность намного больше и на самом главном уровне нужно ловить событие самого последнего вложенного объекта? На каждом уровне подписываться на событие ребенка и диспатчить его для родителя?
__________________
кто не отвечает, того garbage collector забирает

Старый 29.01.2015, 15:28
callme вне форума Посмотреть профиль Отправить личное сообщение для callme Найти все сообщения от callme
  № 5  
Ответить с цитированием
callme
 
Аватар для callme

Регистрация: Dec 2014
Сообщений: 312
Можно ловить событие, когда оно в фазе захвата.
Третий параметр в addEventListener().

Код AS3:
sprite1.addEventListener('someEvent', sprite1_someevent, true);
Код AS3:
package
{
    import flash.display.Sprite;
    import flash.events.Event;
 
    public class Main extends Sprite
    {
        public function Main()
        {
            var sprite1:Sprite = new Sprite();
            var sprite2:Sprite = new Sprite();
            var sprite3:Sprite = new Sprite();
            var sprite4:Sprite = new Sprite();
 
            addChild(sprite1);
            sprite1.addChild(sprite2);
            sprite2.addChild(sprite3);
            sprite3.addChild(sprite4);
 
            sprite1.addEventListener('someEvent', sprite1_someevent, true);
 
            sprite4.dispatchEvent( new Event('someEvent') );
        }
 
        private function sprite1_someevent(e:Event):void
        {
            trace("function sprite1_someevent()");
        }
    }
}

Старый 29.01.2015, 15:52
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 6  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Лучше, конечно же, продумывать приложение иерархически, чтобы Императору не приходилось звонить каждому солдату в окоп и уж тем более наоборот. Разделяйте ответственность, назначайте командиров, устанавливайте порядок и направление отчетности. У каждого должна быть своя зона ответственности, и она определяется еще на уровне выделения Класса как сущности. В мире флэш это конечно немного не так абстрактно, из-за обилия визуальных объектов возникает некая растерянность, к кому/к чему "привязывать" логику. Надо всё же как-то разделить действия, ответственность, чтобы кнопка "только нажималась", панель кнопок "только сообщала о выборе", а решения принимал тот, кто эту панель кнопок и создал для интерфейса с пользователем. Если у Вас Мейн должен знать все о какой-то тридевятой кнопке в тридесятом контейнере, значит Вы не разделили ответственность по объектам и Мейн перегружен. Ему нужны министры, а министрам — менеджеры, организовывающие персонал. Создавайте цепочки иерархии, компануйте однотипные задачи, не валите все в одну кучу Мейн.
__________________
Reality.getBounds(this);

Старый 29.01.2015, 16:30
callme вне форума Посмотреть профиль Отправить личное сообщение для callme Найти все сообщения от callme
  № 7  
Ответить с цитированием
callme
 
Аватар для callme

Регистрация: Dec 2014
Сообщений: 312
Цитата:
Сообщение от Wolsh Посмотреть сообщение
Лучше, конечно же, продумывать приложение иерархически, чтобы Императору не приходилось звонить каждому солдату в окоп и уж тем более наоборот.
Как избавиться от глобальных переменных?

Пример:

В библиотеке Starling есть хранилище ассетов. Я кладу этот объект в глобальную переменную потому что мне придется обращаться к этому хранилищу много где.

new MovieClip(globalAssetStore);

Можно передавать этот assetStore в конструкторы, которые передадут этот объект во вложенные конструкторы. Но код становится нечитабельным.

Старый 29.01.2015, 18:13
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 8  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,922
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
Цитата:
Кнопка сама себя подписывает на CLICK. При клике диспатчит одно из событий панели.
Что за ерунда? Где логика?
Кнопка не знает ничего о панели, она лишь знает свою функцию.
Можно вызывать callBack() внутри кнопки, на который сделать сеттер onClick = someFunc;
Но колбеки делают код неоднородным, а поэтому лучше подписываться на клик в двух местах - снаружи кнопки для того, чтобы знать, когда менять xml и внутри кнопки, чтобы к примеру менять визуальное отображение и состояние.

Предлагаю сделать ещё интересней,
Код AS3:
package 
{
	import flash.display.Sprite;
 
	/**
	 * ...
	 * @author ZackMercury
	 */
	public class Panel extends Sprite 
	{
		private static const OFFSET_BETWEEN_BUTTONS:int = 5;
 
		private var _buttons:Vector.<Button>;
 
		public function Panel()
		{
			_buttons = new Vector.<Button>();
		}
 
		public function addButton(caption:String, onClick:Function):void
		{
			var btn:Button = new Button(caption);
			btn.onClick = onClick;
			addChild(btn);
			_buttons.push(btn);
 
			update();
		}
 
		public function removeButton(caption:String):void
		{
			for (var i:int = 0; i < _buttons.length; i ++)
			{
				if (_buttons[i].caption == caption)
				{
					removeChild(_buttons[i]);
					_buttons.splice(i, 1);
				}
			}
 
			update();
		}
 
		private function update():void
		{
			for (var i:int = 0; i < _buttons.length; i ++)
			{
				_buttons[i].y = (_buttons[i].height + OFFSET_BETWEEN_BUTTONS) * i;
			}
		}
	}
 
}
Код AS3:
package 
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
 
	/**
	 * ...
	 * @author ZackMercury
	 */
	public class Main extends Sprite 
	{
		public function Main()
		{
			if (stage) init();
			else addEventListener(Event.ADDED_TO_STAGE, init);
		}
 
		public function init(e:Event = null):void
		{
			if (hasEventListener(Event.ADDED_TO_STAGE)) removeEventListener(Event.ADDED_TO_STAGE, init);
			//entry
			var panel:Panel = new Panel();
			panel.addButton("Start game", buttonClicked);
			panel.addButton("Exit", buttonClicked);
			panel.addButton("Options", buttonClicked);
			panel.removeButton("Options");
			addChild(panel);
		}
 
		private function buttonClicked(e:MouseEvent):void
		{
			switch((e.target as Button).caption)
			{
				case "Start game":
					//начинаем игру
					break;
				case "Exit":
					//выходим из игры
					break;
				default:
					throw new Error("No action for this button");
			}
		}
	}
}
__________________
There is no thing in this world that is not simple.


Последний раз редактировалось ZackMercury; 29.01.2015 в 22:39.
Старый 29.01.2015, 18:32
callme вне форума Посмотреть профиль Отправить личное сообщение для callme Найти все сообщения от callme
  № 9  
Ответить с цитированием
callme
 
Аватар для callme

Регистрация: Dec 2014
Сообщений: 312
to djken, я ошибся, надо делать как SuriTheAngel говорит.

Добавлено через 1 час 30 минут
SuriTheAngel
Мне кажется пусть лучше панель свои кнопки создает. Какие преимущества есть у твоего подхода?

Старый 29.01.2015, 21:17
ZackMercury вне форума Посмотреть профиль Отправить личное сообщение для ZackMercury Найти все сообщения от ZackMercury
  № 10  
Ответить с цитированием
ZackMercury
 
Аватар для ZackMercury

блогер
Регистрация: Jul 2013
Адрес: Север
Сообщений: 1,922
Записей в блоге: 23
Отправить сообщение для ZackMercury с помощью ICQ Отправить сообщение для ZackMercury с помощью Skype™
PHP код:
Какие преимущества есть у твоего подхода
Это не мой подход, а подход с точки зрения Объектно-Ориентированного Программирования. (ООП)
Преимущества. Даже лень перечислять...

1) Можно эту же панель не переписывая использовать в любых других проектах, ведь кнопки создаются через методы addButton() и удаляются через removeButton() снаружи панели.
2) Логично, что панель выполняет лишь свои функции - является панелью, в которую можно добавить кнопки или удалить из неё кнопки.
3) Логично, что кнопки являются кнопками и выполняют лишь свою функцию, не меняют никаких xml.
4) Конечно, В КРАЙНЕМ СЛУЧАЕ, НУ ВДРУГ НУ ВООБЩЕ ППЦ КАК НАДА БУДИТ, можно создавать кнопки в панели, используя её же методы из конструктора =) Для справки)
5) Скачав классы Panel, Button не нужно лезть внутрь этих классов, чтобы знать как ими пользоваться. Достаточно написать var panel:Panel = new Panel();
напишите
panel.
И среда(FlashDevelop) сама подсказывает, какие есть методы у этого класса. И из их названий точно и ясно, что они делают.
addButton() в переводе значит "добавить кнопку", для справки.
removeButton() в переводе "убрать кнопку".
набор передаваемых аргументов тоже достаточно ясно описан и подсказывается средой=)

взгляните на код
Код AS3:
public function init(e:Event = null):void
		{
			if (hasEventListener(Event.ADDED_TO_STAGE)) removeEventListener(Event.ADDED_TO_STAGE, init);
			//entry
			var panel:Panel = new Panel();
			panel.addButton("Start game", buttonClicked);
			panel.addButton("Exit", buttonClicked);
			panel.addButton("Options", buttonClicked);
			panel.removeButton("Options");
			addChild(panel);
		}
 
		private function buttonClicked(e:MouseEvent):void
		{
			switch((e.target as Button).caption)
			{
				case "Start game":
					//начинаем игру
					break;
				case "Exit":
					//выходим из игры
					break;
				default:
					throw new Error("No action for this button");
			}
		}
Разве из него не сразу ясно, что он делает? Задача программиста - упрощать себе работу, а не усложнять.
Поэтому мы пишем набор инструментов, подобно классу Button(кнопка) или Panel(панель).
При желании можно добавить классу Panel свойство orientation
и 2 константы - Panel.HORIZONTAL, Panel.VERTICAL.
Они будут определять, как будут располагаться кнопки - горизонтально или вертикально.
Вот так вот мы и работаем)
Улучшаем наши инструменты потихоньку.
Потом мы можем в любой проект сунуть эти классы и они будут работать.
Чтобы не копаться в их коде, мы пишем снаружи все обработчики кликов и пользуемся их свойствами и методами.

P.S. Если хотите проверить, как будет работать код - могу ещё дописать класс Button
__________________
There is no thing in this world that is not simple.


Последний раз редактировалось ZackMercury; 29.01.2015 в 22:39.
Создать новую тему Ответ Часовой пояс GMT +4, время: 19:33.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


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


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