¿Cómo hago algo que parpadeo / parpadeo con más frecuencia a medida que se acerca la desaparición?

10

En mi juego, cuando matas a un enemigo, pueden dejar caer algo como un paquete de salud u oro. Quiero que esto tenga un límite de tiempo para que eventualmente desaparezca si no lo recoges. Quiero que el elemento parpadee con más frecuencia cuanto más se acerque la gota a la "muerte". ¿Cómo se hace el algoritmo de "parpadeo más frecuente"?

Daniel Kaplan
fuente

Respuestas:

2

Mi preocupación con cualquiera de los enfoques que se ofrecen actualmente es que ambos conducirán a un parpadeo de 'velocidad variable', lo que no solo podría distraer a los jugadores sino que también dificultaría medir exactamente cuánto tiempo le queda a un objeto antes de que desaparezca . En su lugar, en algún lugar de sus parámetros (ya sea que ser global para el procesador o en una base por objeto) que tendría cuatro constantes: slowBlinkTime, slowBlinkRate, fastBlinkTimey fastBlinkRate. Al renderizar, si la vida restante de su objeto es inferior a fastBlinkTime, parpadee fastBlinkRate; de lo contrario, si es menor que slowBlinkTime, entonces parpadee slowBlinkRate. Si quisiera ir un paso más allá, podría tener una variedad de distintos blinkTimesyblinkRates y verifíquelos uno por uno, pero en la práctica es probable que sea excesivo y solo tener estados de 'advertencia' y 'críticos' debería ser suficiente. El código se vería así:

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
}

Tenga en cuenta que este código supone un ciclo de parpadeo medio encendido y medio apagado (eso es lo que 0.5frepresenta en la prueba), pero podría modificarse fácilmente por algo así como dos tercios encendido, un tercio apagado simplemente ajustando la constante apropiada. Esto tampoco hace nada para 'sincronizar' el parpadeo entre los estados rápido y lento, pero eso es relativamente sencillo de pulir.

Esto debería ser sencillo de enchufar, y tendrá la ventaja sustancial de IMHO de que los jugadores podrán ver el cambio de parpadeo 'lento' a 'rápido' y saber exactamente cuánto tiempo les queda. Comenzaría con valores de parámetros como 5s para slowBlinkTimey 0.5s para slowBlinkRatey 2s / 0.25s para fastBlinkTimey fastBlinkRate, pero eso definitivamente depende de tu juego en particular.

Steven Stadnicki
fuente
No entiendo. Si el parpadeo se vuelve más y más rápido, ¿no sería un mejor indicador de cuánto tiempo le queda exactamente al objeto que solo 2 modos?
Daniel Kaplan
1
@tieTYT El problema es que, especialmente cuando la tasa de parpadeo es variable, es difícil para los usuarios (a) determinar exactamente qué tan rápido parpadea un objeto, y (b) correlacionar eso con cuánto tiempo más tiene que vivir. Imagine tener un control deslizante de 0 a 100 frente a un 'interruptor' con posiciones en 0, 50 y 100; las personas pueden adivinar el valor del control deslizante dentro del 5-10%, pero sabrán exactamente en qué valor está activado el interruptor, y es mucho más difícil medir una tasa que una posición.
Steven Stadnicki
A pesar de lo que sugieren los votos, creo que esta es la mejor respuesta. Además, es mucho más fácil de implementar (al menos conceptualmente). Mi respuesta obtuvo más votos, pero todavía no estoy satisfecho visualmente. Su enfoque le dará una mirada satisfactoria.
Daniel Kaplan
14

Si t baja de T a 0, podría usar algo como sin ((T - t) ²), entonces si el número es> 0, dibuja el objeto, si es <0 no lo hace


Lo intenté yo mismo y tuve que jugar con eso. Para mí, T era 100. Esta ecuación hizo que las cosas parpadearan súper rápido todo el tiempo. Entonces, para reducir la velocidad, cambié la ecuación a sin (((T - t) / 10) ²). Esto fue después de jugar con los números como / 6 y / 7.

También probé esto: sin ((T - t) ² * 1/100)

Y luego no me gustó cómo la gota parecía ser invisible casi tanto como era visible. Quería que rara vez fuera invisible. Lo logré haciendo esto: sin ((T - t) ² * 1/100) + .5 Eso + .5 desplaza la "línea" senoidal para que no se vuelva <0 con tanta frecuencia.

Nada de esto funcionó exactamente como yo quería. El problema es que el parpadeo comenzaría demasiado pronto. Quería que la gota fuera visible durante 3 segundos y luego comenzara a parpadear. Para lograr eso, hice algo como esto:

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

Eso xserían los 3 segundos.

También vale la pena señalar que esta es la herramienta que utilicé todo el tiempo para visualizar cómo se vería el parpadeo. Creo que esto hubiera tardado 5 veces más sin la herramienta visual.

Daniel Kaplan
fuente
Impresionante, me encanta esta solución, otra forma rápida sería hacerlosin(t * pow((t/T), 1.5))
Gustavo Maciel
4

¿Quizás con la ayuda de otra variable?

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

Es un poco más largo que la solución que te propusiste, pero te ahorras costosas siny powoperaciones, y tienes mucho más control sobre cómo el parpadeo va más rápido.

Pijama Panda
fuente