Поэтому я создаю игру, в которой вы можете отправлять корабли в разные места, чтобы продавать или покупать такие ресурсы, как дерево, железо, золото и т. Д.
Теперь мне было интересно, как ресурсы должны создаваться в игре. Я придумал 2 варианта
Создайте класс для каждого ресурса:
public class ResourceBase { private int value; // other base properties } public class Gold : ResourceBase { public Gold { this.value = 40 // or whatever } }
Создать экземпляры класса Resource
public class Resource { string name; int value; public Resource(string name, int value) { this.name = name; this.value = value; } } // later on... Resource gold = new Resource("Gold",40);
Со вторым вариантом можно заполнить игровые ресурсы из файла resources.json, мне нравится эта структура.
Новые идеи / шаблоны дизайна / структуры всегда приветствуются!
РЕДАКТИРОВАТЬ: Это немного похоже на приложение-компаньон Assassins Creed Black Flag. Смотрите панель ресурсов на изображении ниже
РЕДАКТИРОВАТЬ 2: Я провел еще несколько исследований "загрузки элементов / ресурсов из файла JSON" и нашел этот блог: Сила JSON в разработке игр - Предметы . Он показывает лучшее из варианта 1 и варианта 2. Вы все еще можете добавить функциональность для каждого ресурса :)
источник
enum
вместо.Ответы:
Переходите ко второму подходу, просто потому, что вы можете в любое время вводить новые типы ресурсов или элементы без необходимости переписывать или обновлять код ( разработка на основе данных ).
Редактировать:
Чтобы более подробно рассказать о том, почему это в целом хорошая практика, даже если вы на 100% уверены, что какое-то значение никогда не изменится.
Давайте возьмем пример консольной игры, упомянутый в комментариях, потому что это дает очень вескую причину того, почему вы не должны жестко кодировать что-либо, если вы действительно не имеете (или не хотите), например, ключи шифрования, ваше собственное имя и т.д.
При выпуске игры на консолях, они обычно должны проходить процесс обзора, при котором собственный QA производителя консоли будет тестировать игру, играть в нее, искать проблемы и т. Д. Это обязательно и стоит денег, больших денег. Я думаю, что однажды прочитал, что выпуск может стоить 30 000-50 000 долларов только за сертификацию.
Теперь представьте, что вы запускаете игру, платите 30 000 долларов и ждете. И вдруг вы замечаете, что некоторые из ваших игровых ценностей буквально нарушены. Допустим, вы можете купить железные слитки за 50 золотых и продать их за 55 золотых.
Чем ты занимаешься? Если вы жестко запрограммировали этот материал, вам придется создать новую версию обновления / выпуска, которая должна будет еще раз пройти проверку, так что в худшем случае вы снова заплатите за повторную сертификацию! Бьюсь об заклад, Ubisoft не будет возражать, но для вашего собственного маленького кармана разработчиков инди-игр ... ой!
Но представьте себе, что игра просто время от времени проверяет наличие обновленных определений игры (например, в форме файла JSON). Ваша игра может загружать и использовать последнюю версию в любое время, не требуя обновления. Вы можете исправить этот дисбаланс / эксплойт / ошибку в любое время, не требуя повторной сертификации или других уплаченных денег. Просто какое-то незначительное дизайнерское решение, вы не думали, что оно того стоило, просто сэкономили вам 5-значную сумму денег! Разве это не круто? :)
Только не пойми меня неправильно. Это также относится к другим типам программного обеспечения и платформ. Загрузка обновленных файлов данных в целом намного проще и выполнима для обычного пользователя, независимо от того, игра это или какое-то приложение / инструмент. Представьте себе игру, установленную в Program Files в Windows. Для обновления вам нужны права администратора, и вы не можете изменять запущенные программы. С DDD ваша программа просто загружает данные и использует их. Плеер может даже не заметить, что произошло обновление.
источник
Практическое правило заключается в том, что вы используете разные классы, когда для объектов требуется разный код и экземпляры одного и того же класса, когда для объектов требуются только разные значения.
Когда ресурсы имеют различную игровую механику, которая является уникальной для них, может иметь смысл представлять их с помощью классов. Например, если у вас есть Плутоний, который имеет период полураспада, и Кролики, которые размножаются в соответствии с последовательностью Фибоначчи , то может иметь смысл иметь базовый класс
Resource
с методом,Update
реализованным как неоперативный, и двумя производными классами,HalfLifeResource
иSelfGrowingResource
который переопределите этот метод, чтобы уменьшить / увеличить значение (и, возможно, также включить логику, чтобы управлять тем, что происходит, когда вы храните оба рядом друг с другом).Но когда ваши ресурсы на самом деле являются просто глупыми числами, тогда нет смысла реализовывать их с помощью чего-то более фантастического, чем простая переменная.
источник
Я хотел бы добавить, что есть две дополнительные опции:
Интерфейс: вы можете рассмотреть это, если класс ресурсов будет просто «хранилищем» для 5 целых чисел, и каждая сущность будет иметь различную логику в отношении ресурсов (например, тратить / добывать игрока, город производит ресурс). В этом случае вам может вообще не понадобиться класс - вы просто хотели показать, что у некоторой сущности есть переменная, с которой другие могут взаимодействовать:
Кроме того, у этого есть преимущество: вы можете грабить город с точно таким же кодом, как и с вражеским флотом, способствуя повторному использованию кода.
Недостатком является то, что реализация такого интерфейса может оказаться утомительной, если его реализуют многие классы, так что вы можете использовать интерфейсы, но не исходную проблему, решив ее с помощью опции 1 или 2:
Экземпляры (с перечислением): в некоторых случаях было бы желательно использовать перечисление вместо строки при определении типа ресурса:
это обеспечит некоторую «безопасность», потому что ваша IDE предоставит вам список всех допустимых ресурсов при назначении его после написания точки
ResourceType = Resource.
, кроме того, есть дополнительные «хитрости» с перечислениями, которые вам могут понадобиться, такие как явный тип или композиция / флаги который я могу себе представить полезным при создании:Что касается того, что лучше - серебряной пули нет, но лично я склоняюсь к любой форме экземпляров, они могут быть не такими причудливыми, как интерфейс, но они просты, не загромождают дерево наследования и широко поняты.
источник
my-great-enum
) в какое-либо C # -образующее представление enum (MyGreatEnum
).Вы должны использовать вариант 1, который имеет 3 преимущества:
new Gold(50)
resource instanceof Gold
источник
Если у ваших ресурсов нет собственной бизнес-логики или особых сценариев взаимодействия с окружающей средой, другими ресурсами (помимо торговли, о которой вы рассказали) или игроком, то второй вариант делает добавление новых очень простым.
Если вам нужно рассмотреть ситуации, например, что произойдет, если вы смешаете два ресурса для крафта, если ресурсы могут иметь совершенно разные свойства (ведро воды сильно отличается от куска угля) или другие сложные экономические взаимодействия, тогда подход 1 - это гораздо более гибкий для двигателя, но не данные.
источник