Як зробити так, щоб я блискав / моргав частіше, коли він наближався до зникнення?


10

У моїй грі, коли ти вбиваєш ворога, вони можуть кинути щось на зразок пакета здоров'я чи золота. Я хочу, щоб це було обмеженням часу, щоб воно з часом зникло, якщо ви його не забрали. Я хочу, щоб предмет частіше спалахував, чим ближче крапля до «смерті». Як зробити алгоритм "частіше миготіння"?

Відповіді:


2

Мене турбує будь-який із запропонованих підходів, що вони зараз приводять до «блискучої» з мінливою швидкістю, що може не тільки відволікати гравців, але й складно оцінити, скільки часу залишилось об'єкта, перш ніж воно зникне . Замість цього, де - то в ваших параметрах (будь то глобальне для визуализатора або на основі кожного об'єкта) я б чотири константи: slowBlinkTime, slowBlinkRate, fastBlinkTimeі fastBlinkRate. Під час візуалізації, якщо залишилося життя вашого об'єкта менше fastBlinkTime, тоді мигніть його на fastBlinkRate; в іншому випадку, якщо вона менше slowBlinkTime, тоді митьте її на slowBlinkRate. Якщо ви хочете піти на крок далі, ви могли б мати масив різних blinkTimes іblinkRates та перевіряйте їх по черзі, але на практиці це, ймовірно, буде надмірним, а просто "попереджувальних" та "критичних" станів повинно бути достатньо. Код виглядатиме приблизно так:

float blinkCycle;
if ( entity.timeLeft < fastBlinkTime ) {
  blinkCycle = entity.timeLeft/fastBlinkRate;
} else if ( entity.timeLeft < slowBlinkTime ) {
  blinkCycle = entity.timeLeft/slowBlinkRate;
}
blinkCycle = blinkCycle - floor(blinkCycle); // find blinkCycle 'mod 1'
if ( (entity.timeLeft < slowBlinkTime) && (blinkCycle < 0.5f) ) {
  renderBlinked(entity); // this should be the 'blinked' state, whether flashed or missing
} else {
  renderNormal(entity); // the normal render for the entity
}

Зауважте, що цей код передбачає цикл миготіння на половину увімкнення (саме те, що 0.5fявляє собою тест), але його можна легко налаштувати на щось на зразок двох третин, третина відключивши, лише налаштувавши відповідну константу. Це також не робить нічого, щоб «синхронізувати» миготіння між швидкими та повільними станами, але це досить просто для полірування.

Це потрібно легко підключити, і це матиме істотну перевагу IMHO в тому, що гравці зможуть побачити перехід від «повільного» до «швидкого» блимання і точно знати, скільки часу їм залишилося. Я б почав зі значень параметрів, таких як 5s для slowBlinkTimeі 0,5s для slowBlinkRate, і 2s / 0,25s для fastBlinkTimeі fastBlinkRate, але це, безумовно, залежить від вашої гри.


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

1
@tieTYT Проблема полягає в тому, що, особливо коли швидкість моргання мінлива, користувачам важко (a) точно визначити, наскільки швидко блимає об'єкт, і (b) співвіднести це з тим, скільки часу він повинен жити. Уявіть, що у вас є повзунок від 0 до 100 проти перемикача з положеннями 0, 50 та 100; люди, можливо, зможуть здогадатися про значення слайдера в межах 5-10%, але вони точно знатимуть, на яке значення включений перемикач - і набагато складніше оцінити швидкість, ніж позиція.
Стівен Стадницький

Попри те, що пропонують голоси, я вважаю, що це найкраща відповідь. Крім того, це легше здійснити (принаймні концептуально). Моя відповідь отримала більше голосів, але я все ще не візуально цим задоволений. Ваш підхід додасть задовільний вигляд.
Даніель Каплан

14

Якщо t знижується з T до 0, ви можете використовувати щось на кшталт sin ((T - t) ²), то якщо число> 0, ви малюєте об'єкт, якщо це <0, ви не


Я сам спробував це, і мені довелося повозитися з цим. Для мене Т було 100. Це рівняння змусило речі весь час блимати надто швидко. Щоб уповільнити це, я змінив рівняння на sin (((T - t) / 10) ²). Це було після роздумування з цифрами типу / 6 та / 7.

Я також спробував це: sin ((T - t) ² * 1/100)

І тоді мені не сподобалося, як крапля здавалася невидимою майже настільки, наскільки це було видно. Я хотів, щоб воно рідко було непомітним. Я домігся цього, виконуючи це: sin ((T - t) ² * 1/100) + .5 Це + .5 зміщує синусову "лінію" вгору, щоб вона не ставала <0 так часто.

Нічого з цього не працювало точно так, як я хотів. Проблема полягає в тому, що моргання розпочнеться занадто рано. Я хотів, щоб крапля була видно протягом 3 секунд, а потім почала моргати. Для цього я зробив щось подібне:

isVisible(drop)
  if drop.t > x
    return true
  else
    sin((T - x - drop.t * 1/100) + .5 >= 0

Це xбули б 3 секунди.

Також варто зазначити, що це той інструмент, який я весь час використовував, щоб візуалізувати, як виглядатиме мерехтіння. Я думаю, що без наочного інструменту це займе 5 разів більше.


Дивовижний, я люблю це рішення, Інший швидкий спосіб буде робитиsin(t * pow((t/T), 1.5))
Густаво Антунеш

4

Може, за допомогою іншої змінної?

current_length = 4
length_decrease = 0.5
current_time = current_length

function update(delta_time)
    if current_time > 0 then
        draw()
    end
    current_time -= delta_time
    if current_time < -current_length then
        current_length -= length_decrease -- feel free to get creative here
        if current_length < 0 then
            disable_object()
        end
        current_time += current_length * 2
    end
end

Це трохи довше рішення, яке ви запропонували самі, але ви економите собі кошти sinта powоперації, і у вас є набагато більший контроль над тим, як миготіння проходить швидше.

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