Идеи для алгоритма повреждения атаки (язык не имеет значения)

8

Я работаю над игрой, и мне нужны идеи о том ущербе, который будет нанесен врагу, когда ваш игрок атакует. Общее количество здоровья, которое имеет противник, называется enemyHealth, и имеет значение 1000. Вы начинаете с оружием, которое наносит 40 пунктов урона (может быть изменено). У игрока есть характеристика атаки, которую вы можете увеличить, называемая playerAttack. Это значение начинается с 1, и может иметь максимальное значение 100 после того, как вы повысите его уровень многократно и сделаете его дальше в игре. Количество урона, наносимого оружием, сокращается и уменьшается, и каждый раз при попадании противника вычитается 40 очков из общего количества 1000 очков здоровья. Но то, что playerAttackделает, это добавляет к этому значению в процентах. Вот алгоритм, который я сейчас имею. (Я убрал все графические интерфейсы, классы и т. Д. И дал переменным очень точные имена)

double totalDamage = weaponDamage + (weaponDamage*(playerAttack*.05))
enemyHealth -= (int)totalDamage;

Похоже, это отлично работает по большей части. Итак, я проверил некоторые значения ...

//enemyHealth ALWAYS starts at 1000
weaponDamage = 50;
playerAttack = 30;

Если я установлю эти значения, то количество урона, нанесенного врагу, составит 125. Это выглядело как хорошее число, поэтому я хотел посмотреть, что произойдет, если атака игроков будет максимизирована, но с самым слабым стартовым оружием.

weaponDamage = 50;
playerAttack = 100;

totalDamage заканчивается 300, что убьет врага всего за несколько попаданий. Даже с такой высокой атакой я бы не хотел, чтобы самое слабое оружие могло так быстро убивать врага. Я думал о добавлении защиты, но я чувствую, что игра потеряет последовательность и станет несбалансированной в долгосрочной перспективе. Возможно, хорошо разработанный алгоритм модификатора уменьшения оружия подойдет для оружия более низкого уровня или чего-то в этом роде. Просто нужно сделать перерыв в попытках выяснить, как лучше всего это сделать, и, возможно, кто-то, имеющий опыт работы с играми и поддерживающий постоянный уровень, может дать мне несколько идей / указателей.

Dillon
источник
2
Я думаю, что нам нужно немного больше информации. Насколько легко выровнять свой playerAttackпоказатель до 100? Учитывая, что это максимальное значение, не будет ли уместным убийство врага в нескольких ударах? (Является ли враг 1000-HP чем-то, что вы увидите в начале игры? Стандартный враг? Босс?)
Ли

Ответы:

14

Ответ, предоставленный Grzegorz Sławecki, уже хороший, но я хотел объяснить обоснование его метода и дать вам инструменты для адаптации решений к вашим потребностям в игровом процессе.

Параметры настоящей задачи: уровень атаки игрока a , урон от оружия w , общий нанесенный урон за одну атаку d , здоровье врага H и минимальное количество ударов, необходимых для убийства врага, назовем его n .

Если вы хотите, чтобы игрок , чтобы убить в п хитов, то его общий ущерб d должен быть таким , чтобы

(n-1) .d <H ≤ nd    или, другими словами, n = ceil (H / d) .

d зависит от урона оружия w и уровня атаки игрока a, и мы можем ожидать, что оружие улучшается с ростом уровня, поэтому давайте напишем d (a) и w (a) вместо простых d и w . Также ожидается, что враги, с которыми сталкивается игрок, станут более жесткими, поэтому снова H (a) . Это все возрастающие функции , и вы хотите , чтобы они удовлетворяют указанные выше неравенства. Неизвестные проблемы являются функциями. Вы устанавливаете одно в качестве ограничения, а другие находите. У вас есть степени свободы, хотя это хорошо.

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

Предположим, например, что вы хотите, чтобы игрок получал все больше и больше ударов по ходу игры. Вы также хотите, чтобы по мере увеличения необходимого количества попаданий оно увеличивалось все реже и реже, чтобы игрок проводил большую часть игры, ударяя 5 раз, чем 2 раза. Вот как выглядит n (a) :

желаемый п (а)

Используемая функция: n (a) = ceil (2 / 3.srrt (a)) .

Мы хотим, чтобы H (a) / d (a) оставалось в пределах диапазонов значений, которые делают n (a) желаемым значением, и поскольку n (a) = ceil (H (a) / d (a)) , эти диапазоны являются следующие прямоугольники:

n (a) и n (a) -1

и H (a) / d (a), естественно, можно установить равным 2 / 3.sqrt (a), чтобы мы получили следующий график с красной кривой H (a) / d (a) :

n (a), n (a) -1 и H (a) / d (a)

Замечание: мы можем легко найти H (a) / d (a) здесь, потому что мы знаем функцию, для которой n (a) является ceil, но если бы наша спецификация для n была менее приятной, нам пришлось бы сделать нашу собственную подгонку функционировать, используя различные приемы. Не все проблемы такие приятные!

Итак, мы хотим, чтобы H (a) / d (a) напоминали настраиваемую функцию квадратного корня, и мы знаем, что H и d должны увеличивать функции. Решений много. Например,

H (a) = a. 2 / 3. площадь (а)    и    d (а) = а

Первое решение для H и D

Но мы бы хотели, чтобы урон и HP противника увеличивались очень сильно, чтобы в конце игры были большие, впечатляющие цифры, просто для стиля, поэтому мы вместо этого устанавливаем

H (a) = a². 20/3. Кв. (А)    и    d (а) = 10.a²

Лучшее решение для H и D

Весь смысл, и лучшая часть, заключается в следующем: вы знаете, что ваши решения проблемы ( H (a) и d (a) ) соответствуют спецификациям ( n (a) ), поэтому вы получаете то же самое n (a) , но у вас есть свобода. Вы точно знаете, какая у вас есть свобода, и вы можете использовать ее для настройки опыта. Вы должны всегда стараться дать себе такую ​​свободу, удовлетворяя при этом ваши самые важные потребности, когда это возможно.

Теперь, когда мы выбрали одноразовый урон d (a) , и поскольку d (a) зависит от урона от оружия w (a) , мы можем использовать d (a) в качестве нашей спецификации и попытаться найти w (a ), что дает нам это д (а) . Принципы одинаковы, проблема в другом: мы хотим, чтобы игрок наносил больше урона при увеличении его уровня, даже если оружие осталось прежним, и мы также хотим, чтобы урон увеличивался, когда само оружие улучшается, а уровень остается то же.

Но какое значение должен иметь каждый фактор? Предположим, мы хотим, чтобы уровень был важнее оружия: большая часть вариаций d (a) = a² должна быть независимой от w (a) , например, с

w (a) = 22.sqrt (a)    и, следовательно,    d (a) = (22.sqrt (a)). (10 / 22.a.sqrt (a)) = w (a). (10 / 22.a.sqrt (a))

Мы получаем следующий график для w (a) ...

ш (а)

... и все тот же г (а) , потому что мы снова нашли решение , которое подчинялось спецификации , здесь d (а) , и у нас есть свойства , указанные выше , с ш и вклад в повреждение (предположим , что мы смотрим на d как функция от a и w : тогда, если бы а были фиксированными, и мы имели бы w, изменяющийся в уравнении d (a, w) = a / 30.w , d все равно был бы возрастающей функцией от w , и то же самое верно если зафиксировать вес и сделать различаться).

Это w (a) может дать вам значение, которое будет отображаться в описании игрового оружия: мы получим «Урон от оружия: 220» с лучшим оружием в игре, например.

Мы могли бы использовать совершенно другую спецификацию для нашего игрового процесса и, следовательно, для n (a) , например, такую, которая заставляет число требуемых попаданий быстро увеличиваться по ходу игры, а затем и на плато, и полученные решения будут отличаться.

jrsala
источник
Это сочетает в себе хорошее понимание математики с геймплеем в качестве отправной точки. Отличный ответ.
Марки Томас
1
@MarcksThomas Ну, спасибо! Я бы хотел, чтобы больше людей четко определяли свои потребности и строили свои игры оттуда. Таким образом мы увидим более законченные, качественные игры.
Jrsala
Да, я согласен, что это идеальный ответ. Я читаю это с удовольствием :)
Grzegorz Sławecki
1
Фантастический! Я бы хотел, чтобы математика такого рода была более регулярной частью литературы по системному дизайну. (Может быть, мне стоит написать свое эссе о повреждениях и щитах когда-нибудь ...)
Стивен Стадницки,
Отличный ответ, но почему вы должны использовать однозначные переменные в ваших уравнениях? Сколько раз я спрашиваю: «Что aзначит снова?» и прокрутить вверх?
Даниэль Каплан
9

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

Ваша цель в игровом процессе - чтобы убить врага, требуется определенное количество ударов. Сколько хитов зависит от трех переменных:

  • уровень силы врага
  • уровень силы персонажа
  • уровень мощности оружия

Сначала вы должны создать таблицу всех возможных комбинаций этих трех переменных: низкий, средний или высокий уровень (пока нет конкретных чисел, только «низкий», «средний» или «высокий») и сколько хитов вы хотите потребоваться для этих комбинаций.

Затем вы должны попытаться найти формулу и диапазоны значений, которые лучше всего соответствуют вашим желаемым значениям.

Philipp
источник
7

Самый простой способ, это увеличить урон от оружия между уровнями оружия в геометрической прогрессии.

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

level   weapon  enemy   attack  total   hits needed
        dmg     hp      factor  dmg     to kill
======================================================
1       1       2       5       1.25    1.6
2       4       16      10      6       2.666666667
3       9       54      15      15.75   3.428571429
4       16      128     20      32      4
5       25      250     25      56.25   4.444444444
6       36      432     30      90      4.8
7       49      686     35      134.75  5.090909091
8       64      1024    40      192     5.333333333
9       81      1458    45      263.25  5.538461538
10      100     2000    50      350     5.714285714
11      121     2662    55      453.75  5.866666667
12      144     3456    60      576     6
13      169     4394    65      718.25  6.117647059
14      196     5488    70      882     6.222222222
15      225     6750    75      1068.75 6.315789474
16      256     8192    80      128     6.4
17      289     9826    85      1517.25 6.476190476
18      324     11664   90      1782    6.545454545
19      361     13718   95      2075.75 6.608695652
20      400     16000   100     2400    6.666666667
Куда:
1. общая сумма рассчитывается по Вашей формуле
2. оружие dmg = уровень * уровень (экспоненциальный рост)
3. враг hp = 2 * уровень * уровень * уровень (экспоненциальный рост)
4. фактор атаки = 5 * уровень
5. Число необходимых ударов описывает, сколько попаданий необходимо, находясь на уровне х и используя оружие на уровне х, чтобы убить врага на уровне х.

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

Вы также должны заметить, что, например, чтобы убить врага 20-го уровня с атакой 100 и оружием 1-го уровня, которое требует 6 урона, потребуется много времени. Если, на Ваш взгляд, это занимает слишком много времени, играйте с константами.

Гжегож Славецки
источник
Что означает «фактор атаки»?
Даниэль Каплан
0

Я считаю, что метод World of Warcraft - один из лучших. Базовые характеристики игроков оказывают слабое влияние на общий урон, причем большая часть модификатора урона зависит от бонусных характеристик на экипировке. Это значительно облегчает расширение игры и ее баланс со временем

ProtoJazz
источник