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

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

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

Регистрация: Dec 2009
Сообщений: 125
Записей в блоге: 1
По умолчанию Изменение свойств одного объекта через методы другого объекта

Пример из игры. Мы собираем кристаллы и счетчик кристаллов это фиксирует. Кристаллы - это экземпляр одного класса, счетчик - другого.

Как в практике правильного ООП реализуется взаимодействие двух объектов разных классов?

1. Я могу добавлять прослушиватель в их родителе и управлять свойствами детей из родителей:

родительский класс Main
Код AS3:
kristall.addEventListener(MouseEvent.CLICK, growCounter);
 
public function growCounter (e) {
  counter.grow(kristall.num);
}
Здесь мне не нравится, что много прослушивателей, много кода - все будет записано в родительском классе, а хотелось бы все записать в детей. Но я не знаю, как это делается правильно и проще...

2. Я могу передавать параметром один объект в другой и осуществлять управление там:

родительский класс Main
Код AS3:
var kristall = new Kristall(counter);
класс Kristall
Код AS3:
this.counter = counter;
addEventListener(MouseEvent.CLICK, collect);
 
public function collect (e) {
 this.counter.grow(this.num)
}
Здесь мне не нравится, передача в параметр друг другу объектов. Может сложиться ситуация, когда объект в параметре должен будет поменяться, и опять же управлять свойством прийдется из родителя.

Может и правда все управление нужно из родителя делать? Или есть еще более правильные принципы ООП? Как вообще в играх это делается?

Старый 06.05.2012, 11:37
alexxus вне форума Посмотреть профиль Отправить личное сообщение для alexxus Найти все сообщения от alexxus
  № 2  
Ответить с цитированием
alexxus

Регистрация: Dec 2010
Сообщений: 16
Как расширенный вариант первого примера:
В Main пишем 1 слушатель.
Код AS3:
this.addEventListener(MouseEvent.CLICK, growCounter);
 
public function growCounter (e) {
 if(e.target is CKristall)
  counter.grow(Ckristall(e.target).num);
}
А вот по-поводу ссылки на объект Counter в CKristall, как-то лишает CKristall самодостаточности =)


Последний раз редактировалось udaaff; 06.05.2012 в 13:15.
Старый 06.05.2012, 11:42
КорДум вне форума Посмотреть профиль Отправить личное сообщение для КорДум Найти все сообщения от КорДум
  № 3  
Ответить с цитированием
КорДум
 
Аватар для КорДум

блогер
Регистрация: Jan 2008
Адрес: syktyvkar
Сообщений: 3,803
Записей в блоге: 10
Цитата:
а хотелось бы все записать в детей
И это как раз-таки неправильно в корне.
Дите диспатчит событие TAKE_CRYSTAL например, родитель (в Вашем случае Main) ловит его, меняет счетчик у другого дитя.
А вообще, посмотрите в сторону MVC и его упрощенных вариаций.
__________________
тут я

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

Регистрация: Dec 2009
Сообщений: 125
Записей в блоге: 1
alexxus, мне нравится это направление - таким образом можно универсализировать функцию growCounter главного класса, чтобы отвечать вообще на любой клик в игре.

КорДум, я что-то такое и желал услышать. Значит, правильный подход управлять всеми объектами из родителя. Насчет mvc много раз встречал на форуме и читал в википедии его принципы пару раз. Как-то не дается пониманию. Начинающему легче видеть частные случаи, чем глобальные принципы ООП.

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

Допустим так:

главный класс
Код AS3:
  var obj:Object = {}; //объект в свойствах главного класса
 
public function Main () {
  var counter:Counter = new Counter(obj);
  this.obj.counter = counter;
  var kristall:Kristall = new Kristall(obj);
  this.obj.counter = counter;
 }
Бред?.. Или даже вообще не сработает?

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

блогер
Регистрация: Oct 2005
Адрес: Днепродзержинск - город Брежнева и других логопедов
Сообщений: 1,421
Записей в блоге: 4
Отправить сообщение для -De- с помощью ICQ Отправить сообщение для -De- с помощью Skype™
Почему-бы counter и kristall не сделать св-вами класса Main, чем извращаться через obj?
Заодно вы получите строгую типизацию (собсно НЕ строгая типизация - это плохо обычно).
Но лучше и такого не делать, обьект, хранящий в себе всё, называется god object. Не делайте такого, путано получается.
__________________
Бобры отвечают на вопросы не потому, что знают на них ответы; они отвечают потому, что их спрашивают.

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

Регистрация: Dec 2009
Сообщений: 125
Записей в блоге: 1
- Потому что я не смогу из kristall'а поменять что-то в counter. Мне все равно прийдется их либо передавать параметрами, либо работать с ними из главного класса

Статья о божественном объекте объясняет, почему я не хочу все функции хранить в главном классе.

тезис статьи
Цитата:
Вместо того, чтобы общаться друг с другом непосредственно, другие объекты полагаются на божественный объект.
Мне бы хотелось, чтобы кристаллы общались со счетчиком без родителя... А то так весь код наберется в классе Main. Я потом захочу, чтоб дровосек рубил дерево и у объекта дерева убавлялся объем дров, а у объекта дровосека прибавлялся. А когда он притащит дрова в дровник, то у него убавится, а у счетчика дров прибавится. Как в играх это делается? Кто-нибудь создает игры такого масштаба?

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

блогер
Регистрация: Jan 2008
Адрес: syktyvkar
Сообщений: 3,803
Записей в блоге: 10
Здесь просто офигенно подойдет модель + контроллер и вьюшки.
Меняем в контроллере модель, вьюшки модель слушают. Вот и получается общение и все довольны.
__________________
тут я

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

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Model == legalized GO.
__________________
Reality.getBounds(this);

Старый 07.05.2012, 00:08
expl вне форума Посмотреть профиль Отправить личное сообщение для expl Найти все сообщения от expl
  № 9  
Ответить с цитированием
expl

блогер
Регистрация: Feb 2006
Сообщений: 1,474
Записей в блоге: 3
Цитата:
Здесь мне не нравится, что много прослушивателей, много кода - все будет записано в родительском классе, а хотелось бы все записать в детей. Но я не знаю, как это делается правильно и проще...

2. Я могу передавать параметром один объект в другой и осуществлять управление там:
Обычно второй подход к хорошему не приводит. Тут суть в чём:
есть n объектов, взаимодействующих друг с другом. Если позволять каждому общаться с каждым напрямую - при изменении поведения одного - необходимость изменений кода взрывной волной пойдёт по всем. Если же они общаются только через общего посредника только сообщая что с ними самими произошло - менять придётся только один компонент и посредника

Если событийная модель выглядит громоздкой:
- можно использовать сигналы (не требуется создавать классы объектов, но больше проблем с типизацией)
- можно завязать каждый компонент на посредника и передавать его всем хоть в конструкторе (паттерн так и называется: Mediator). И каждый компонент будет напрямую дергать методы посредника, а посредник менять другие компоненты. Недостатки - компоненты нельзя использовать с другим посредником, но при сложной логике взаимодействия бывает что такой подход лучше событийного

Цитата:
А то так весь код наберется в классе Main
Вообще, если объекты, меняющие счётчик кристаллов и его отображающие - могут появляться и исчезать - то не надо их менять из контроллера. Здесь нужно забыть всё, что я рассказал выше и сделать диаметрально противоположное:
- Счетчик - модель - имеет поле numMinerals и посылает события о его изменении
- при появлении контроллера, который может изменять количество минералов - ему передаётся в конструктор модель и он изменяет numMinerals
- всё, что отображает эти кристаллы подписывается при своем появлении на экране на модель и отписывается при убирании с экрана. И соответственно отображает изменения.

Т.е. получается, что не контроллер меняет компоненты, а компоненты сами решают когда им измениться, слушая модель.

Т.е. тут выбор "контроллер всех слушает и меняет"<->"все слушают и меняют модель".
Но в обоих случаях компоненты взаимодействуют не напрямую, а через посредника


Что и сама модель c полем numMinerals может существовать, а может нет?
Значит делаем корневую модель c полем mineralsModel и слушаем когда она появится и когда исчезнет. Появилась - подписываемся, исчезла - отписываемся.

Может еще конкретнее опишите ситуацию, пообъектно? И правила когда что появляется и кто кому принадлежит(не с точки зрения классов, а с точки зрения игровой логики)?


Последний раз редактировалось expl; 07.05.2012 в 00:27.
Старый 08.05.2012, 22:28
SvetozarPNZ вне форума Посмотреть профиль Отправить личное сообщение для SvetozarPNZ Найти все сообщения от SvetozarPNZ
  № 10  
Ответить с цитированием
SvetozarPNZ
 
Аватар для SvetozarPNZ

Регистрация: Dec 2009
Сообщений: 125
Записей в блоге: 1
expl, вы писали про посредник. Я что-то такое имею в виду, создавая переменную главного класса и передавая параметром ее всем дочерним объектам.

Могу предложить очень конкретную ситуацию. Программируем игру Марио. Надеюсь, все играли.


У нас квадратики с вопросительными знаками, удар по которым прибавляет нам количество монеток в счетчике. Я правильно понимаю, что такой квадратик нужно вынести в отдельный класс? Да и счетчик тоже (пусть даже в комплексе с другими счечиками).

Вот. И как им взаимодействовать? После столкновения персонажа с объектом вопросительного знака последний диспатчит событие, которое прослушивается. Вопрос где?
1. В главном классе, родителе всех созданных объектов, тогда там будут слушаться и остальная сотня объектов мира марио (на мой взгляд, весь код игры будет там).
2. В самом себе, на слушателе будет вызываться метод, который должен уметь повлиять на объекты - экземпляры других классов (счетчика, персонажа и т.д.). Может быть это стоит делать через посреднический объект, который будет параметром при создании?

Как это делается грамотными разработчиками?..

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

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

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


 


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


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