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

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

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

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Спасибо, очень доходчиво.

Цитата:
А вот насчет множества Моделей это перебор. Ну, или они могут быть как части одной Модели: ты можешь считать что твой Character это CharacterModel, смысл от этого не очень поменяется, разве что возникнет вопрос "а как быть с CharacterController? Что он должен делать?" )) При разделениях Моделей на множество важно осознавать, насколько они зависимы друг от друга всмысле обмена данными. В режиме поединка тебе постоянно надо иметь данные о персонаже и оппоненте "вместе", да еще и об их аммуниции; а вот глобальное меню игры здесь вроде как совсем не при делах — оно может быть отдельной триадой, так как его данные абсолютно обособлены.
Вот я как раз поэтому и спрашивал выше, насколько жёстким является требование создавать полную триаду MVC на каждый из элементов общей конструкции. Я как рассуждал. Добавляем класс GameModel - такой "стол", на котором считаем всю игровую логику. Но при этом если в классе Character "живут" и обновляются по некоторым установленным правилам значимые для механики и одновременно отображаемые для игрока свойства, то зачем мне их тянуть в GameModel, если я могу посчитать их прямо в классе Character и там же создать событие, которое подхватит CharacterView, чтобы отразить изменения, произошедшие именно с этим персонажем. Получается, игрок, взаимодействуя с GameView, выбрал, чего делать. Контроллер это принял и послал команду в GameModel, а Game Model обновилась сама, плюс обновила экземпляры Character для героя и врага. Все трое отправили события, чего показать. Вроде, нормальная схема, как мне кажется. Один главный контроллер, плюс по отдельной Model и View для "стола" и персонажей.

Цитата:
В MVC нет такой категории "data". Данные бегают туда-сюда постоянно.
Да, тут всё понятно, закрыли тему Дату отправляем храниться в XML или "статические" классы, откуда будем по необходимости вытягивать.

Ещё с позволения несколько вопросов. Я пока единственное, что реально написал из будущей MVC - это все три класса со ссылками друг на друга "по классике", плюс в Model создал метод setup, который рассчитывает стартовые значения свойств и т.п. Хотел сделать примерно то же самое с GameView, но возник вопрос. Опять на счёт иерархии отображения . В методе View.setup я хотел сразу создать основные экранные объекты, начиная с моей любимой области для вывода текста. Для этого изготовил новый класс MainTextArea, расширяющий Sprite - контейнер. Внутрь воткнул простенький прямоугольник (в дальнейшем будет окно с "красивой" рамкой), а поверх него в том же контейнере - объект TetxField для вывода собственно текста. GameView добавил его в список отображения, на экране окно появилось, слава аллаху. Решил сразу попрактиковаться и написать метод, который по получении соответствующего события от Модели будет выводить текст. Вот тут началась фигня. Ибо записать напрямую MainTextArea.text я не могу, т.к. это Sprite. Делать область вывода как "голый" TextField совсем без контейнера как-то тоже не хочется - мало ли чего в ней ещё потребуется наворотить... Прикинул вариант написать собственный метод для GameView, получающий по событию текст, чтобы потом "отправить" его в MainTextArea...
И тут мне пришло в голову красивое в своей простоте решение. А может быть пусть сам экземпляр MainTextArea слушает события от модели и выводит текст, который его попросят? Плюс в том, что во-первых, мы сокращаем длину канала взаимодействия, т.к. данные от модели не нужно будет "протаскивать" через главный Вью, а во-вторых, планируемые функции подпадают под ответственность класса MainTextArea - выводить тексты. При этом, замечу, поскольку экземпляр MainTextArea - это креатура GameView, значит последний при необходимости может изменить или удалить его, т.е. иерархия не нарушается. Корректное это решение или всё-таки иерархия нарушается? Прокомментируйте, пожалуйста.

И второе. Во всех примерах MVC, которые я видел, весь код модели был помещён непосредственно в класс Model. В результате даже для простеньких игрушек в нём набиралось прилично разных функций. А если проект будет покрупнее, то там будет просто "мясо"... Верно я понимаю, что "главная" модель должна выглядеть как такой распределитель обязанностей, который получает команды от контроллера и "раздаёт" их разным специализированным классам для выполнения конкретных вычислений?

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

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
Да, все верно, главная содержит в себе глобальные параметры и приватные экземпляры дочерних моделей, доступ к которым осуществляется по геттерам.
__________________
while(live()) { hope(); }

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

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

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

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Цитата:
Сообщение от Wolsh Посмотреть сообщение
Ну, не спрайт, а MainTextArea))
Ну раз ты придрался, я тогда аккуратно оспорю. А разве с т.з. наследования, наш MainTextArea не "is Sprite"?

Цитата:
Так что забабахать ему сеттер .text вполне в твоих силах.
Точняк, спасибо. Туда и формат сразу удалось прикрутить. Теперь получается вообще красиво: модель "знает", к чему относится тот или иной кусок текста и отражает это в строковом id, а вьюшка подхватывает из event.target этот идентификатор и по нему забирает нужный формат, который хранится в третьем месте.

Просьба прокомментировать моё решение на счёт окончательной "разблюдовки" MVC. Поскольку, я напоминаю, у меня текстовый квест, то основных "интерактивных" областей на экране всегда три: область вывода текста, "уголок" героя, где изменяющийся портрет, всякие полоски здоровья, баффы/дебаффы и т.п. и такой же "уголок" соперника. Я рассудил так. Коль они у меня всю дорогу находятся каждый на своём месте, то хрена ли я буду лепить отдельные вьюшки! Это же не RTS, где враги прут пачками и каждый экземпляр нужно отрисовать... И оставил я один контроллер и одну вьюшку.

И небольшой практический вопрос, который меня поставил в тупик. Довольно часто встречается ситуация, когда нужно вывести порцию текста игроку, что-то по мелочам обновить, а затем, когда он осознает увиденное и кликнет, выводить текст и обновлять экран дальше. Естественно, чтобы он сообразил, что игра не зависла, а ждёт от него действие, я сделал класс ClickToContinue, который выводит соответствующее сообщение на выбранном языке, красиво мерцающее на видном месте. Но вот внедрение его в мою MVC вызвало затруднение. Вроде как сам клик ловить в контроллере - не дело, это прерогатива вьюшки. Значит, контроллер "дёргает" вьюшку и говорит "давай тормози до клика". Вьюшка берёт под козырёк и вываливает на сцену мой красивый ClickToContinue. А вот потом что? Что делать с кликом, который вьюшка поймала?

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

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
Цитата:
Сообщение от Appleman Посмотреть сообщение
Значит, контроллер "дёргает" вьюшку и говорит "давай тормози до клика". Вьюшка
берёт под козырёк и вываливает на сцену мой красивый ClickToContinue. А вот потом что? Что делать с кликом, который вьюшка поймала?
По идее, по mvc контроллер дергает не вьюшку, а модели говорит, что сейчас у нас пауза (или изменяет какой-либо параметр сеттером в модели), которая, в свою очередь, диспатчит событие "торможение_до_клика". А вьюшка слушает модель и, в частности, это событие. Вьюшку же, в свою очередь, слушает контроллер, который подписан событие что-то вроде "продолжить_после_паузы". По этому событию контроллер меняет что-то в модели, которая диспатчит событие, которое слушает вьювер и так далее.

Может это и не совсем правильно, но у меня для этих целей обычно служит такой специальный классик-объектик, который называется как-нибудь на вроде "информационное окно", или "окно сообщений". Оно может инициализироваться на главной сценей, принимая в себя верхний слой. А потом, в любом месте кода, я просто, обращаясь к этому классу, дергаю функцию "показать окно", передавая её label - текст, который нужно вывезти, и, если нужно, индентификатор картинки и т.п. А иногда это просто обычный класс-Sprite, и в любом месте кода я создаю новый его экземпляр, передавая в конструктор label и тут же добавляю его на сцену. А все остальное проиходит внутри этого класса и он ничего не знает о том, откуда его вызывают и кто, и зачем. Все, что он умеет - это отобразить графику, встроенную в него - окно с полупрозрачным фоном, отобразить текст, пришедший в конструктору, и удалить сам себя. Да, такой подход часто ругают, но я люблю удаляющие сами себя классы, это очень удобно)) У него просто есть приватная функция remove(), которая вызывается при нажатии на крестик либо ВНЕ окна, и которая выглядит таким образом:
Код AS3:
private function remove():void
{
       this.parent.removeChild(this);
}
Добавлено через 2 минуты
то есть, в моем случае, вся идея сводится к тому, чтобы иметь некий классик, который вообще ни сном не духом о том - куда его добавляют, какая там невероятная космическая архитектура реализована в приложении и тому подобное - он просто существует сам в себе. Просто объектик со своей внутренней логикой. И это позволяет его применять в любом проекте, просто создав его экземпляр, передав ему текст и добавив на сцену. Все остальное же он делает сам.
__________________
while(live()) { hope(); }

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

Регистрация: Jun 2012
Адрес: Новосибирск
Сообщений: 6,644
Записей в блоге: 4
Цитата:
Да, такой подход часто ругают, но я люблю удаляющие сами себя классы, это очень удобно))
Экземпляры классов, если быть точнее. Классы сами себя не удаляют.
И в этом методе есть очень большая проблема. Отсутствует проверка на наличие parent. Если экземпляр не будет никуда добавлен, то при вызове всё сразу отвалится с null pointer исключением.
Лучше уж так:
Код AS3:
public function removeFromParent():void
{
       if (parent) parent.removeChild(this);
}
п.с. Я тоже не вижу в этом подходе ничего плохого)
__________________
Ко мне можно и нужно обращаться на ты)

Старый 31.10.2017, 20:33
Godwarlock вне форума Посмотреть профиль Отправить личное сообщение для Godwarlock Найти все сообщения от Godwarlock
  № 27  
Ответить с цитированием
Godwarlock

Регистрация: Jan 2012
Сообщений: 836
А мне вот последнее время перестает нравится суть контроллера, который слушает вьюшку, потом вносит изменения в модель, а та в свою очередь возвращает изменения во вью. Как то много лишних действий, нет?

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

Регистрация: May 2008
Адрес: Питер
Сообщений: 385
Отправить сообщение для ZergMaster с помощью ICQ Отправить сообщение для ZergMaster с помощью Skype™
caseyryan да, совершенно верно, забыл указать это. Так как зачастую выходит, что кроме удаления себя со сцены происходит еще некоторое количество действий, то этот метод может выглядеть так
Код AS3:
public function removeFromParent():void
{
       if (!parent) 
                return;
 
       //некоторая логика
       parent.removeChild(this);
}
Добавлено через 7 минут
Godwarlock так у нас же может быть множество вьюшек. И таким образом, когда контролер изменяет модель, они ничего не знают о том - сколько вьюх и вообще что там творится снаружи, а модель просто рассылает события. А потом уж кто их поймает - тот и использует. В этом то вся и красота mvc, и если такой системы не будет, то да, это будет уже не mvc. Такая модель особенно актуальна, когда у нас неограниченное и, быть может, даже неизвестное количество вьюшек, которые должны отображать одну и ту же инфу.

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

модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
Цитата:
А разве с т.з. наследования, наш MainTextArea не "is Sprite"?
Не всё так однозначно. Он еще и "is Object" кроме прочего. Но Обжекту ты бы смог добавить .text, а спрайту не можешь, а MainTextArea cнова можешь. Чудеса.

По поводу click to continue — а Модели то есть вообще дело до этого? До того что пауза. В ней что-то происходит? Или она составила кадр, известила вьюху и спит пока не скажут давай следующий кадр?
__________________
Reality.getBounds(this);

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

Регистрация: Dec 2014
Адрес: Санкт-Петербург
Сообщений: 479
Цитата:
Сообщение от Wolsh Посмотреть сообщение
По поводу click to continue — а Модели то есть вообще дело до этого? До того что пауза. В ней что-то происходит? Или она составила кадр, известила вьюху и спит пока не скажут давай следующий кадр?
Второе. Ничего не происходит.

Вообще вижу тут выше дискуссию на счёт нужности контроллера. Испытываю примерно те же ощущения, правда, пока особо не выпендривась, т.к. нужно хоть что-то рабочее написать, прежде чем делать выводы.
Но вот взять, например, мою типичную ситуацию с выводом диалога выбора дальнейших действий игроком. По задумке модель берёт весь массив действий и, используя свою логику, фильтрует его в зависимости от состояния игровых параметров. Отфильтрованный массив по событию забирает вью, чтобы вывести игроку. В контроллере висит слушатель события выбора действия. Когда игрок делает свой выбор, вью принимает его и отправляет в контроллер. Контроллер же, не приходя в сознание, отправляет идентификатор действия обратно в модель (он ваще не понимает, что это за фигня к нему прилетела!), чтобы там это действие было обработано. Спрашивается, на фига тащить всё через контроллер, если можно сразу из вьюхи принять в модель?

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

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

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


 


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


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