Comment puis-je faire clignoter / clignoter plus fréquemment un élément qui se rapproche de la disparition?
10
Dans mon jeu, lorsque vous tuez un ennemi, il peut laisser tomber quelque chose comme un pack de santé ou de l'or. Je veux que cela ait un délai afin qu'il finisse par disparaître si vous ne le prenez pas. Je souhaite que l'élément clignote plus fréquemment à mesure que la goutte se rapproche de la "mort". Comment faites-vous l'algorithme "clignotant plus fréquemment"?
Ma préoccupation avec l'une ou l'autre des approches actuellement proposées est qu'elles conduiront toutes deux à un clignotement à vitesse variable, ce qui pourrait non seulement distraire les joueurs, mais aussi rendre difficile la mesure exacte du temps qu'il reste à un objet avant qu'il ne disparaisse. . Au lieu de cela, quelque part dans vos paramètres (que ce soit mondial pour l'équarrissage ou sur une base par objet) j'aurais quatre constantes: slowBlinkTime, slowBlinkRate, fastBlinkTimeet fastBlinkRate. Lors du rendu, si la durée de vie restante de votre objet est inférieure à fastBlinkTime, faites-le clignoter fastBlinkRate; sinon, si c'est moins que slowBlinkTime, alors clignote slowBlinkRate. Si vous vouliez aller plus loin, vous pourriez avoir un tableau de blinkTimes etblinkRates et vérifiez-les un par un, mais dans la pratique, cela risque d'être excessif et le simple fait d'avoir des états «d'avertissement» et «critiques» devrait suffire. Le code ressemblerait à ceci:
float blinkCycle;if( entity.timeLeft < fastBlinkTime ){
blinkCycle = entity.timeLeft/fastBlinkRate;}elseif( 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}
Notez que ce code présume un cycle de clignotement à moitié allumé et à moitié éteint (c'est ce que 0.5freprésente le test), mais pourrait facilement être modifié pour quelque chose comme les deux tiers, un tiers désactivé juste en ajustant la constante appropriée. Cela ne fait rien non plus pour «synchroniser» le clignotement entre les états rapide et lent, mais c'est relativement simple à polir.
Cela devrait être simple à brancher, et cela aura l'avantage substantiel à mon humble avis que les joueurs pourront voir le passage du clignotement «lent» au «rapide» et savoir exactement combien de temps il leur reste. Je commencerais par des valeurs de paramètres comme 5 s pour slowBlinkTimeet 0,5 s pour slowBlinkRateet 2 s / 0,25 s pour fastBlinkTimeet fastBlinkRate, mais cela dépend certainement de votre jeu particulier.
Je ne comprends pas. Si le clignotement devient de plus en plus rapide, ne serait-ce pas une meilleure indication de combien de temps il reste à l'objet que 2 modes?
Daniel Kaplan
1
@tieTYT Le problème est que, en particulier lorsque le taux de clignotement est variable, il est difficile pour les utilisateurs de (a) déterminer exactement à quelle vitesse un objet clignote, et (b) corréler cela avec combien de temps il doit vivre. Imaginez avoir un curseur de 0 à 100 par rapport à un «interrupteur» avec des positions à 0, 50 et 100; les gens peuvent deviner la valeur du curseur entre 5 et 10%, mais ils sauront exactement quelle valeur le commutateur est activé - et il est beaucoup plus difficile d'évaluer un taux qu'une position.
Steven Stadnicki
Malgré ce que les votes suggèrent, je pense que c'est la meilleure réponse. De plus, c'est beaucoup plus facile à implémenter (au moins conceptuellement). Ma réponse a obtenu plus de votes, mais je n'en suis toujours pas satisfait visuellement. Votre approche donnera un aspect satisfaisant.
Daniel Kaplan
14
Si t descend de T à 0, vous pourriez utiliser quelque chose comme sin ((T - t) ²) alors si le nombre est> 0 vous dessinez l'objet, si c'est <0 vous ne le faites pas
Je l'ai essayé moi-même et j'ai dû le bricoler. Pour moi, T était 100. Cette équation a fait clignoter les choses très rapidement tout le temps. Donc, pour le ralentir, j'ai changé l'équation en sin (((T - t) / 10) ²). C'était après avoir bricolé les chiffres comme / 6 et / 7.
J'ai aussi essayé ceci: sin ((T - t) ² * 1/100)
Et puis je n'ai pas aimé la façon dont la goutte semblait être invisible presque autant qu'elle était visible. Je voulais que ce soit rarement invisible. J'ai accompli cela en faisant ceci: sin ((T - t) ² * 1/100) + .5 Ce + .5 décale le "sinus" sinusoïdal de sorte qu'il ne devienne pas <0 aussi souvent.
Rien de tout cela ne fonctionnait exactement comme je le voulais. Le problème est que le clignotement commencerait trop tôt. Je voulais que la goutte soit visible pendant 3 secondes, puis commencer à clignoter. Pour ce faire, j'ai fait quelque chose comme ceci:
isVisible(drop)if drop.t > x
returntrueelse
sin((T - x - drop.t)²*1/100)+.5>=0
Ce xserait les 3 secondes.
Il convient également de noter que c'est l'outil que j'ai utilisé tout le temps pour visualiser à quoi ressemblerait le clignotement. Je pense que cela aurait pris 5 fois plus de temps sans l'outil visuel.
Génial, j'adore cette solution, une autre façon rapide serait de le fairesin(t * pow((t/T), 1.5))
Gustavo Maciel
4
Peut-être avec l'aide d'une autre variable?
current_length =4
length_decrease =0.5
current_time = current_length
function update(delta_time)if current_time >0then
draw()end
current_time -= delta_time
if current_time <-current_length then
current_length -= length_decrease -- feel free to get creative hereif current_length <0then
disable_object()end
current_time += current_length *2endend
Elle est un peu plus longue que la solution que vous avez proposée vous-même, mais vous vous épargnez des coûts sinet des powopérations, et vous avez beaucoup plus de contrôle sur la façon dont le clignotement va plus vite.
Si t descend de T à 0, vous pourriez utiliser quelque chose comme sin ((T - t) ²) alors si le nombre est> 0 vous dessinez l'objet, si c'est <0 vous ne le faites pas
Je l'ai essayé moi-même et j'ai dû le bricoler. Pour moi, T était 100. Cette équation a fait clignoter les choses très rapidement tout le temps. Donc, pour le ralentir, j'ai changé l'équation en sin (((T - t) / 10) ²). C'était après avoir bricolé les chiffres comme / 6 et / 7.
J'ai aussi essayé ceci: sin ((T - t) ² * 1/100)
Et puis je n'ai pas aimé la façon dont la goutte semblait être invisible presque autant qu'elle était visible. Je voulais que ce soit rarement invisible. J'ai accompli cela en faisant ceci: sin ((T - t) ² * 1/100) + .5 Ce + .5 décale le "sinus" sinusoïdal de sorte qu'il ne devienne pas <0 aussi souvent.
Rien de tout cela ne fonctionnait exactement comme je le voulais. Le problème est que le clignotement commencerait trop tôt. Je voulais que la goutte soit visible pendant 3 secondes, puis commencer à clignoter. Pour ce faire, j'ai fait quelque chose comme ceci:
Ce
x
serait les 3 secondes.Il convient également de noter que c'est l'outil que j'ai utilisé tout le temps pour visualiser à quoi ressemblerait le clignotement. Je pense que cela aurait pris 5 fois plus de temps sans l'outil visuel.
la source
sin(t * pow((t/T), 1.5))
Peut-être avec l'aide d'une autre variable?
Elle est un peu plus longue que la solution que vous avez proposée vous-même, mais vous vous épargnez des coûts
sin
et despow
opérations, et vous avez beaucoup plus de contrôle sur la façon dont le clignotement va plus vite.la source