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

9

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

В настоящее время я борюсь с тем, чтобы сделать эту игру все сложнее, и вероятность появления врага в конечном итоге достигнет 100%.

Пока что у меня есть что-то похожее на следующее

if(Math.random() < 1 - (1/elapsed_time) && spawnTimer <= 0 ){
    spawnEnemy()
    spawnTimer = rand(); // random number between 1 and 3
}

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

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

В настоящее время я использую javascript для написания игры, но, очевидно, это больше о концепции.

TommyBs
источник
Сколько времени прошло? Это то, что прошло до сих пор? Как часто вы называете это состояние?
AturSams
Привет, да, извините, прошедшее время прошло с момента запуска игры, и это называется в моем цикле update () игр, основанном на window.requestAnimationFrame
TommyBs

Ответы:

3

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

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

Позвольте rateбыть количество монстров, которые вы хотите прийти в каждую минуту (или раунд).

Позвольте GROWTH_RATEбыть скорость, с которой увеличивается трудность (пока это будет 0.2).

Допустим, вы начали с rate = 10. Теперь игрок убивает 5монстров, так что вы можете увеличить скорость GROWTH_RATE * 5 = 1.0и новые rate = 11.

Как реализовать условие, которое будет генерировать rateмонстров каждую минуту:

Установить икру таймер число от 0.5до 1.0 multiplied by 60 seconds orкруглого времени and divided byскорость . Also leave a0.25` случайно не монстр порождена , когда таймер достигает 0 и время рандомизированы снова.

Если rateкогда-либо достигнет, threshвам нужно замедлить. Теперь вместо того, чтобы увеличивать rateпутем GROWTH_RATE, вы можете увеличить его 1 / math.sqrt(rate). Таким образом, игрок не будет мгновенно уничтожен в более сложной обстановке.

Вы можете сбросить threshдо 80% от того, rateв котором игрок проиграл игру.

Если вы хотите рандомизировать силу монстра, будьте осторожны с таймером. Например, если вы решили , что player-score(определяются монстрами , убитыми до сих пор) , будет использоваться для определения максимальной силы монстра , который может породить, вы можете сделать что - то вроде этого: max-monster-strength = player-score / 1000. Затем рандомизации floatили doubleмежду 0.0к 1.0и умножьте результат сам по себе.

float monster_power = Math.random();
monster_power *= monster_power; // Multiply result by itself
    // Makes hard monsters less frequent than weak ones
monster_power *= max_monster_strength;

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

spawn_timer *= math.sqrt(monster_power);
AturSams
источник
6

Есть много вариантов, два с вашей текущей настройкой:

  • Сделать врагов сложнее
  • Вызывать больше врагов (чаще или несколько одновременно)

Тогда еще с дополнительными функциями:

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

Что касается построения кривой сложности, там действительно нет правильного ответа. Это займет много тестов игры и настройки, чтобы сделать это правильно. Это будет зависеть от того, как долго должна длиться игра и насколько трудно вы хотите, чтобы она была. Я предлагаю вам использовать Excel или такой сайт, как WolframAlpha, и посмотреть, какую кривую создают различные функции. Попробуйте экспоненциальное увеличение, линейное увеличение и т. Д. Найдите тот, который работает для вас.

MichaelHouse
источник
Спасибо за идеи, но я думаю, что выбранный ответ больше, чем мне нужно. Но вы определенно дали мне больше пищи для размышлений, и я проголосовал за ваш ответ
TommyBs
2

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

static const double SPAWN_CHANCE_ON_DIFFICULTY_1 = 0.01;

for (int i = 0; i < currentDifficulty; i++) {
   if(Math.random() < SPAWN_CHANCE_ON_DIFFICULTY_1 ){
       spawnEnemy()
   }
}

На уровне сложности 1 с вероятностью 1% появляется один враг за такт.

На уровне сложности 1000 будет появляться до 1000 врагов, каждый с отдельным шансом 1%. Это означает, что в среднем 10 будет появляться за тик, но это также может быть больше или меньше. Существует вероятность того, что число, очень отличающееся от 10, появится сразу, может быть, даже все 1000. Но это очень маловероятное событие из-за того, как работает вероятность (сравните: Закон больших чисел ).

Когда вы добавляете больше разных врагов с различным поведением и характеристиками, вы, возможно, захотите, чтобы некоторые из более сильных врагов начинали появляться только на более высоких сложностях и даже тогда с низкой плотностью. Для этого вы можете добавить модификатор сложности, который вычитается из текущей сложности. Таким образом, враг не будет появляться до того, как будет достигнут этот уровень сложности, и даже тогда только с меньшей вероятностью:

for (EnemyType enemyType: allEnemyTypes) {
    for (int i = 0; i < currentDifficulty - enemyType.getDifficulty(); i++) {
        if(Math.random() < enemyType.spawnChance() ){
            spawnEnemy(enemyType);
        }
    }
}
Philipp
источник
1
Это стимулирует, но должно быть оптимизировано перед использованием. Например, вы можете использовать Math.random () один раз, чтобы решить, сколько врагов появиться. Если вы хотите оставить меньше шансов для большого количества противников, вы можете реализовать «Нормальное распределение» более эффективно. stackoverflow.com/questions/2325472/…
AturSams