Ну так от разрастания самой базы никуда не деться, ведь она должна содержать всю информацию о всех предметах. Но такое хранилище сложно сделать типизированным, поэтому предлагаю не заострять внимание на проблеме структуры именно базы (пусть это будет упомянутый тобой текстовый формат или что удобно), а рассматривать ее исключительно как внешнее хранилище описаний, своеобразный конфигурационный файл.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>
- Weapon (свойства: урон)
- Structure (свойства: высота)
- <Statue>
- Item (свойства: вес)
Для UI весь уровень -- это лишь массив GameObject. У GameObject достаточно свойств, чтобы быть отрисованным и на этом уровне абстракции этого достаточно. При попытке что-то поднять становится важно, является ли объект Item (может ли вообще быть поднят) и если да, каков его вес; весь инвентарь -- это список Item. Опять же, на этом уровне абстракции этого достаточно. При попытке взять Item (а предметов другого типа в инвентаре быть не может, он же список Item) в качестве оружия, проверяется является ли оно Weapon. Ну а слот под оружие именно типа Weapon, и значит при просчете атаки можно будет не задумываться о наличии или отсутствии полей, в слоте точно Weapon с описанием, материалом, весом и уроном.
То же самое можно сделать и без наследования (NetHack, anyone?), достаточно аккуратно следить что куда идет, но таким образом достигается несколько удобных моментов:
1. Объект не захламляется полями там, где это не нужно (GameObject для UI не имеет ни урона, ни питательности), но всегда имеет их там, где это нужно (слот оружия в руке).
2. За выполнением условий какой тип где может быть использован следит компилятор, который куда внимательнее человека.
3. Обобщение игровой логики, которой не важен подтип объекта, производится нагляднее, так как не важно может быть с любого удобного узла иерархии.
Конкретная иерархия и набор свойств взяты из воздуха для наглядности. Очевидно, что в конкретной игре все будет по-другому, в зависимости от игровой механики.
В такой ситуации использование базы объектов сводится к определению конкретного класса в коде, экземпляром которого будет объект, и загрузке всех его свойств в соответствующие поля.