Задать вопрос

Как с помощью ООП смоделировать сложный игровой мир?

Всем доброго времени суток!

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

В чём, собственно вопрос? Я для себя постоянно что-то пишу, велосипежу, так сказать, и сейчас мой взор направлен на создание RPG-движка с невероятно высокими требованиями по реалистичности. Ну, чтобы можно было камень с земли подобрать, кинуть в кого-то, или, например, ножку от стула оторвать, да пришить негодяя, либо снега отведать (почему нет?) и многое другое.

Всё это крайне пересекается с действительностью, а потому путь свой я начал с разработки системы онтологических категорий: `Entity`, `AbstractEntity`, `MaterialEntity`, `PhysicalObject`, ну и т.д. И всё было прекрасно до тех пор, пока я всерьёз не задумался о том, что действительно из себя представляют окружающие объекты?

Например, гитара. Это, вроде музыкальный инструмент, не так ли? Да вот как бы не так. Ещё это может быть оружием, а иногда - дровами для печки (если сильно надо).

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

Т.е. вместо того, чтобы смотреть на гитару и думать: "О, это гитара, сейчас как сыграю!", я, вероятнее всего, мыслю: "Визуальные свойства данного объекта связаны с уже известным понятием гитара, которое связано с понятиями музыкальный инструмент, дерево, рукоять, опасность порвать струну и т.д.".

Как вариант решения я вижу: АОП + КОП, но пока не уверен, что это не потому, что мои познания в ООП чересчур малы.

В общем, товарищи и коллеги, надеюсь, кто-то подсобит советом и рекомендациями, хотя бы с тем, где искать ответы на свои вопросы. Спасибо!

Update 1: добавлю немного кода.
public abstract class Entity
{
  public int Guid;
}

public abstract class MaterialEntity : Entity
{
  public Vector4 Position;
  public Vector3 Size;
}

public abstract class PhysicalObject : Entity
{
  public Mass Mass;
  public Temperature Temperature;
}

// Существо.
public abstract class Creature : PhysicalObject
{
  // Здоровье, мана и прочее.
}

// Предмет какой-нибудь.
public abstract class Thing : PhysicalObject
{

}


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

Ещё пример: оружие. Если продолжить так:
public class Weapon : Thing
{
  public int Damage;
}

public abstract class MusicalInstrument : Thing
{
  public abstract void PlayMusic();
}

То как потом показать, что гитара - может быть как музыкальным инструментом, так и оружием, в зависимости от желания и контекста? Кажется, что наследование не помогает.

Если инкапсулировать поведение в объекты, как в паттерне Стратегия, то где их располагать? Отвечая на такие вопросы я пришёл к выводу, что поможет исключительно КОП, т.к. я хочу динамические сущности с динамическим поведением, но, быть может, существуют практики, о которых ещё не знаю, которые позволяют справляться с такой сложностью.

Update 2: к сожалению и к моему удивлению, вопрос был многими неверно понят и, вероятнее всего, причиной этому послужила его неоднозначность и сложность интерпретации.

Так или иначе, для тех, кто, всё же, нашёл в нём что-то знакомое, с чем обязательно столкнулся бы всякий разработчик игр, пытающийся реализовать детскую мечту реалистичной игровой Вселенной, чем-то похожей на, скажем, серию TES (чем она и меня в своё время столь привлекала) и многие другие, я решил предоставить несколько наводок касаемо того, где искать ответ:
1. КОП - компонентно-ориентированное программирование. Примеры: Unity. Отсюда ES (Entity systems) - Artemis (C#).
2. АОП - аспектно-ориентированное программирование. Судя по описанию, в теории, может помочь.
3. Кажется (только половину прочёл), в книге Криса Партриджа Business objects: Re-engineering for Re-use вскрываются абсолютно те же проблемы, а также даётся полное описание того, как можно перепрошить парадигму мышления на иной лад, более похожий на действительность.
4. Также есть подозрения, что ответы будут в книге Object Thinking.

Всем спасибо за ответы и успехов!
  • Вопрос задан
  • 3356 просмотров
Подписаться 19 Оценить 13 комментариев
Пригласить эксперта
Ответы на вопрос 11
@ehs
Architect / 3d designer
А я бы посмотрел на задачу с другой стороны. Вот представьте ваш главный герой еще младенец, не знает что на гитаре можно играть, в костер дрова кидать, бутерброд даже не знает зачем. Он может поднять и съесть камень, гитару, да все что угодно. Вот и реализуйте все желаемые действия для персонажа, а всем объектам дайте только физические характеристики -размер, вес, температура, горючесть, жидкость. Дайте возможность герою сыграть музыку на камнях! И задача ваша будет описать возможную логику взаимодействий, как в жизни, как ребенка учить. Вот пытается герой съесть гитару - она по размерам не лезет в рот, сует камень - пусть подавится и помрет )
Ну и на этой печальной ноте я пожалуй закончу ))
Ответ написан
Комментировать
riky
@riky
Laravel
наверное можно было бы сделать это аналогично тому как в Unity у GameObject назначаются компоненты. то есть универсальные объекты для всего всего и к ним добавляются любые компоненты которые модифицируют их поведение.
Ответ написан
sim3x
@sim3x
Спроектируй простой
Усложни

Пока что у тебя слишком много теореизирований и слишком мало кода
Ответ написан
xmoonlight
@xmoonlight
https://sitecoder.blogspot.com
Ну, чтобы можно было камень с земли подобрать, кинуть в кого-то, или, например, ножку от стула оторвать, да пришить негодяя, либо снега отведать (почему нет?) и многое другое.

1. Решите проблему обработки объекта, как составного элемента из разных материалов, включая все физические и химические взаимодействия.
2. Оцените текущие ПК, возможности движков, затрачиваемые ресурсы и мощности видео-карт на один усреднённый объект.
3. Оцените трудозатраты на создание прототипа такого объекта: погреться у гитары и т.п.
4. Если желание не пропадёт, а мощности позволят - нужно будет много РАСПРЕДЕЛЁННЫХ человеко-ресурсов для наполнения мира такими предметами.
Объём работы - огромный!

Про код:
Объект - это коллекции экземпляров объектов "атомных классов", имеющий собственное "дерево" зависимостей и список состояний (гитара, дрова, линейка, пулемёт и т.д.) и принимающий в конкретный момент времени одно из этих состояний.
Состояния могут быть обратимыми и не обратимыми (поэтому "дерево" зависимостей): т.е., на поломанной на дрова гитаре, сыграть - нельзя, и из дров собрать рабочую гитару - тоже.
Ответ написан
@Jomeisama
Объектно-ориентированное мышление (2014)
Автор: Мэтт Вайсфельд
Ответ написан
Djaler
@Djaler
Сеньор-помидор
В Java, например, я бы решал это дело с помощью интерфейсов, а не абстрактных классов. Ибо класс может реализовывать много интерфейсов, а расширять только один класс. Так, например, класс Гитара может реализовывать интерфейс Музыкальный инструмент, у которого есть метод Играть, интерфейс Оружие с методом Бить, и так далее.
Ответ написан
@woodapiary
Начните проектировать модель с атрибутов объектов и связей между объектами/контейнеров объектов. Поведенческие характеристики оставьте на потом. Другими словами, подумайте как сохранить и загрузить модель в БД. Не будете же хардкодить, что в ваше модели при старте 5 гитар с 6 струнами и все гитары деревянные).
Это такой практический совет - плясать от реальных данных.
Ответ написан
@Cawich
в Java есть объект Object... так вот, более абстрагированную сущность тебе не надо.
З.Ы. по теме - чтобы реализовать расширяемую модель, тебе не надо придумывать велосипеды и костыли. почитай паттерны проектирования, почитай про IoC фреймворки... там все уже описано и расписано - как что и почем. проблема только в том, что мало кому удается соблюдать описанные правила полностью, потому что "ну вот тут явно так проще и надежнее". а потом появляются костыли, велосипеды, заглушки, ненужные фильтры и т.д.....
Ответ написан
webinar
@webinar
Учим yii: https://youtu.be/-WRMlGHLgRg
А почему бы не посмотреть как сделаны подобные движки? UnrealEngine, CryEngine и другие. По сути все что Вы описали там уже есть. Может стоит начать с разбора хорошо сделанного продукта, что бы понять, что бы понять что и как.
Ответ написан
@maxstroy
Подобная задача решалась нами в области безопасности. Произошло некоторое происшествие, следы которого нам известны - задымление, например. Но мы не знаем, то ли это пожар, то ли химическая атака, то ли взрыв гранаты при атаке террористов. Мы должны иметь возможность моделировать известные нам факты, считать вероятность тех или иных последствий и принимать решения об оптимальных действиях. Все это затискать в ООП нельзя. Сам я не программист, поскольку моя задача - создание моделей для таких кейсов. Эти модели создаются в предикатах первого и второго уровня. А вот те, кто кладет это в код, делятся впечатлениями о том, что программировать это лучше на функциональных языках программирования, хотя, повторю, что я в этом ничего не смыслю
Ответ написан
Комментировать
Santacruz
@Santacruz
Cryptocurrencies + Trading
composition vs inheritance
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы