Я не уверен, читаете ли вы это до сих пор, но я долго боролся с подобной проблемой.
Я разработал множество различных типов систем воздействия. Я кратко расскажу о них сейчас. Это все основано на моем опыте. Я не утверждаю, что знаю все ответы.
Статические модификаторы
Этот тип системы в основном полагается на простые целые числа для определения любых модификаций. Например, от +100 до Макс. HP, +10 к атаке и так далее. Эта система также может обрабатывать проценты. Вам просто нужно убедиться, что укладка не выходит из-под контроля.
Я никогда не кэшировал сгенерированные значения для системы такого типа. Например, если бы я хотел показать максимальное здоровье чего-либо, я бы сгенерировал значение на месте. Это предотвратило склонность к ошибкам и облегчило понимание для всех участников.
(Я работаю на Java, поэтому ниже следует Java, но он должен работать с некоторыми модификациями для других языков). Эту систему можно легко сделать, используя перечисления для типов модификации, а затем целые числа. Конечный результат может быть помещен в какую-то коллекцию, которая имеет пары упорядоченных ключей и значений. Это будет быстрый поиск и расчеты, поэтому производительность очень хорошая.
В целом, это работает очень хорошо с простыми статическими модификаторами Тем не менее, код должен существовать в надлежащих местах для используемых модификаторов: getAttack, getMaxHP, getMeleeDamage и так далее и так далее.
Там, где этот метод не работает (для меня) очень сложное взаимодействие между любителями. Нет реального простого способа взаимодействия, кроме как немного поднять его. У него есть несколько простых возможностей взаимодействия. Чтобы сделать это, вы должны внести изменения в способ хранения статических модификаторов. Вместо использования enum в качестве ключа, вы используете String. Эта строка будет именем Enum + дополнительная переменная. 9 раз из 10 дополнительная переменная не используется, поэтому вы по-прежнему сохраняете имя перечисления в качестве ключа.
Давайте сделаем быстрый пример: если вы хотите иметь возможность изменять урон против нежити, у вас может быть упорядоченная пара, подобная этой: (DAMAGE_Undead, 10) DAMAGE - это Enum, а Undead - дополнительная переменная. Поэтому во время боя вы можете сделать что-то вроде:
dam += attacker.getMod(Mod.DAMAGE + npc.getRaceFamily()); //in this case the race family would be undead
В любом случае, это работает довольно хорошо и быстро. Но он терпит неудачу при сложных взаимодействиях и наличии «специального» кода везде. Например, рассмотрим ситуацию с «25% шансом телепортироваться при смерти». Это «довольно» сложный вопрос. Вышеуказанная система может справиться с этим, но не легко, так как вам необходимо следующее:
- Определите, есть ли у игрока этот мод.
- Где-нибудь, есть код для выполнения телепортации, если все прошло успешно. Расположение этого кода само по себе является обсуждением!
- Получить правильные данные с карты модов. Что означает значение? Это комната, где они тоже телепортируются? Что, если у игрока есть два мода на телепорт? Не сложатся ли суммы вместе ?????? ПРОВАЛ!
Так что это подводит меня к следующему:
Ультимативная комплексная система баффов
Однажды я попытался написать 2D-MMORPG самостоятельно. Это была ужасная ошибка, но я многому научился!
Я переписал систему аффектов 3 раза. Первый использовал менее мощный вариант из вышеперечисленного. Вторым было то, о чем я собираюсь поговорить.
Эта система имела ряд классов для каждой модификации, поэтому такие вещи, как: ChangeHP, ChangeMaxHP, ChangeHPByPercent, ChangeMaxByPercent. У меня был миллион таких парней - даже такие вещи, как TeleportOnDeath.
У моих классов были вещи, которые делали следующее:
- applyAffect
- removeAffect
- checkForInteraction <--- важно
Применить и удалить объяснить сами (хотя для таких вещей, как проценты, эффект будет отслеживать, насколько он увеличил HP, чтобы убедиться, что когда эффект исчезает, он только удалит добавленную сумму. Это было с ошибками, lol, и Мне потребовалось много времени, чтобы убедиться, что это правильно. У меня все еще не было хорошего чувства по этому поводу.).
Метод checkForInteraction был ужасно сложным фрагментом кода. В каждом из классов аффектов (т. Е. ChangeHP) он будет иметь код, чтобы определить, должен ли он быть изменен входным аффектом. Так, например, если у вас было что-то вроде ....
- Buff 1: Наносит 10 ед. Урона от огня при атаке
- Buff 2: Увеличивает весь урон от огня на 25%.
- Buff 3: Увеличивает весь урон от огня на 15.
Метод checkForInteraction будет обрабатывать все эти эффекты. Для этого нужно было проверить каждое влияние на ВСЕХ игроков поблизости! Это потому, что тип аффектов, с которыми я сталкивался у нескольких игроков на протяжении области. Это означает, что в коде НИКОГДА не было каких-либо специальных утверждений, подобных приведенным выше - «если мы только что умерли, мы должны проверить телепорт при смерти». Эта система будет автоматически обрабатывать его правильно в нужное время.
Попытка написать эту систему заняла у меня около 2 месяцев и несколько раз заставила голову взорваться. ОДНАКО, он был ДЕЙСТВИТЕЛЬНО мощным и мог делать безумное количество вещей - особенно если учесть следующие два факта для способностей в моей игре: 1. У них были целевые диапазоны (то есть: одиночный, сам, только группа, PB AE self , PB AE target, целевой AE и т. Д.). 2. Способности могут иметь более 1 влияния на них.
Как я уже упоминал выше, это была 2-ая из 3-х аффектных систем для этой игры. Почему я отошел от этого?
У этой системы была худшая производительность, которую я когда-либо видел! Это было ужасно медленно, так как нужно было так много проверять каждую происходящую вещь. Я пытался улучшить его, но счел это неудачей.
Итак, мы подошли к моей третьей версии (и другому типу баффов):
Комплексный аффект-класс с обработчиками
Так что это в значительной степени комбинация первых двух: у нас могут быть статические переменные в классе Affect, который содержит множество функций и дополнительных данных. Затем просто вызовите обработчики (для меня, скорее, некоторые статические служебные методы вместо подклассов для конкретных действий. Но я уверен, что вы можете использовать подклассы для действий, если вы тоже этого хотите), когда мы хотим что-то сделать.
Класс Affect будет содержать все сочные полезные вещи, такие как целевые типы, продолжительность, количество использований, шанс выполнения и так далее, и так далее.
Мы все равно должны были бы добавить специальные коды для обработки ситуаций, например, телепортации после смерти. Нам все равно придется проверять это в боевом коде вручную, а затем, если он существует, мы получим список эффектов. Этот список аффектов содержит все применяемые в настоящее время аффекты на игрока, который имел дело с телепортацией после смерти. Затем мы просто посмотрели бы на каждый из них и проверили, выполнялся ли он и был ли он успешным (остановимся на первом успешном). Если все прошло успешно, мы бы просто позвонили обработчику, чтобы позаботиться об этом.
Взаимодействие может быть сделано, если вы тоже хотите. Нужно просто написать код, чтобы искать конкретные баффы для игроков и т. Д. Поскольку он имеет хорошую производительность (см. Ниже), он должен быть достаточно эффективным для этого. Просто нужны более сложные обработчики и так далее.
Таким образом, она имеет высокую производительность первой системы и все еще очень сложна, как вторая (но не так много). В Java, по крайней мере, вы можете сделать несколько хитрых вещей, чтобы получить производительность почти первой в большинстве случаев (например, наличие карты enum ( http://docs.oracle.com/javase/6/docs/api/java) /util/EnumMap.html ) с Enums в качестве ключей и ArrayList воздействий в качестве значений. Это позволяет увидеть, есть ли у вас быстрые эффекты [поскольку список будет равен 0, или на карте не будет перечисления], и не иметь постоянно перебирать списки аффектов игрока без всякой причины. Я не возражаю перебирать аффекты, если они нам нужны в данный момент. Я оптимизирую позже, если это станет проблемой).
В настоящее время я заново открываю (переписываю игру на Java вместо базы кода FastROM, в которой она была изначально), мой MUD, который закончился в 2005 году, и недавно я столкнулся с тем, как я хочу реализовать свою систему баффов? Я собираюсь использовать эту систему, потому что она хорошо работала в моей предыдущей неудачной игре.
Что ж, надеюсь, кто-нибудь где-нибудь найдет некоторые из этих идей полезными.