Как я могу определить элементы в моей RPG, как Java-игра?

21

Я случайно работаю над игрой типа RPG на Java, но у меня возникают проблемы с выяснением того, как я могу иметь элементы, которые могут делать много разных вещей, не создавая разные классы для каждого элемента.

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

Если я расширяю класс рубки или оружие, то я не могу расширить другой класс.

Если у меня есть разделка, а оружие - интерфейс, то у меня будет много дублированного кода, когда кинжал может атаковать монстров, а другой топор может рубить деревья.

Я надеюсь, что есть способ иметь один класс Item и загружать элементы и их соответствующие способности из файла. Если это возможно, как это можно сделать? Если это не так, каков наилучший способ иметь предметы в игре?

MESLewis
источник

Ответы:

15

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

Чтобы загрузить из файла:

Во-первых, используйте YAML. YAML - это язык описания данных; он может быть проанализирован относительно быстро, прочитан и отредактирован людьми, поддерживает двоичные данные, и библиотеки существуют для большинства языков программирования, включая Java. Это решает "как мне получить данные из файлов в объекты?"

Во-вторых, используйте шаблон flyweight . Большая часть данных, которые вы читаете из этих файлов, является статической. Он не будет меняться в каждом случае («топор наносит 1d10 базового урона и разбивает дерево, но не камень» - это верно для всех пяти топоров, которые есть у игрока). На самом деле вы читаете из файлов YAML эти платонические определения, и ваши индивидуальные экземпляры имеют неопознанные (и постоянные) ссылки на них, а также данные для каждого экземпляра, такие как «Сколько качаний до того, как я сломался?», «Игрок дал мне нестандартное имя? »и так далее.

Обмениваясь данными между экземплярами в одном объекте, вы сохраняете много памяти и облегчаете обновление элементов без сохранения состояния игры (сохранение игр или базы данных игроков).

Итак, ваша структура классов выглядит примерно так:

  • Класс Item - один экземпляр на элемент
    • Владеет оружейным экземпляром
    • Owns-a Tool экземпляр
    • Имеет - нестандартное имя и т. Д.
  • Оружие класса - (до) один экземпляр за предмет
    • Is-a ItemComponent
    • Относится к WeaponDef
    • Имеет бонусный уровень зачарования и т. Д.
  • Инструмент класса - (до) один экземпляр на элемент
    • Is-a ItemComponent
    • Относится к ToolDef
    • Имеет - долговечность и т. Д.
  • Класс WeaponDef - один экземпляр для каждого вида оружия
    • Чтение из файла, поля должны быть постоянными.
    • Имеет базовое количество урона, 1 или 2 руки и т. Д.
  • класс ToolDef - один экземпляр для каждого вида инструмента
    • Чтение из файла, поля должны быть постоянными.
    • Имеет базовую прочность, материалы, которые он может сломать и т. Д.
Марко Зайц
источник
18

Шаблон проектирования Component (не Composite) отлично подходит для этой цели: http://gameprogrammingpatterns.com/component.html

По сути, Ax будет экземпляром класса Item, который содержит WeaponComponent и ToolComponent (возможно). Чтобы проверить, можно ли что-то использовать в качестве оружия, проверьте, к нему ли прикреплен оружейный компонент, а затем обратитесь к этому экземпляру WeaponComponent, чтобы получить информацию об оружии предмета.

Конечно, загрузка из файла - это отдельное упражнение.

Грегори Эйвери-Вейр
источник
И, конечно же, когда у вас есть компоненты, вы снова сможете эффективно использовать интерфейсы. Ваш тип Ax может реализовывать IChopper и IWeapon, но затем может раскрыть поведение компонента для него, позволяя вам повторно использовать как тип, так и реализацию по мере необходимости и исключая тест для компонентов. Если все оси имеют одинаковые возможности, но разные характеристики, то вы золотой. Если вам нужны элементы, обладающие уникальными способностями, вам может потребоваться реализовать коллекцию игровых компонентов и попросить ваши процедуры обновления запросить объекты о том, что они могут делать с помощью имеющихся компонентов.
CodexArcanum
6
@CodexArcanum: «Ваш тип Ax может реализовывать IChopper и IWeapon, но затем может отображать поведение компонента для него» - Какой смысл в этом? Это просто раздувает вашу иерархию классов. Смысл шаблона компонента в том, что вам не нужен класс Ax, интерфейс IChopper или интерфейс IWeapon, только конкретные компоненты Chopper и Weapon и элемент верхнего уровня.
В настоящее время я работаю над системой компонентов для своих игровых предметов и на самом деле имею только одну серьезную жалобу на то, как используется шаблон. Учитывая компоненты Оружия, Одежды и Расходуемого, предмет может быть теоретически «поврежден» с точки зрения предметов, которые не могут быть одновременно Оружием и Одеждой, или Одежды, которая также является Расходуемой. Логически элемент может быть только одним «Основным компонентом», но, ограничивая компоненты, вы устраняете необходимость в системе компонентов вместе. Таким образом, один из фундаментальных недостатков с иначе потрясающей системой
Krythic