jarg

Форум для проектов, находящихся на стадии Альфа и Бета. В них ещё не реализована вся задуманная автором функциональность, а значит идёт активная разработка.

Модераторы: Sanja, Максим Кич

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 07 сен 2013, 01:12

Похоже я наконец понял как оно у тебя устроено =/
ishellstrike писал(а):Почему меня это насторожило: эта база может неприлично разрастись, а делать универсальные поля, вроде "характеристика1" "характеристика2", которые будут батоном трактоваться, как питательность, а мечем, как урон, мне кажется чем-то неправильным, или тут я не прав?
Ну так от разрастания самой базы никуда не деться, ведь она должна содержать всю информацию о всех предметах. Но такое хранилище сложно сделать типизированным, поэтому предлагаю не заострять внимание на проблеме структуры именно базы (пусть это будет упомянутый тобой текстовый формат или что удобно), а рассматривать ее исключительно как внешнее хранилище описаний, своеобразный конфигурационный файл.

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

Код: Выделить всё

IBlock a = GetBlock(x,y);
...=BlockDataBase.Data[a.Id].Description
if(BlockDataBase.Data[a.Id].Prototype == typeof(BlockTable)) {
...=BlockDataBase.Data[a.Id].%поле, характерное для стола%
}
Основной проблемой я вижу отсутствие иерархии. Объект принадлежит либо нескольким несвязанным "классам" (теги или компоненты, получаются артефакты типа меча-ящика), либо только одному конкретному "классу" (и случается, что нож совершенно не похож на топор), т. е. фактически есть только две крайности. Код обработки всегда работает с абстрактным "объектом" и вынужден делать проверки типа на каждый чих и в разных местах программы.

Иерархия сущностей может существенно повлиять на структуру программы. Например, пусть:
  • GameObject (свойства: тайл, материал, описание, ...)
    • Item (свойства: вес)
      • Weapon (свойства: урон)
        • <Knife>
        • <Axe>
      • <Stool>
    • Structure (свойства: высота)
      • <Statue>
Жирным отмечены классы в коде, простым в угловых скобках -- объекты в базе, те самые отличающиеся только значениями полей.

Для UI весь уровень -- это лишь массив GameObject. У GameObject достаточно свойств, чтобы быть отрисованным и на этом уровне абстракции этого достаточно. При попытке что-то поднять становится важно, является ли объект Item (может ли вообще быть поднят) и если да, каков его вес; весь инвентарь -- это список Item. Опять же, на этом уровне абстракции этого достаточно. При попытке взять Item (а предметов другого типа в инвентаре быть не может, он же список Item) в качестве оружия, проверяется является ли оно Weapon. Ну а слот под оружие именно типа Weapon, и значит при просчете атаки можно будет не задумываться о наличии или отсутствии полей, в слоте точно Weapon с описанием, материалом, весом и уроном.

То же самое можно сделать и без наследования (NetHack, anyone?), достаточно аккуратно следить что куда идет, но таким образом достигается несколько удобных моментов:
1. Объект не захламляется полями там, где это не нужно (GameObject для UI не имеет ни урона, ни питательности), но всегда имеет их там, где это нужно (слот оружия в руке).
2. За выполнением условий какой тип где может быть использован следит компилятор, который куда внимательнее человека.
3. Обобщение игровой логики, которой не важен подтип объекта, производится нагляднее, так как не важно может быть с любого удобного узла иерархии.

Конкретная иерархия и набор свойств взяты из воздуха для наглядности. Очевидно, что в конкретной игре все будет по-другому, в зависимости от игровой механики.

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

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 09 сен 2013, 11:06

Похоже все-таки я не понял =|
ishellstrike писал(а):<...> предметы, монстры, блоки карты -- имеют разные базы и разные, соответственно, поля <...> Подклассы у блоков и монстров есть, ибо логика может отличаться <...> У предметов подклассов нет, есть перечисление типа, по-моему этого достаточно. Логика предметов всегда одна <...>
Собственно, тогда я не вижу проблемы. Просто приведенный тобой кусочек и оговорки вида "рисовали сами себя" создали впечатление чего-то типа бесконечных свитчей на каждый мыслимый вариант и вообще бардака. Если же выходит, что все как-никак по полочкам разложено, могу только посоветовать не спешить и использовать выбранный подход пока он явно не начнет трещать по швам. В процессе вероятно всплывут всякие косяки, куда деться, но они хотя бы будут найдены не ценой нескольких полных переписываний из-за каждого нового, а как бы разом.

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

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 09 сен 2013, 12:29

Один момент который я описывал в решении "реализация всех интерфейсов предмета в одном объекте и тегов" таки был упущен.
Чтобы избежать каши из полей, и не хранить излишние "урон" для еды и "питательность" для меча, свойства объекта представляют собой динамический ассоциативный массив. Свойство "питательность" будет иметь место только при наличии тега "ЕДА", а "урон" только при наличии "ОРУЖИЕ". В базе или хранилище мы их так и храним в связке "имя свойства" - "значение". Все реализации хранения данных позволяют так сделать. Храните ли вы сохранение в текстовом файле, бинарнике или даже в базе данных (две таблицы "предметы" и "свойства предметов" связанный один ко многим).
Фактически мы абстрагируемся от конкретики полей и класс "предмет" предполагает наличие переменного списка из N именованных полей/свойств. Которые инкапсулированы в объект, и доступ к ним осуществляется через единую функцию ПолучитьПараметр('Имя параметра').

Вот так будет выглядеть меч:

Код: Выделить всё

[NAME=simple sword]
[WEAPON]
  [W_TYPE=SWORD]
  [W_ACC=4]
  [W_DAMAGE =5]
[WEIGHT=5]
[PRICE=10]
Вот так магический меч

Код: Выделить всё

[NAME=magic sword]
[WEAPON]
  [W_TYPE=SWORD]
  [W_ACC=4]
  [W_DAMAGE =5]
[MAGIC_EFFECT]
  [ME_TYPE=ON_HIT]
  [ME_SPELL=FROST]
  [ME_POWER=3]
[WEIGHT=6]
[PRICE=40]
А вот так еда.

Код: Выделить всё

[NAME=ration]
[FOOD]
  [NUTRITION=10]
[WEIGHT=1]
[PRICE=5]
Каждый предмет имеет только необходимые поля для работы его интерфейсов, которые заявлены с помощью тегов [WEAPON] [MAGIC_EFFECT] и [FOOD]. Хотя сам объект имеет реализацию для всех функций. В очень грубом приближении это своеобразное множественное наследование интерфейсов реализованное через теги, а не через средства языка.

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 09 сен 2013, 12:38

ПолучитьПараметр('Имя параметра')
не люблю я такие вещи...

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 09 сен 2013, 12:45

Jesus05 писал(а):
ПолучитьПараметр('Имя параметра')
не люблю я такие вещи...
Я понимаю вызвано не формой записи, можно конечно и GetParamXXX для каждого написать, а самим фактом что параметр может не найтись.
Но это плата за абстракцию.

Но все таки, давайте аргументы. В чем подводный камень?

Аватара пользователя
Jesus05
Сообщения: 1840
Зарегистрирован: 02 дек 2009, 07:50
Откуда: Норильск, сейчас Санкт-петербург.
Контактная информация:

Re: jarg

Сообщение Jesus05 » 09 сен 2013, 12:56

Oreyn писал(а):
Jesus05 писал(а):
ПолучитьПараметр('Имя параметра')
не люблю я такие вещи...
Но все таки, давайте аргументы. В чем подводный камень?
Опечатки не проверяемые компилятором. (можно обойти дефайнами\константами конечно)
Справочник который надо помнить. (дефайны\константы все равно придется помнить или лазить смотреть их)
Неопределенное возвращаемое значение. (GetHP и GetName возвращают разные вещи, придется возится с приведением типов.)

ну это то что быстро пришло в голову.

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 09 сен 2013, 13:05

Oreyn писал(а):В базе или хранилище мы их так и храним в связке "имя свойства" - "значение" <...> класс "предмет" предполагает наличие переменного списка из N именованных полей/свойств
Своеобразный вариант stringly-typed кода =)

А если серьезно, у этого подхода есть существенный недостаток в том, что нет эффективного механизма гарантировать наличие, тип, корректность применения тех или иных свойств. В упрощенном примере выше я упомянул как структура программы (контейнеры, типы переменных) автоматически обеспечивает корректность набора полей. Ошибки при добавлении и использовании новых полей быстро выявит компилятор, ну а банальные опечатки и вовсе IDE подчеркнет. Причем строго говоря, в подходе с ассоциативным массивом "каша из полей" никуда не девается, полей просто не видно. У вундеробъекта, есть и Item.Damage, и Item.Nutrition, в зависимости от некоторого Item.TypeFlags, просто поле используешь или нет. У ассоциативного массива потенциально есть и Item["Damage"], и Item["Nutrition"], в зависимости от некоторых Item["Weapon"] и Item["Food"], просто поля запрашиваешь или нет.

В итоге что так, что эдак, объект выходит нетипизированным (с точки зрения кода/компилятора) и вынуждает проверять и проверять наличие необходимых в конкретном месте полей. Быстрое добавление-удаление полей из объектов -- сомнительный в общем-то плюс. Желание "вот тут по-быстрому что-то прикрутить" это признак плохо продуманной архитектуры, и как правило означает, что в скором времени в одном месте программы что-то будент работать чуточку не совсем так, как во всей остальной части. По-моему, такой подход можно использовать, скажем, для скриптования событий или квестов, но не для самого приложения.

Оговорка: вышесказанное касается строго-типизированных ЯП (мейнстрим, то есть). Если ЯП сам по себе скрипт и подобная методология разработки там норма, то почему бы и нет.
Пытается раскуклиться

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 09 сен 2013, 16:20

Cfyz писал(а):
Скрытый текст: ПОКАЗАТЬ
Oreyn писал(а):В базе или хранилище мы их так и храним в связке "имя свойства" - "значение" <...> класс "предмет" предполагает наличие переменного списка из N именованных полей/свойств
Своеобразный вариант stringly-typed кода =)

А если серьезно, у этого подхода есть существенный недостаток в том, что нет эффективного механизма гарантировать наличие, тип, корректность применения тех или иных свойств. В упрощенном примере выше я упомянул как структура программы (контейнеры, типы переменных) автоматически обеспечивает корректность набора полей. Ошибки при добавлении и использовании новых полей быстро выявит компилятор, ну а банальные опечатки и вовсе IDE подчеркнет. Причем строго говоря, в подходе с ассоциативным массивом "каша из полей" никуда не девается, полей просто не видно. У вундеробъекта, есть и Item.Damage, и Item.Nutrition, в зависимости от некоторого Item.TypeFlags, просто поле используешь или нет. У ассоциативного массива потенциально есть и Item["Damage"], и Item["Nutrition"], в зависимости от некоторых Item["Weapon"] и Item["Food"], просто поля запрашиваешь или нет.

В итоге что так, что эдак, объект выходит нетипизированным (с точки зрения кода/компилятора) и вынуждает проверять и проверять наличие необходимых в конкретном месте полей. Быстрое добавление-удаление полей из объектов -- сомнительный в общем-то плюс. Желание "вот тут по-быстрому что-то прикрутить" это признак плохо продуманной архитектуры, и как правило означает, что в скором времени в одном месте программы что-то будент работать чуточку не совсем так, как во всей остальной части. По-моему, такой подход можно использовать, скажем, для скриптования событий или квестов, но не для самого приложения.

Оговорка: вышесказанное касается строго-типизированных ЯП (мейнстрим, то есть). Если ЯП сам по себе скрипт и подобная методология разработки там норма, то почему бы и нет.
Да, тут есть с чем согласиться, и есть с чем нет. Под "каша из полей" подразумевалось, что объект хранит/записывает/выделяет память для ненужных ему полей. И этого как раз происходить не будет с ассоциативным массивом. Если мы не объявили тег, лишних полей у этого экземпляра нет/память не выделяли/не сериализовали ничего лишнего. Если же мы объявили тег, значит он и его поля нам нужны.
Да, и плюс то не в том, чтобы быстро добавлять/удалять поля на ходу или чего-то быстро прикручивать. Добавляться они будет в шаблонах предметов и при процедурной генерации. То есть вопрос - как изначально построить гибкий конструктор предметов и прописать доступные кирпичики которые то как-раз и строго определены дизайном.
По поводу опечаток - Jesus05 правильно отметил, константы дефайны и среда намекнет на неправильное написание.

С другой стороны. Действительно идет ущерб строгой типизации. Да, нужно будет помнить словарь дефайнов, но и имена полей которые содержат нужный параметр аналогично нужно будет помнить. Да, нужно будет проверять наличие полей. Даже если ввести доверительное допущение "если есть тег, должны быть и соответствующие ему поля". В конце концов ошибки можно отловить и исправить, как минимум если фиксировать обращения к несуществующим полям из функции обращения к полю по имени.

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

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 10 сен 2013, 13:31

Oreyn писал(а):То есть вопрос - как изначально построить гибкий конструктор предметов и прописать доступные кирпичики которые то как-раз и строго определены дизайном.
Я предлагаю посмотреть на проблему несколько более широко.

1. Существенные изменения структуры данных вынуждены сопровождаться симметричными изменениями алгоритмов, их обрабатывающих. Так введение "питательности" в игре, где ее раньше не было, не ограничится одним описанием поля в файлике и одной функцией в коде. Будут затронуты многие части игры, изменится баланс, игровая механика.

2. Если доработка не касается (или не должна касаться) кода и алгоритмов в нем, то полагается, что существующие алгоритмы и механика уже готовы к новым данным. Например, добавляется ловушка, которая на самом деле комбинация из уже существующих триггеров и эффектов.

3. Если желаемый объект в текущую модель данных не лезет, то практически гарантированно он и обработан будет неверно (ошибочно, неполно, вообще не будет), ведь алгоритмы сами по себе не напишутся, а текущие заточены под текущую же модель [данных]. В этом случае надо взвешенно проработать модель заново и решить, отказаться от задумки или расширить модель и перейти к п.1, воплотив ее в коде.

Однако, излише свободная структура данных (в частности, ассоциативный массив) провоцирует пропустить шаг "взвешенно проработать модель" и перети сразу к "воплотить в коде". Завести новое поле или новый тип объекта легче легкого, осталось вставить пару if-else в одну или две функции и вроде работа сделана. Что сказывается позже, когда становится ясно, что изменение затронуло еще несколько мест, тянет за собой еще пару полей, требует пересмотра правил игры и вообще убило баланс.

Еще раз: изменения в структуре данных это тревожный звоночек, тут маловероятно отделаться одной маленькой правкой. Поэтому использовать инструмент, допускающий подход "изменим сейчас, а с последствиями разберемя потом", нерационально.
Oeryn писал(а):В общем, если в дизайне фиксированное количество типизированных предметов, конструктор с тегами тут ни к чему. Если нужна гибкая процедурная генерация и настраиваемые внешним "скриптингом" шаблоны, добро пожаловать.
Не фиксированное количество типизированных предметов, а фиксированное число типов предметов. Класс предмета (который вероятно будет отражен одноименной конструкцией в коде) это не сам предмет, это и есть тот самый шаблон предмета, который должен настраиваться внешним скриптингом.
Пытается раскуклиться

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 11 сен 2013, 07:41

Cfyz писал(а):Существенные изменения структуры данных вынуждены сопровождаться симметричными изменениями алгоритмов, их обрабатывающих.
Все вышесказанное описывает зло от поэтапной переделки и наращивания структуры как таковой, против изначального планирования. Но в целом согласен, "скриптовый" конструктор более располагает к соблазну допилить еще новых и, возможно, не нужных фич.
Cfyz писал(а): Не фиксированное количество типизированных предметов, а фиксированное число типов предметов. Класс предмета (который вероятно будет отражен одноименной конструкцией в коде) это не сам предмет, это и есть тот самый шаблон предмета, который должен настраиваться внешним скриптингом.
Все верно, это и имел в виду. В первом случае шаблоны предметов хардкодятся в виде классов предметов, которые наследованиями обобщают и выделяют функционал, во втором настраивается внешним скриптом из тегов, которые включают необходимый функционал.

Да, тут еще такой нюанс, действую по принципу - для каждого класса, экземпляры которого создаются динамически (предметы, монстры и т.д.), предусматриваю объект-менеджер, который управляет их временем жизни. Фактически это "базы/коллекции" которые умеют создать экземпляр объекта из шаблона и корректно удалить/очистить память. Что удобно реализуется когда, например, все возможные предметы это один и тот же класс и управляются одним менеджером.
В случае когда предметы представлены разными классами, как корректно сделать менеджер для них? Отдельно создавать менеджер для каждого класса и один менеджер, который хранит списки для каждого класса?
(Да, это не выпад и не спор по поводу классы/теги. Интересуюсь самой реализацией.)

Аватара пользователя
Cfyz
Сообщения: 776
Зарегистрирован: 30 ноя 2006, 10:03
Откуда: Санкт-Петербург
Контактная информация:

Re: jarg

Сообщение Cfyz » 11 сен 2013, 08:52

Oreyn писал(а):для каждого класса, экземпляры которого создаются динамически (предметы, монстры и т.д.), предусматриваю объект-менеджер, который управляет их временем жизни. Фактически это "базы/коллекции" которые умеют создать экземпляр объекта из шаблона и корректно удалить/очистить память.
А какой это ЯП и что входит в "управление временем жизни" и "корректно удалить/очистить"?

(Я надеюсь топикстартер не против того, что мы тут развели.)
Пытается раскуклиться

Аватара пользователя
Максим Кич
Администратор
Сообщения: 1642
Зарегистрирован: 03 дек 2006, 20:17
Откуда: Витебск, Беларусь
Контактная информация:

Re: jarg

Сообщение Максим Кич » 11 сен 2013, 08:55

Oreyn писал(а): Да, тут еще такой нюанс, действую по принципу - для каждого класса, экземпляры которого создаются динамически (предметы, монстры и т.д.), предусматриваю объект-менеджер, который управляет их временем жизни. Фактически это "базы/коллекции" которые умеют создать экземпляр объекта из шаблона и корректно удалить/очистить память. Что удобно реализуется когда, например, все возможные предметы это один и тот же класс и управляются одним менеджером.
В случае когда предметы представлены разными классами, как корректно сделать менеджер для них? Отдельно создавать менеджер для каждого класса и один менеджер, который хранит списки для каждого класса?
(Да, это не выпад и не спор по поводу классы/теги. Интересуюсь самой реализацией.)

А разве объект не должен сам за собой подчищать память? В том плане, что идея деструктора как раз в этом и состоит. Тогда на совести «менеджера» остаётся: вызвать деструктор объекта (который по умолчанию у него есть вне зависимости какому классу он принадлежит) и удалить из коллекции ссылку, которая после вызова деструктора ведёт в никуда.

Потом, если у нас в одной коллекции оказываются экземпляры разных классов, то эти классы в любом случае имеют хотя бы какую-то общность. Я не большой знаток C#, но в любом случае, либо это потомки одного предка, либо они «крякают похоже», либо им была сделана одна и та же инъекция. Т.е. требование к таким классам одинаково реагировать на требования менеджера — более чем выполнимо. А как они убивают свои ресурсы и какие события порождают при этом — это должно быть отдано на откуп самим объектам.

Опять же, я бы разделил Фабрику (то, что создаёт экземпляр объекта) и Коллекцию (то, что хранит экземпляры объекта). Потому что они чисто архитектурно могут захотеть жить в разных местах. Чаще всего Фабрика — это синглтон, а Коллекций может быть много. Скажем, монстр может таскать с собой Коллекцию своих предметов. Убиваем монстра, его деструктор отправляет указатель на Коллекцию в соответствующий сеттер клетки, в которой монстр убит, и освобождает остальные свои ресурсы. Как результат, Коллекция лежит на полу. С другой стороны, мы когда мы генерируем уровень, мы обращаемся к Фабрике монстров, которые, при рождении могут при необходимости обращаться к Фабрике предметов чтобы наполнить себе карманы. Создавать персональную Фабрику для каждого монстра нет смысла — поэтому она у нас либо просто одна и мы знаем где её искать, либо это синглтон, и нам даже искать её не надо.
Dump the screen? [y/n]

Аватара пользователя
Максим Кич
Администратор
Сообщения: 1642
Зарегистрирован: 03 дек 2006, 20:17
Откуда: Витебск, Беларусь
Контактная информация:

Re: jarg

Сообщение Максим Кич » 11 сен 2013, 09:26

Cfyz писал(а):(Я надеюсь топикстартер не против того, что мы тут развели.)
Где-то была подходящая тема, если что, я просто перекину сообщения туда.
Dump the screen? [y/n]

Аватара пользователя
Oreyn
Сообщения: 297
Зарегистрирован: 07 авг 2013, 14:59

Re: jarg

Сообщение Oreyn » 11 сен 2013, 14:16

Cfyz писал(а):А какой это ЯП и что входит в "управление временем жизни" и "корректно удалить/очистить"?
Максим Кич писал(а): А разве объект не должен сам за собой подчищать память? В том плане, что идея деструктора как раз в этом и состоит. Тогда на совести «менеджера» остаётся: вызвать деструктор объекта (который по умолчанию у него есть вне зависимости какому классу он принадлежит) и удалить из коллекции ссылку, которая после вызова деструктора ведёт в никуда.
Язык С++. Посмотрел, действительно и тут можно же объявить массив указателей на базовый объект и наполнять его ссылками на новосозданные производные объекты.
И да, все верно, про роль менеджера и вызов деструкторов. Оценил идею разделить "фабрику" и "хранилище".

Аватара пользователя
Максим Кич
Администратор
Сообщения: 1642
Зарегистрирован: 03 дек 2006, 20:17
Откуда: Витебск, Беларусь
Контактная информация:

Re: jarg

Сообщение Максим Кич » 03 окт 2013, 21:21

ishellstrike писал(а):Попал в ступор с генерацией дрог, карта бесконечная, генерируется по шумовой сглаженной функции. Практически даже нет идей. Разве что нагенерировать заранее очень большой массив с дорогами, скажем [1000, 1000] секторов (не 1000000 элементов конечно, разреженный), для бесконечной карты зазеркалить его, а потом при генерации очередного сектора сверяться с ним. И с городами так же поступить?
На самом деле, тут не хватает вопроса. В чём проблема?

Проблема с тем, что карта бесконечная? Генерить по мере необходимости. Всё равно бесконечную карту игрок всё не обойдёт. Генерить вместе с городами, а точнее сразу после городов. Города, по хорошему, надо расставлять вдоль рек/озёр/морей, но этим можно и пренебречь — вон, ZAngband кидал как RNG на душу положит и никто не жаловался.

Проблема с тем, что каждый тайл дороги надо описать? Кривые Безье нам в помощь. Или сплайны. Или и то, и другое.

Проблема провести дорогу по карте — ну тут уже надо смотреть, что там твоя «шумовая сглаженная» выдаёт на-гора.
Dump the screen? [y/n]

Ответить

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 31 гость