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

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

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 27.12.2017, 16:14
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 91  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
Соответственно, Модель не "знает" что в том или ином случае нужно использовать KnifeActions, WalkAction или TalkAction.
а зачем ей знать, напомни?
Из твоего вопроса непонятно где затык. Модель получает выбранный Action, в нем есть персонажи, есть ActionData и единый метод intiate(). А что еще надо?
__________________
Reality.getBounds(this);

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

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Я планировал реализовывать через наследование различные типы действий, чтобы был некий базовый Action и его наследники, переопределяющие метод initiate(). А затык в том, что все экземпляры Action, из которых выбирает пользователь, создаются самой моделью в рантайме. Вот в частности здесь:

Код AS3:
public function pickActions() : Vector.<Action>
		// Подбирает доступные для игрока в данный момент действия
		{
			var newAction: Action;
			var availableActions: Vector.<Action> = new Vector.<Action>;
 
			for each (var actionData: ActionData in _allActions)
			{	
				newAction = new Action(actionData, heroModel, enemyModel);
				if (newAction.testCriticalConditions()) availableActions.push(newAction);
 
				newAction = new Action(actionData, enemyModel, heroModel);
				if (newAction.testCriticalConditions()) availableActions.push(newAction);
				}
			}
			return availableActions;
		}
Поэтому когда модель "пробегает" все шаблоны действий, она не может "выбирать" нужного наследника класса Action.

Теоретически можно было бы запилить туда выбор в зависимости от того, к какому классу принадлежит actionData, примерно вот так:

Код AS3:
if (actionData is ActionDataTalk) newAction = new TalkAction(actionData, heroModel, enemyModel);
else if (actionData is ActionDataFight) newAction = new FightAction(actionData, heroModel, enemyModel);
Но по-моему, это жуткая ересь и надругательство над самой идеей ООП

В отличие от экземпляров Action, экземпляры ActionData делаются вручную мною, созданные по ним шаблоны будущих действий попадают в вектор, записанный в переменную _allActions. В принципе, можно их наследовать с учётом специфики тех или иных видов игровых действий и их обработки. Но там - лишь "статические" данные: базовый урон, длительность действия и т.п. Производить какие-то расчёты в ActionData мне чисто философски представляется неправильным. Хотя, возможно, я и ошибаюсь. Чисто технически метод initiate() хорошо переопределяется внутри наследников ActionData.

В этом случае в классе Action пишем:

Код AS3:
public function initiate()
{
_actionData.initiate(ch1: Character, ch2: Character);
}
__________________
Не сломано - не чини!


Последний раз редактировалось Appleman; 27.12.2017 в 18:27.
Старый 27.12.2017, 20:07
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 93  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Ну не знаю.. чтобы не трогать структуру на данный момент, я бы просто сгруппировал ActionData не в один вектор "всеЭкшенДаты" а несколько, соответствующих подтипам Action'ов, и соотв. проверял/создавал экшены не в одном цикле, а в нескольких, таким образом зная, какого типа Экшен должен быть создан для данной ЭкшенДата. Потому что, по сути у тебя ЭкшенДата "как бы" имеет подклассы, но они "предполагаемые" а не реализованные. Это типы не "я являюсь ..." а "я предназначен для использования в ...".
__________________
Reality.getBounds(this);

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

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Да, на счёт предназначения - всё верно. Вот только если брать за основу предложенный тобой способ, не совсем понятно, чем это лучше по сравнению с описанным мной вариантом проверки каждого обрабатываемого экземпляра ActionData на принадлежность тому или иному подклассу. Ведь придётся также каждый вектор по очереди спрашивать "кто здесь", и по результату выбирать нужный подкласс Action. Те же в профиль.

По уму нужно как-то изголиться и сделать типа "полиморфное создание", когда подкласс объекта определяет тип вновь создаваемого другого объекта, частью которого он будет.

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

Добавлено через 15 минут
Да, или как вариант вообще забить на эти ActionDat-ы, и делать сразу Action-ы, но без действующих лиц. И добавить отдельный метод для "регистрации" и тестирования в нём персонажей и уже initiate/execute для запуска готового варианта. Тогда проблема вроде бы решается сама собой, но класс более муторный получается. Будет приличное количество сеттеров-геттеров болтаться вместе с методами обработки и расчётов. Уж очень мне понравилась идея делать отдельно ActionData и "подключать" её к будущему классу действия. Выходит очень наглядно и компактно, только, как выясняется, не супер-технологично, увы.

Добавлено через 38 минут
...извините, я как акын - ещё подумал, ещё написал. Я наверное вообще не прав в той части, что все "статичные" данные создаю и храню как свойства класса. В контексте действий - это вся ActionData: статусы персонажей, базовый урон, дистанция, условия и т.п. Приходится сеттеры-геттеры для них плодить, волноваться за их случайное изменение. Может быть есть хорошие варианты, как можно удобно хранить и быстро вытаскивать "статические" свойства, неизменные на всём протяжении работы программы? Object-ы и XML пока скорее не понравились.
__________________
Не сломано - не чини!


Последний раз редактировалось Appleman; 27.12.2017 в 21:56.
Старый 27.12.2017, 22:32
Wolsh вне форума Посмотреть профиль Отправить личное сообщение для Wolsh Найти все сообщения от Wolsh
  № 95  
Ответить с цитированием
Wolsh
Нуб нубам
 
Аватар для Wolsh

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
не совсем понятно, чем это лучше.. проверки каждого ActionData на принадлежность тому или иному подклассу.
Насколько я понял, никаких подклассов ActionData сейчас нет. И не надо.

Цитата:
Ведь придётся также каждый вектор по очереди спрашивать "кто здесь", и по результату выбирать нужный подкласс Action
Зачем спрашивать, если он заранее известен? Все даты для ActionTalk лежат в векторе _actionTalkData, а все для ActionKnife — в _actionKnifeData? Ты же даты создаешь "руками" и я так полагаю знаешь, какие для чего? Ну так и распихивай их сразу в нужные вектора и потом
Код AS3:
//// T A L K
for each (var actionData:ActionData in _actionTalkData)
{	
	newAction = new ActionTalk(actionData, heroModel, enemyModel);
	if (newAction.testCriticalConditions()) availableActions.push(newAction);
}
//// K N I F E
for each (var actionData2:ActionData in _actionKnifeData)
{	
	newAction = new ActionKnife(actionData2, heroModel, enemyModel);
	if (newAction.testCriticalConditions()) availableActions.push(newAction);
}
К тому же появляется возможность не шустрить неуместные типы действий, типа "а поговорить?" во время боя..

Цитата:
По уму нужно как-то изголиться и сделать типа "полиморфное создание"
Есть такой паттерн — Фабрика, очень популярный. Но навскидку не скажу, подходит ли он здесь технически, почитай сам.

Цитата:
Приходится сеттеры-геттеры для них плодить, волноваться за их случайное изменение.
Ну так для того геттеры-сеттеры и разделили, что в отличие от просто public var ты можешь разрешить только один доступ из двух. Не делай сеттеры, и никто не сможет изменить данные, только читать их (read-only) через геттер. Но тогда задавать их придется только в конструкторе, что конечно неудобно когда их два десятка... но посмотри например конструктор TextFormat'а: там дофигища параметров.
__________________
Reality.getBounds(this);


Последний раз редактировалось Wolsh; 27.12.2017 в 22:52.
Старый 27.12.2017, 23:55
Appleman вне форума Посмотреть профиль Отправить личное сообщение для Appleman Найти все сообщения от Appleman
  № 96  
Ответить с цитированием
Appleman
 
Аватар для Appleman

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Wolsh, спасибо. Понял, что ты имел в виду. Я написал, что "спрашивать", потому что нужно же ещё как-то передать весь список в Модель. Вот я подумал, что все эти векторы соберём в ещё один массив и будем по одному доставать и идентифицировать. Согласись, что если подклассов будет не 2 как в примере, а 22, то нужно для каждого по переменной забабахать в Модели - все эти _actionWalkData... Те ещё костыли. Буду думать, в общем.

Не хочется себя сковывать в количестве подклассов. Пока склоняюсь к собственному варианту сделать сразу единые и неделимые Action-ы, которые будут сами себе и data, и model. Не очень правда понимаю, чем мне это ещё отольётся. Уже вижу слабое место такого подхода в сравнении с существующим. Сейчас каждое действие создаётся каждый раз заново - с чистого листа. А если юзать постоянно одни и те же объекты, меняя в них действующих лиц, то хрен его знает, какие "хвосты" там будут оставаться после каждой итерации...
__________________
Не сломано - не чини!


Последний раз редактировалось Appleman; 28.12.2017 в 00:14.
Старый 28.12.2017, 17:15
Godwarlock вне форума Посмотреть профиль Отправить личное сообщение для Godwarlock Найти все сообщения от Godwarlock
  № 97  
Ответить с цитированием
Godwarlock

Регистрация: Jan 2012
Сообщений: 836
Wolsh
Цитата:
Не делай сеттеры, и никто не сможет изменить данные, только читать их (read-only) через геттер
Есть программы по типу ArtMoney, для изменения значения переменных. Это гарантирует защиту от них всех?

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

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Речь шла вообще о другом, о разработке. Под "никто" имелось ввиду "из коллег" или "по пьяни".
__________________
Reality.getBounds(this);

Старый 29.12.2017, 16:32
Godwarlock вне форума Посмотреть профиль Отправить личное сообщение для Godwarlock Найти все сообщения от Godwarlock
  № 99  
Ответить с цитированием
Godwarlock

Регистрация: Jan 2012
Сообщений: 836
Wolsh то есть по сути в геттерах и сеттерах вообще никакого смысла нет почти. Исключение, разве что если после присвоения или чтения определенной записи, нужно выполнить какое-то дополнительное действие внутри set/get. Во всяком случае у меня так стоит с обновлением игровой валюты. Через set изменяю значение, а потом делаю диспатч там же, чтобы произвести изменения во вью.

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

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

Создать новую тему Ответ Часовой пояс GMT +4, время: 23:09.
Быстрый переход
  « Предыдущая тема | Следующая тема »  
Опции темы
Опции просмотра

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

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


 


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


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