Як я можу масштабувати кількість та виклик ворогів на хвилі атаки в міру просування гри?


9

Я зараз роблю захисну гру, де вороги будуть нереститися і атакувати армію гравця. Це схоже на гру Tower Defense, за винятком лише одного рівня. Вороги продовжуватимуть нересту, поки зрештою користувач не загине, або він накопичить достатньо велику армію, щоб вони знищили будь-якого ворога, який нереститься миттєво (сподіваємось, це буде досить складно, щоб цього не сталося).

З чим я зараз боюся, як зробити цю гру прогресивнішою, і ймовірність появи нересту в основному зрештою сягне 100%.

Поки що у мене є щось подібне до наступного

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

Але це здається занадто рівномірним для початку. На даний момент я породжую лише одного типу ворога, ідея полягає в тому, що породжуються більш жорсткі вороги з часом.

Я також думаю, що мені потрібно рандомізувати свою роботу spawnTimerтрохи більше і зробити це швидше з часом, але я просто не бачу, щоб зрозуміти, як має виглядати моя логіка в цілому цьому розділі. Хтось може допомогти з грубою ідеєю такого роду формули?

Зараз я використовую JavaScript для написання гри, але очевидно, що мова йде більше про концепцію.


Що минув час? Це те, що пройшло дотепер? Як часто ви називаєте цей стан?
AturSams

Привіт, так, вибачте, минув час - час, що минув з моменту початку гри, і це називається в моєму циклі оновлення () ігор, який базується на 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);

6

Варіантів, два з вашою поточною установкою:

  • Робіть ворогів важче
  • Народжують більше ворогів (частіше або декількох одночасно)

Потім більше з додатковими функціями:

  • Вороги починають наносити різні види ушкоджень, і гравець повинен по-різному захищатися проти кожного. Наприклад, дальні напади, магія тощо.
  • Вороги починають захищатися від різного типу пошкоджень. Гравець повинен створити кілька типів пристроїв, що завдають шкоду, щоб протистояти. Наприклад, гравець починається зі стрілецьких та гарматних атак. Ворог, який має дуже високу стійкість до стріл, нереститься, тому гравець повинен переконатися, що вони збалансували свої атаки.

Щодо складання кривої складності, насправді правильної відповіді немає. Для того, щоб виправитись, знадобиться багато ігор і налаштувань. Це залежатиме від того, як довго гра повинна тривати і наскільки складно ви хочете. Я пропоную вам скористатися Excel або таким сайтом, як WolframAlpha, і подивитися, яку криву створюють різні функції. Спробуйте експоненціальні збільшення, лінійні збільшення тощо. Знайдіть те, що працює для вас.


Дякую за ідеї, але я думаю, що обрана відповідь - це більше те, що мені потрібно. Але ти напевно дав мені більше їжі для роздумів, і я підтримав твою відповідь
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);
        }
    }
}

1
Це стимулює, але його слід оптимізувати перед його використанням. Наприклад, ви можете використовувати Math.random () один раз, щоб визначити, скільки ворогів нерестувати. Якщо ви хочете залишити менший шанс для великої кількості ворогів, ви могли б реалізувати "Звичайний розподіл" більш ефективно. stackoverflow.com/questions/2325472 / ...
AturSams
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.