Як створити частинки, які реагують на гравця та ворогів?


38

В даний час я роблю гру зі своїм власним ігровим механізмом, про який я писав на C ++ і використовую найсвіжіший SDD directx.

Гра - це космічний шутер зверху вниз (з досить цікавим поворотом), і я хочу отримати такий собі ефект туманності, який пролетить гравець. Мені дуже хочеться спробувати відчути приємне тактильне відчуття сотень частинок, що рухаються з шляху корабля гравця, коли він влітає в них. Дещо схоже на те, як частинки рухаються гравцем у Geomtry Wars на XBLA.

Я досвідчений програміст, коли мова йде про C ++. Однак я не знаю, як почати реалізовувати цей ефект. У когось є якісь круті ідеї чи вибір дизайну, які я, можливо, захочу розглянути? Не соромтеся відповідати на будь-яку ступінь глибини, яку ви хочете.

Відповіді:


65

Це класна ідея. Вам знадобиться якийсь градієнт дифузії навколо вашого корабля. Є три фізичні моделі, про які я можу подумати:

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

  2. Якщо ви хочете, щоб вони віддалилися від корабля і продовжували рух, коли вони переїхали. Це подібно до стандартної фізики в загально порожньому просторі, де немає (або дуже малих) градієнтів тиску.

  3. Ви хочете швидко відсунути частинки від корабля, як це наближається, як у пунктах (1) та (2), але як тільки корабель піде, частинки будуть повільно врівноважувати себе, щоб бути рівновіддаленими від вас.

Спільне для всіх трьох рішень : потрібно мати дифузійне поле, яке рухається разом з вашим кораблем. У цьому прикладі ми зробимо це круговим. Потім ви виявляєте вектор, називаєте його v1 між судном і кожною частинкою в цьому регіоні. Просуньте свою частинку вздовж цього вектора. Наскільки сильно ви його відштовхнете, буде залежати від відстані від корабля: використання 1 - v1.magnitude. Ця формула надасть вам лінійну силу, однак ви можете змінити її, щоб використовувати щось інше, наприклад, крива сили кругової сили, що зменшує силу до країв. Це дало б більше вигляду, ніби навколо корабля є сферичний, а не круговий градієнт тиску.

Для рішення 1 : Все, що ви зараз робите, - це змінити візуалізацію цієї частинки (тобто положення спрайта) для кожного оновлення візуалізації , за допомогою цього вектора. Оскільки ви робите це таким чином, це суто ефект відтворення і не впливає на фактичне світове становище частинки. Таким чином, ви додаєте світову позицію до зміщення візуалізації (v1), і тепер у вас є добре зміщені частинки, коли ви проходите повз до них або біля них, і плавно повертаєте частинки, проходячи повз (позаду вас).

Для рішення 2 : Замість того, щоб просто застосувати v1 до позиції перегляду, застосуйте його до кожного логічного оновлення до позиції частинки. Так, p1.position += v1. Таким чином, ви прикладаєте прискорюючу силу до частинки, яка перекладається на швидкість. Ймовірно, ви хочете, щоб швидкість кожної частинки була зменшена, так що вони поступово сповільнюватимуться і зупиняться, як тільки ви пройдете. Ви можете бачити, як це рішення призведе до згущення частинок у вашій туманності, оскільки вони ніколи не повторно розповсюджуються. Впевнений, не дуже реально, оскільки туманності мають градієнти тиску всередині них, якими б слабкими не були насправді.

Для рішення 3: Те саме, що (2), але в цьому випадку вам доведеться повторно розповсюджувати частинки. Зробити це легко - це жорстокий підхід, але оскільки це лише частинки і, таким чином, цукерки для очей, вам, ймовірно, не потрібно охоплювати величезну область, що цікавить (ймовірно, лише радіус гравцяPosition + maxPlayerSpeedPerTick, або будь-що інше прямокутна площа оточує це для логічних цілей). Кожна частинка буде застосовувати силу на одну іншу частинку в межах інтересу. Вони знову застосовуватимуть сили, засновані на відстані одна від одної. Обчисліть всі сили між частинками в одному зачистці по всій цікавій області, а потім застосуйте всі сили в одному зачистці. Нарешті, переконайтесь, що ви виконуєте цю обробку сили між частинками лише на частинках, що мають нульову швидкість. І як тільки будь-яка частинка досягне деякої мінімальної швидкості,

Існують всілякі формули дифузії тощо. Але я думаю, що в цьому випадку найкраще вирішення працює найкраще.


Мате, на жаль, на даний момент у мене немає репутації, щоб підтвердити вашу відповідь (і я зможу це зробити лише один раз, що менше, ніж заслуговує). Ви абсолютно прибили те, що я шукаю у своєму першому рішенні. Фантастична відповідь. Чесно. Спасибі!
Метт Макдональд

Тотальне задоволення, Метт, це гарне питання і варто розгинати мозок!
Інженер

Я також вирішив, що при дуже невеликій зміні коду я міг би застосувати це до менших астероїдів в поясі. Знову дякую.
Метт Макдональд
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.