Проект шаблон/игра.
Гибкая процедурная генерация данжа.
Самописный DI через рефлекцию.
Универсальная модульная система предметов.
И другие модули для работы с датой, ассетами, таймерами и тд.
Где что: Assets/App
- /Common - шаблонный код
- /Game - код основной игры, сейчас там мало чего написано, нечего смотреть
- /Generation - код генерации данжа, завершен, можно посмотреть
Помечаем класс аттрибутов Scoped и экземпляр класса добавится в di. В качестве параметра передаётся контекст, в данном случае это сцена.
[Scoped(typeof(GameSceneContext))]
public class GameItemsManager
{
...
}
Помечаются поля класса в которые заинжектятся экземпляры. Можно инжектить по интерфейсу, конкретный экзампляр и список
[Scoped(typeof(GameSceneContext))]
public class ModuleItemsManager
{
[Inject] private readonly IContainersDataManager m_ContainersDataManager;
[Inject] private readonly List<IModuleDtoToConfigConverter> m_ModuleDtoToConfigConverters;
[Inject] private readonly Logger m_Logger;
}
Помечаются классы, которые должны существовать всё время.
[Singleton]
public class ContainersDataManagerProxy : IContainersDataManager
{
}
Проблема: есть инвентарь. Как положить туда абсолютно разное... всё, не меняя код при добавлении нового типа (броня, карточки для гвинта, заклинание)
Решение: в дате инвентаря, хранить только список ссылок на предметы. Ссылка выглядит примерно так
public class DataReference
{
public string Key => m_Key; // id контейнера, в котором лежат конкретные экземпляры
public int Index => m_Index; // индекс элемента в списке контейнера
...
}
Проблема: есть оружие. Хочу добавить ему зачарование. Для зачарования нужна дата. Все даты зачарований уникальны и изменяются. Как не хранить в дате предмета список дат-интерфейсов для зачарований. (потому что они плохо парсятся)
Решение: хранить в дате предмета, список ссылок на даты зачарований
public class ModuleItemData
{
public string Id => m_Id; // id предмета
public List<DataReference> ModuleRefs => m_ModuleRefs; // список ссылок на даты модулей
...
}
Assets/App/Common/Data - DataManager, который сохраняет дату
Assets/App/Common/DataContainer - Контейнеры дат. Те самые ссылки на дату.
Assets/App/Common/ModuleItem - Модульные предметы
Assets/App/Game/GameItems - Пример использования модульных предметов (броня, оружие)
Код лежит туть
Генерация данжа состоит из шагов, которые можно добавлять в DungeonGenerator или через агрегацию.
Шаги на скрине
- Создание комнат
- Расталкивание комнат так, чтобы они не пересекались
- Выбор маленьких комнат
- Удаление маленьких комнат
- Выбор комнат, расстояние между которыми меньше заданного значения
- Удаление комнат из предыдущего шага
- Создание графа из комнат и применение Триангуляции Делоне
- Создание минимального остовного дерева через алгоритм Краскала
- Создание корридоров - комнат между комнатами
- Обход графа в ширину и выбор начальной и конечной комнаты
- Создание дороги из начальной в конечную комнату через обход графа в глубину
- Распределение ключей для дверей так, чтобы пришлось посетить каждую комнату в данже
- Создание стен
- Создание дверей
