Что такое хорошая структура данных Java для хранения предметов RPG Game? - PullRequest
8 голосов
/ 01 апреля 2012

Я создаю RPG-игру для подземелий на Java и застрял в создании структуры данных.

У меня есть много объектов Thing, которые я могу скопировать, чтобы заполнить подземелье.Например, есть объект Thing с хлебом, объект Thing с мечом, объект Thing с кольчугой, существо (я) монстров и т. Д. Я хочу сохранить их в центральной библиотеке, а затем иметь возможность извлекать объект, используя определенныезапросы.Я хочу хранить их, используя следующие поля:

int minLevel
int maxLevel
double probability
int[] types

Таким образом, у ржавого меча будет minLevel 1, maxLevel 3, probability редкости (3%),и [type.SWORD,type.WEAPON,type.ITEM,TYPE.EQUIP].Лучший меч имел бы minLevel 2, maxLevel 10, редкость (1%).

Тогда я хочу получить случайный type.SWORD из библиотеки и сказать, что я на уровне 3. Яследует приобретать ржавый меч чаще, чем лучший, исходя из их вероятности.Если бы я извлек type.SWORD из библиотеки, запрашивая уровень 10, я бы вернул только лучший меч.

Надеюсь, это имеет смысл.

РЕДАКТИРОВАТЬ ВНа этапе инициализации будут созданы все основные объекты.Такие вещи, как доступное оружие, броня, еда, зелья, палочки, все основные возможные вещи, которые имеют уникальную графическую плитку в игре.Затем, когда я хочу разместить объект где-нибудь, я просто делаю копию одной из доступных вещей, немного корректирую ее статистику и втыкаю ее в мир.Фактические предметы - это подкласс корневого класса Thing, такие как класс Creature, Item, Equip (расширяет предмет), Weapon (расширяет снаряжение), Armor (расширяет снаряжение), Food (расширяет предмет) и т. Д. Но я хочу отметитьони разные в базе данных библиотеки, я хочу использовать дополнительные теги, такие как type.RARE, type.ARTIFACT, type.CURSED, поэтому я хочу, чтобы дополнительные теги помимо класса.

Игра использует LIBGDX, чтобы быть доступнойна Android и в качестве апплета.Я использую бесплатный набор Rltile, в котором тысячи хороших плиток.Я буду использовать Pubnub или Google App Engine для поддержки многопользовательской игры.

Ответы [ 2 ]

5 голосов
/ 01 апреля 2012

Я могу придумать три ответа:

  1. написать свой собственный Library, который хранит эти вещи в Map с пользовательскими методами.так что у вас может быть Map<Type,List<Object>>, в котором хранятся списки вещей по типу, а затем метод, который принимает тип, извлекает список из карты и выбирает что-то по вероятности (это легко сделать - вы просто повышаете вероятность, генерируетеслучайное число между 0 и суммой, а затем пройтись по списку, вычитая вероятность элемента из вашего случайного значения, пока оно не станет отрицательным - вы возвращаете элемент, который сделал его отрицательным [*]).Вы также можете фильтровать список сначала по уровню, например.

    , если у вас есть реальное сочетание разных вещей, и вы не хотите основывать это на типах, тогда другой вариант (медленнее, но более гибок)это разместить все в списке, а затем отфильтровать по вашим потребностям.хороший способ сделать это с помощью guava - см. Iterables.filter и Predicate в https://code.google.com/p/guava-libraries/.. Вы можете предоставить интерфейс, который принимает предикат и возвращает случайный выбор из того, что осталось после фильтрации.предикаты легко построить «встраиваемыми» с анонимными классами - см. примеры в https://code.google.com/p/guava-libraries/wiki/FunctionalExplained#Functions_and_Predicates

  2. , все это хранится в базе данных.Может быть, я слишком предприимчив, и люди, играющие в игры, никогда бы этого не сделали, но мне кажется, что небольшая встроенная база данных, такая как sqlite или H2, была бы идеальной для этого.затем вы можете выбирать вещи с помощью SQL-запросов (это уже длинный ответ, поэтому я не буду здесь подробно останавливаться).

  3. измените ваш дизайн.то что вы описываете не очень ОО.вместо типов ваши Вещи могут реализовывать интерфейсы.так, например, интерфейс Weapon будет иметь метод getMinLevel().и затем, с таким дизайном, используйте базу данных с ORM (hibernate).

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

[*] это предполагает, что вы всегда хотите что-то вернуть.если вероятности нормализованы, и вы не хотите ничего возвращать, выберите начальное значение от 0 до 1 (или от 0 до 100, если используются проценты).и, если ничто не превращает значение в отрицательное при выполнении списка, ничего не возвращается.

2 голосов
/ 01 апреля 2012

Самый простой подход - поместить все ваши объекты в один большой массив и использовать повторную выборку для выбора объекта.

Процедура выбора случайного элемента очень проста:

  1. Выберите случайное число от 0 до размера ArrayList
  2. Получить объект по этому индексу из библиотеки
  3. Если объект не соответствует заданным вами критериям (например, "имеет тип.SWORD или type.MACE? ") вернуться к началу
  4. Если объект находится за пределами минимального или максимального уровня, вернуться к началу
  5. Если объект имеет редкостьменее 100%, создать случайное число от 0 до 100%.Если случайное число превышает редкость объекта, вернитесь к началу.Большинство объектов должны иметь редкость, скажем, 10-100%, если вы хотите чрезвычайно распространенные объекты, вы можете добавить их несколько раз в библиотеку.

Эта процедура произведет объект, который удовлетворяет критериям раньшеили позже (если он существует) и будет делать это в соответствии с процентом редкости.

Одна небольшая хитрость заключается в том, что он будет зацикливаться бесконечно, если такого объекта не существует.Предположим, что в библиотеке нет уровня на 17 уровне, например?Чтобы обойти это, я бы предложил расширить minLevel и maxLevel после каждых 100 попыток, чтобы в конце концов найти их.Убедитесь, что у вас всегда есть объект уровня 1 каждого типа.

В целях безопасности вы можете также потребовать спасения после, скажем, 100 000 попыток (но не забывайте выдавать исключение - это проблема, если вы запрашиваете вещикоторые не существуют в библиотеке!).

PS Я реализовал подобную библиотечную систему в похожей на мошенников игре под названием Tyrant, которую я создал много лет назад.Источник здесь, если вы заинтересованы:

https://github.com/mikera/tyrant/blob/master/src/main/java/mikera/engine/Lib.java

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...