Как сделать, чтобы что-то вспыхивало / мигало чаще, когда оно приближалось к исчезновению?

10

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

Даниэль Каплан
источник

Ответы:

2

Меня беспокоит любой из предлагаемых в настоящее время подходов: они оба приведут к миганию с переменной скоростью, что не только отвлекает игроков, но и затрудняет точную оценку того, как долго объект оставался до исчезновения. , Вместо этого, где - то в ваших параметрах (будь то глобальное для визуализатора или на основе каждого объекта) я бы четыре константы: slowBlinkTime, slowBlinkRate, fastBlinkTimeи fastBlinkRate. При рендеринге, если оставшаяся жизнь вашего объекта меньше, чем fastBlinkTime, мигайте fastBlinkRate; в противном случае, если оно меньше slowBlinkTime, тогда моргните slowBlinkRate. Если вы хотите , чтобы дальше идти на шаг , то вы могли бы иметь множество различных blinkTimeс и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в тесте), но его можно легко настроить, например, на две трети, на одну треть, просто изменив соответствующую константу. Это также ничего не делает для «синхронизации» мигания между быстрым и медленным состояниями, но это относительно просто для полировки.

Это должно быть просто для подключения, и это будет иметь ИМХО существенное преимущество в том, что игроки смогут увидеть переход от «медленного» к «быстрому» миганию и точно знать, сколько времени у них осталось. Я бы начал со значений параметров, таких как 5 с slowBlinkTimeи 0,5 с slowBlinkRate, и 2 с / 0,25 с fastBlinkTimeи fastBlinkRate, но это определенно зависит от вашей конкретной игры.

Стивен Стадницки
источник
Я не понимаю Если мигание становится все быстрее и быстрее, разве это не будет лучшим показателем того, как долго объект оставил, чем просто 2 режима?
Даниэль Каплан
1
@tieTYT Проблема заключается в том, что, особенно когда скорость мигания является переменной, пользователям трудно (а) точно определить, насколько быстро мигает объект, и (б) соотнести это с тем, как долго он должен жить. Представьте, что у вас есть ползунок от 0 до 100 против «переключателя» с позициями в 0, 50 и 100; люди могут догадаться о значении ползунка в пределах 5-10%, но они точно будут знать, на каком значении находится переключатель - и измерить скорость намного сложнее, чем позицию.
Стивен Стадницки,
Несмотря на то, что говорят голоса, я думаю, что это лучший ответ. Кроме того, его проще реализовать (по крайней мере, концептуально). Мой ответ получил больше голосов, но я все еще не удовлетворен визуально. Ваш подход даст удовлетворительный вид.
Даниэль Каплан
14

Если t уменьшается от T до 0, вы можете использовать что-то вроде sin ((T - t) ²), тогда, если число> 0, вы рисуете объект, если это <0, вы не делаете


Я сам попробовал это, и мне пришлось повозиться с этим. Для меня T было 100. Это уравнение заставляло вещи моргать очень быстро все время. Поэтому, чтобы замедлить его, я изменил уравнение на sin (((T - t) / 10) ²). Это было после возни с числами, такими как / 6 и / 7.

Я также попробовал это: грех ((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))
Gustavo Maciel
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операции, и вы гораздо больше контроля над тем, как мигание идет быстрее.

Панда Пижама
источник