![]() |
Так. Резюме:
1) пришли данные. Например, враг сделал свой ход и новые координаты врага. Пришли они в коннектор, коннектор их переваривает. 2) После этого коннектор дёргает метод у главного контроллера. Тут логичен вопрос, в каком виде он это делает? На каждый тип действия свой метод (типа атаковали - один метод, написали в чат - другой, пошел дождь - третий)? 3) В главном контроллере испускается событие, что враг походил. Событие содержит новые координаты врага. 4) Контроллер врага, который имеет ссылку на главный контроллер слушал это событие и переместился. 5) Враг нанёс удар, контроллеру надо отправить это на сервер. Он используя ссылку на главный контроллер вызывает у него метод call с необходимыми параметрами. (когда я говорил "напрямую вызываю метод у главного контроллера, он дёргает коннектор" я имел ввиду что вызываю метод подобный call, где описываю всё что я хочу отослать). Поправь пожалуйста, где на этот раз ошибся. И спасибо большое за помощь) |
1) Коннектор без понятия, что конкретно пришло, он распознает это всё как команду и только;
2) Вызывает moveEnemy(id, x, y), точнее (this._client[command.name] as Function).apply(this._client, command /* Command extends Array */); 3) Нет, событие идет new CommandEvent('command_' + command.name, ..., command). Его на самом деле отправляет коннектор после вызова команды у client, а контроллер тупо редиректит; 4) У врага контроллера нет, есть модель EnemyData, у неё тупо метод moveTo(x, y), его вызывает либо основной контроллер, либо дочерний, скажем, боевки; 5) Удары наносит сервер. Действия же игрока отправляются через основной контроллер, используя его метод call. Внутри call пришедшие аргументы перенаправляются в коннектор для отправки в виде команды на сервер. |
Ага, резюме 2.0:
1) Коннектору приходит пакет. Он видит, что это команда, отделяет имя команды от её аргументов, создаёт экземпляр класса Command. В _client он хранит ссылку на главный контроллер. У главного контроллера открыты методы для коннектора, имя метода совпадает с именем команды (или зная команду можно узнать имя метода). 2) Коннектор дёргает метод, сопоставленной этой команде у контроллера. 3) Коннектор испускает событие CommandEvent, которое главный контроллер редиспатчит, чтобы его поймали все кто хотят. 4) Понятно, а в случае чего-то мелкого, что требует взаимодействия с сервером, но содержащее контроллер - что слушает главный контроллер? Модель или контроллер? В каких случаях всё-таки слушает, а в каких контроллер старший вызывает методы напрямую? 5) Любой объект, который хочет общаться с сервером ловит ссылку на главный контроллер и дёргает его метод call. У меня вопрос по пункту 2-3: зачем дёргать сначала метод у клиента, а потом слать через него событие? По сути можно обойтись одним событием, который главный контроллер схватит первым. Можно одним вызовом у клиента - клиент сам сделает событие. |
4) Ничего не слушает, ему по барабану в таком случае. Младший контроллер подпишется на конкретное событие CommandEvent и работает с пришедшим событием;
5) Только младшие контроллеры. Событие не через метод шлется, а следующей строкой после вызова метода, в коннекторе. |
Цитата:
4) Нет, плохо выразился: Цитата:
5) Хм, но чтобы передать в младшие контроллеры ссылку на главный - придется эту ссылку тянуть через промежуточные. Если связь с сервером нужна промежуточному контроллеру - можно ли ему воспользоваться этой ссылкой для связи с сервером или нужно отдавать это более мелким контроллерам? Что делать, если это проблемно или это совсем не задача мелких контроллеров? |
Цитата:
Цитата:
Цитата:
|
Спасибо большое, теперь всё стало понятно.
Только момент ещё в тумане - я правильно понял что call могут дёргать любые дочерние контроллеры по отношению к главному, но всё таки предпочтительнее если это будут крайне-младшие? |
Цитата:
|
Ну почему же, базовый контроллер - контроллер игры, контроллер окна персонажа, в нём контроллер окна статов. =)
Спасибо большое, информация бесценна ) |
Волей судьбы пишу клиент под игру, серверная часть которого уже написана (недобросовестный кодер пропал, предоставив половину исходников весьма низкого качества - взялся писать клиент с 0).
Соответственно возник такой вопрос: 1) Как таковых команд сервер не присылает. Он присылает какие-то идентификаторы, которые позволят идентифицировать, что же сервер хотел сказать. Соответственно клиентом главный контроллер назвать сложно - коннектор создаёт событие и дёргает метод onServerData главного контроллера и передаёт ему событие, которое главный контроллер и отдиспатчит. Это событие слушают дочерние контроллеры и при получении такового они определяют, им ли это сообщение адресовано. В итоге один из контроллеров признает его своим и парсит, остальные после раздумий игнорируют. Правильно ли я понял теорию и применил на практике в моём конкретном случае? Реализуя таким способом я не чувствую себя плохо из за того, что коннектор не дёргает методы клиента по каждому событию. Даже наоборот: мне кажется что на каждую команду от сервера излишне было бы создавать метод в главном контроллере - большая часть из них уйдёт дочерним (они получат его с события), остальная часть, которая должна дёрнуть метод клиента - как я понимаю, для управления элементами у которых нет контроллера (вроде примера с врагом). По моим соображениям таких элементов в игре скорее всего совсем не много, поэтому встают логичные вопросы: 2) Коннектор в любом случае дёрнет метод клиента (речь не про CommandEvent, а про вызов метода у клиента до), при любой команде от сервера, или же только в строго-определенных? Если главный контроллер ничего не должен делать - в таком случае: делается пустой метод, вызов обрамляется в try..catch или же у коннектора есть конкретные мозги чтобы понимать, на что нужно дёргать метод клиента, а на что ненужно? 3) В случае, если коннектор всегда дёргает метод клиента... то объясните, пожалуйста, почему. По мне если обработкой займутся дочерние контроллеры, то главному, в принципе, вмешиваться и не стоит. |
Мои рассуждения о доставке в нужный контроллер.
Можно распространять события по цепочке - chain of responsibility. Причем цепочка легко превращается в дерево, если следовать паттерну визуальных объектов. Если в первом (основном) контроллере нашелся нужный метод, контроллер делает event.stopImmediatlyPropagation(). Иначе событие передается дальше, к дочернему контроллеру посредством бабблига. Если он может такое событие обработать, то можно сделать следующее: либо event.stopImmediatlyPropagation(), либо event.preventDefault(). Во втором случае в основном контроллере можно понять, что событие не нашло адресата, проверив результат выполнения метода super.dispatchEvent() и как-то отреагировать. false означает что событие было захвачено, true - подходящий адресат не был найден. Другой вопрос, оправдано ли ветвление контроллеров. |
dimarik, мысль ясна, спасибо. Я так понимаю если 2 дочерних контроллера, то событие отправляется в каждый. Только непонятно, как реагировать, если в обеих дочерних оно дошло до адресата )
P.S. сейчас вот пишу казино. Там есть общие окна для всех режимов игры (сама игра, зритель, курилка, лобби и т.д.), типа посмотреть информацию об игроке, отправить подарок, открыть окно привата и т.д. Оно всё взаимодействует с сервером, конечно, поэтому без контроллера не обойтись. В итоге я вынес мозги этих общих действий в базовый контроллер, базовая вьюшка всегда находится в DisplayList, она же является host`ом (display object container`ом) для всех остальных вьюшек. Если надо открыть окно - событие просто бабблится по вьюшкам, а возле главной вьюшки её ловит главный контроллер. Главный контроллер создаёт так же другие контроллеры (например, контроллер лобби), который уже размышляет о том, о чем ему сделать, а когда нужно отправить что-то на сервер - монопольно дёргает call и vkontakteCall у главного контроллера (ну, что описал Дениска, в принципе). По моему в таких случаях ветвление контроллеров не то что оправдано, а даже очень удобно. Интересно выслушать твоё мнение по поводу такой системы. Добавлено через 28 часов 12 минут P.S. dimarik, твой подход доставки в нужный контроллер чудо ) Не думал что на практике это будет столь удобно, спасибо огромное. |
сам только начал вникать в эту тему (жаль что еще нету задач котороые имело бы смысл так реалиозвать)
вот нашел такой вариант описания с минимальным примером и еще рекомендуют многие роботлегс |
Вот честно, не смотрел и не очень хочу смотреть фреймворки подобного плана.
Паттерн на то и паттерн, что это просто описание "проблема"-"решение" в хорошем плане. Если речь об архитектурном паттерне - это решение проблемы нормальной архитектуры приложения. Но каждое приложение достаточно уникальное, чтобы заимствовать чужую архитектуру, ни одна написаная ранее архитектура не будет той гибкости, которой я хочу в данном приложении. |
если каждое приложение достаточно уникальное, то смысл тогда в MVC ?
если я верно понял, то этот паттерн для того чтобы эту уникальность и разрулить и например одну и туже модель исопльзовать не один раз и не в одном проекте, а следовательно она должна иметь какието "правила" котороые можно будет исопльзовать в дургом проекте и при этом не думать об переделвании интерфейсов и способов связывания между модулями хотя это лишь мне так поудмалось а вот по поводу той статьи что ниже я скинул, - вникнул и понял что там не то ): там чел внизу про это и напаисал в комментах и дал ссылку на википедию |
Смысл MVC как раз в унифицированном решении проблемы архитектуры, когда требуется отделить данные от представления от манипуляции с этими данными. Ну вот проще говоря, не мыслю как паттерн можно под гребёнку смести, не говоря уж об архитектуре. Рассмотрим паттерн адаптер: он может служить единым интерфейсом для 2-3 социальных сетей, а может служить для единых входных данных от входных устройств - проще говоря управление мышкой/клавиатурой/джойстиком. Единственное что между ними общего - "единый интерфейс для работы с..." - но в этом и суть адаптера. Если смотреть со стороны MVC - общее это может быть некий абстрактный объект контроллера, модели и вьюхи, у которых расставлены эти связи между трио. Но эти связи во всех 3 классах дай бог нагребут 150-200 строчек кода. Я не вижу смысла ради 1% кода в проекте подстраивать под него остальные 99.
Описанное выше - конкретно моё имхо). Наверно, стоит пощупать эти фреймворки чтобы делать такие категоричные заявления... но как то не тянет. |
Код AS3:
вообщем если честно, еще гулбоко не вникал в роботлегс , как чего пойму отпишусь ( : |
Не совсем. В идеале для меня так:
Вьюшка - отображает. Очень удобно тем, что невозможно отображением подпортить логику игры. Добавил вспышку света при взрыве гранаты - и никак не может произойти так, что из за вспышки у врага на крыше упали штаны. Такие баги допустить очень легко, когда всё в куче. Ещё удобно тем, что разработку можно вести на уровне кружочки-квадратики и не ощущать скованность из за неполноты представления - добавляя отображение мы меняем 33% кода, вместо всей 100 (если представить что модель-контроллер-вьюшка имеют равный объем кода, что почти всегда неверно :D). Очень удобно когда ещё люди не знают, как будет выглядеть игра. Есть логика игры, а вот над представлением ещё думают, есть мелкий концепт. Чертовски удобно когда несколько видов игры - например вид сверху и вид сзади (3д, но игра функционала такого же как в 2д). Модель - ну тут в идеале - полная информация о процессе. Идеальная модель для меня - это если удалить вьюшка и контроллер, а потом создать их снова чистенькие и отдать эту модель - всё восстановится в точности/почти в точности, как было раньше. Очень удобно для сериализации: если она не DisplayObject - то просто записываем в ByteArray - получаем AMF объект, который можем сохранить... да хоть в файл. Некоторые в качестве модели используют DisplayObject`ы, ради иерархии и бабблинга событий. Врать не буду - в целом идея удобная, а сериализовывать модели... ну лично мне не приходилось никогда. С другой стороны DisplayObject`ы едят больше памяти, чем просто EventDispatcher`ы, так что эти моменты весьма спорные. Но это я от темы отхожу. Контроллер - ерунда которая всем этим делом управляет и содержит все мозги. Такое разделение помимо описанного может сыграть в плюс при работе в команде - менее опытный программист пишет вьюшку, более опытный - логику, и делается это почти паралельно. Такой практикой не занимался, но я думаю она вполне имеет место быть. |
чуть не растерял остатки мозга, пока все страницы осилил.
понял одно: я не тру и отсталый недофлэшер) исходя из всего, что здесь сказано, у меня получается всего 1 контроллер, он же контейнер, который главный класс, рулит вообще всем происходящим. раздает данные детям. слушает детей на предмет запросов на обновления инфы. если есть сервер, то как правило есть поставщик данных, который пуляет запросы и диспатчит события( если чтонить прилетает) в главный класс, в удобной для меня форме. понимаю как-то далековат я от MVC |
Понимание и прелести MVC приходит со временем. Поначалу начинаешь сам отделять управление от отображения, потом начинается разделение ещё и на данные, помимо отображения и управления, ну а потом осознание что визуализируются то данные, и по сути управление к отображению имеет мало отношения. И тут мы приходим к MVC..)
|
Присоединяюсь к вопросу - зачем нужно MVC на флэше? Хочется простых ответов, на пальцах. Вопрос даже скорее "зачем отделять отображение (ака вьюху)", "что мне лично дало отделение вьюхи".
Вот критика (нубская и тролльская, конечно, просто считаю, что спрашивающий должен написать больше, чем отвечающий, т.к. ему это больше надо): MVC делалось чуваками для серверных языков, чтоб при необходимости можно было легко сменить модель (база данных была в текстовичках, стала на оракл) и вьюху (можно сделать тонкий веп клиент (который там секьюрный и отовсюду доступен), можно толстый (который быстрее и мож чуток побольше умеет), можно розовый (для блондинок)). Соответственно, это достаточно большое и сложное приложение, у которого есть база данных и шанс, что клиенты будут значительно отличаться. Ну т.е. флэш - это клиент, вьюха. Вьюха во вьюхе... ээ во вьюхе во вьюхе... Ну да, хорошо бы, чтобы можно было подменить данные (локализация, звуки, могу ещё расписать на пальцах выгоды), но это не MVC, это "отделяйте данные от кода", более старый в т.ч. принцип. Но смысл на флэше отделять вьюху? |
-De-, художники и дизайнеры ребята непредсказуемые. У игры есть концепт, геймдизайн и всё такое - её можно писать. Пишутся контроллеры и модели, которые впоследствии не трогаются, а весь маразм и гениальность художников воплощается лишь во вьюхе. Невозможно повредить логику игры неверными шагами - в этом прелесть. Количество багов на проектах с мвц лично у меня стремится к 0, как без него они достаточно частые, и ещё фиг пойми почему.
P.S. локализация и звуки это задачи сугубо вьюхи. к модели отношения не имеют. |
Тигра: ты вещаешь, прям как убелённый сединами гуру понявший истинную истину)))
но мвц - не панацея, - лишь один из способов. В реальных задачах даже ООП не всегда приемлем. Но я не против МВЦ - это заразно)) Я против его использования везде и всегда и использования МВЦ- фрэймворков (хотя иногда и они полезны) |
@Котяра: просто начал уже более-менее разбираться. Объясняю чтобы проверить твёрдость моих теоретических знаний )
Конечно, MVC не панацея, иногда он создаёт даже излишние неудобства, в плане скорости разработки на ранних стадиях. MVC у меня в голове проецируется как танк. Хочешь рулить - бери танк, но он тяжелый и сложен в управлении. Нужно что-то лёгкое, быстрое, простое в написании и понимании - MVC не твой выбор. |
Ээ, картинки, звуки, анимации, ну т.е. ассеты - это данные.
Я не против MVC, просто я лично птица гордая, надо пнуть. И хрен бы со мной, но я ж (конечно же, какие сомнения) не для себя, думаю я не один такой. Для кармы там полезно обьяснить неразумным преимущества MVC, как отмазка от ментов может прокатить и пр. =) ЗЫ: дикий оффтоп и вброс, но если у вас не меняется логика игры в процессе производства, то вы - не игродел %) |
Почему же, меняется, дорабатывается, добавляются новые плюшки. Но поменять картинку, добавить фейрверк и всё в этом роде - это происходит куда чаще.
Звуки, картинки, анимации - это не модель, в общем случае. Всё, что юзер видит на экране - это вьюшка. Модель хранит количество патронов в обойме, количество обойм и идентификационный номер автомата. Вьюшка берёт эти 3 числа и устраивает на экране... да хоть 2 мировую. |
Да, возможно у меня в голове неправильное MVC, но для того MVC, что у меня в голове, я вон выше обьяснил, зачем оно нужно вообще.
А у вас выгоды не видно. Проверка на выгодность: меняем поведение автомата при том, что "количество патронов в обойме, количество обойм и идентификационный номер автомата" остается одним и тем же, меняем в одном месте, скорее всего простые и понятные штуки (интересно, кстати, какие например). Вроде ок. А если нет вьюшки, т.е. ваша модель берёт 3 числа и устраивает непристойности, то... то же самое! Зачем платить больше? Т.е. есть вот автомат. Есть его какие-то данные, которые "одни для всех" - они модель. Они - на сервере вообще. Зачем флэшке об этом знать? Флэшка должна по этим данным данным свыше изобразить автомат. Если меняется характер этих данных (сплэш там добавляется например), то один хрен надо править флэшку. И хорошо бы, чтоб в минимальном числе мест. Если автомат становится супермеганавороченным классом, лазить по которому грозит похуданием, то есть куча других способов сгруппировать куски автомата по разным классам. |
Своё виденье я описал в посте №180.
|
Цитата:
Цитата:
Цитата:
Вот сохранять игру - да, без вариантов, MVC - то, что надо. ЗЫ:Вообще мозги начали поворачиваться, спасибо. |
Как трудно уследить за всеми контроллерами? Если контроллеров куча, а это, я думаю, очень хорошо (конечно, если правильно структурировано). Ведь проследить, что там что куда посылает, если что-то там случилось, довольно трудно, разве нет? Плюс держать в голове, что же там у нас во вьюшке, а что у нас в контроллерах. Не говоря уже о том, что там у нас творится с данными в модели... Пока я вижу только одно удобство у MVC, как Тигер сказал, править нужно только вьюшку. Но мне не видится удобным, ибо в голове как-то сформировался синглтон, все действия объекта пишутся в классе этого объекта и взаимодействуют через статичные ссылки Main. Да, в теории может быть MVC и очень даже хорош. Но практика взрывает мозг.
|
Блин, всю ветку не осилил, может было уже, но спрошу все равно... Как обрабатывать событие enterFrame? По идее логику должен обработать контроллер, передать в модель, а та в, свою очередь, во вьювер должна передать команду обновить экран. Как-то мне кажется это замороченным - гонять кучу данных по кругу. Да, вьювер может сам себя обновить, минуя контроллер и модель, но какой же это тогда MVC?
|
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
Если речь о нужде события enterFrame в контроллере - тот создаёт DisplayObject и хватает у него этот enterFrame. Композиция, короче. |
ну по энтерфрэйм/таймеру можно менять модель тоже (например xPos,yPos,zPos)
а во вью это отображать. так у меня сделана одна 3D стрелялка. вью в этом случае это viewport камеры, модель - это координаты 3D объектов. делать каждый 3D объект вьюшкой нельзя. вернее они тоже вьюшки, но другого уровня - слушают например поле модели статус и исходя из него меняют свою текстуру/форму. Но вообще в таком случае чистый мвц не очень подходит. |
Цитата:
|
Цитата:
Цитата:
Вот. И это уже тогда не MVC получается - а просто архитектура. А так как во флэше все привязано к enterFrame - нужен ли вообще нам MVC? P.S.: но это так - нубские мысли. Все равно у каждого свое видение паттернов. |
Цитата:
|
По моему, как минимум в gamedev'е рано или поздно все равно приходишь к MVC. Как не крути, слишком уж удобно отделять представление от данных и всем этим управлять контроллером. Потому не вижу смысла насильно разбираться в паттерне, который видимо просто негде пока применять.
|
Много читал/спрашивал/планировал и пришел к выводу смещения мозгового центра из Controller в Model:
Model Хранит статические данные, состояния и прочее. При поступлении команд на изменение реализует логику по изменению состояния, сообщает об изменениях. View Элемент с двойственным характером. С одной стороны он на свой лад отображает данные из модели и следит за актуальностью этого отображения. С другой стороны еще реагирует на действия пользователя (как правило мышь, клавиатура). Но мышью можно кликнуть по кнопке, сменить состояние CB, сдвинуть ползунок, что там еще? Модель не должна в этом ковыряться, ей нужен четкий сигнал с конкретным значением конкретного свойства/состояния. Controller Самый тонкий элемент системы. Его задача принять сообщение от View, и на основании этого сигнала выдать простое и понятное сообщение. Например вместо "слайдер яркости в состоянии 80" модель уже получит "яркость 0.8". И поменяй я во View слайдер на числовое поле или CB — контроллер переписал и готово. А модель и не прознает. Основная позиция: не Controller, а Model является мозгом системы. К такой схеме я пришел на текущий момент. Ни на что не претендую и не против замечаний — мог что-то не учесть, что станет проблемой при таком подходе (хотя как бы изначально он именно таким и был у отцов-основателей) |
Мозгом системы является контроллер. Представь ситуацию: ты решаешь задачу и пишешь мысли в тетрадку, там её решаешь. Ты - контроллер, тетрадка - модель.
Цитата:
|
2Zebestov
немного меня смущает подмена понятий модели и контроллера у тебя. модель Цитата:
Цитата:
контроллер не выдаёт сообщений он явно меняет модель. |
| Часовой пояс GMT +4, время: 23:14. |
Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.