Jak zrobić coś, co częściej flashuję / mrugam, gdy zbliża się do znikania?


10

W mojej grze, kiedy zabijesz wroga, mogą upuścić coś takiego jak pakiet zdrowia lub złoto. Chcę, aby miało to limit czasowy, aby w końcu zniknęło, jeśli go nie odbierzesz. Chcę, aby przedmiot migał częściej, im bardziej kropla zbliża się do „śmierci”. Jak wykonujesz algorytm „częstszego flashowania”?

Odpowiedzi:


2

Moje obawy związane z jednym z obecnie oferowanych podejść polegają na tym, że oba doprowadzą do migania „zmiennej prędkości”, co może nie tylko rozpraszać graczy, ale także utrudniać dokładne określenie, jak długo obiekt pozostawił, zanim zniknie . Zamiast tego, gdzieś w swoich parametrach (czy to globalny mechanizm renderujący lub na zasadzie per-obiektu) Chciałbym mieć cztery stałe: slowBlinkTime, slowBlinkRate, fastBlinkTimei fastBlinkRate. Podczas renderowania, jeśli pozostały czas życia Twojego obiektu jest krótszy niż fastBlinkTime, mrugnij nim o fastBlinkRate; w przeciwnym razie, jeśli jest mniejszy slowBlinkTime, to mrugnij o slowBlinkRate. Jeśli chcesz pójść o krok dalej, możesz mieć szereg różnych blinkTimes iblinkRatei sprawdzaj je jeden po drugim, ale w praktyce może to być przesada, a wystarczą same ostrzeżenia i stany krytyczne. Kod wyglądałby mniej więcej tak:

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
}

Zauważ, że ten kod zakłada pół-włączony, pół-wyłączony cykl mrugania (to 0.5freprezentuje test), ale może być łatwo dostosowany do czegoś w rodzaju 2/3 włączenia, 1/3 wyłączenia tylko przez dostosowanie odpowiedniej stałej. To również nie robi nic, aby „zsynchronizować” miganie między szybkim i wolnym stanem, ale jest to stosunkowo proste do polerowania.

Powinno to być łatwe do podłączenia, a będzie miało znaczącą przewagę IMHO, że gracze będą mogli zobaczyć przejście z „wolnego” na „szybkie” mruganie i dokładnie wiedzieć, jak długo im pozostało. Chciałbym zacząć od wartości parametrów takich jak 5s dla slowBlinkTimei 0,5s dla slowBlinkRatei 2s / 0,25s dlafastBlinkTime i fastBlinkRate, ale to zdecydowanie zależy od konkretnej gry.


Nie rozumiem. Jeśli mruganie staje się coraz szybsze, czy nie byłby to lepszy wskaźnik do dokładnego czasu, jaki upłynął od obiektu, niż tylko 2 tryby?
— Daniel Kaplan

1
@tieTYT Problem polega na tym, że szczególnie gdy częstotliwość mrugania jest zmienna, użytkownikom trudno (a) dokładnie określić, jak szybko obiekt mruga, i (b) skorelować to z tym, jak długo musi on żyć. Wyobraź sobie, że masz suwak od 0 do 100 w porównaniu z „przełącznikiem” z pozycjami na 0, 50 i 100; ludzie mogą odgadnąć wartość suwaka z dokładnością do 5-10%, ale będą wiedzieli dokładnie, na jakiej wartości jest włączony przełącznik - i znacznie trudniej jest ocenić wskaźnik niż pozycję.
— Steven Stadnicki

Mimo sugestii głosów uważam, że to najlepsza odpowiedź. Ponadto jest znacznie łatwiejszy do wdrożenia (przynajmniej koncepcyjnie). Moja odpowiedź uzyskała więcej głosów, ale nadal nie jestem z niej zadowolona wizualnie. Twoje podejście da satysfakcjonujący wygląd.
— Daniel Kaplan

14

Jeśli t spadnie z T do 0, możesz użyć czegoś takiego jak sin ((T - t) ²), a następnie jeśli liczba wynosi> 0, narysuj obiekt, jeśli jest to <0, nie zrobisz tego


Wypróbowałem to sam i musiałem majstrować przy tym. Dla mnie T było 100. To równanie sprawiło, że wszystko mrugało bardzo szybko przez cały czas. Aby spowolnić, zmieniłem równanie na sin (((T - t) / 10) ²). Było to po majstrowaniu przy liczbach takich jak / 6 i / 7.

Próbowałem także: sin ((T - t) ² * 1/100)

A potem nie podobało mi się, że kropla wydawała się niewidoczna prawie tak bardzo, jak była widoczna. Chciałem, żeby rzadko był niewidoczny. Osiągnąłem to, robiąc to: sin ((T - t) ² * 1/100) + .5 To + .5 przesuwa sinusoidę „w górę” tak, że nie staje się ona tak często <0.

Nic z tego nie działało dokładnie tak, jak chciałem. Problem polega na tym, że mruganie zacznie się zbyt wcześnie. Chciałem, aby kropla była widoczna przez 3 sekundy, a następnie zaczęła mrugać. Aby to osiągnąć, zrobiłem coś takiego:

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

To xbyłyby 3 sekundy.

Warto również zauważyć, że jest to narzędzie, którego używałem przez cały czas, aby wizualizować, jak wyglądałoby mruganie. Myślę, że bez narzędzia wizualnego zajęłoby to 5 razy dłużej.


Wspaniale, uwielbiam to rozwiązanie, Kolejny szybki sposób to zrobićsin(t * pow((t/T), 1.5))
— Gustavo Maciel

4

Może przy pomocy innej zmiennej?

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

Jest to nieco dłużej niż rozwiązanie, które sam zaproponowałeś, ale oszczędzasz się na kosztach sini powoperacjach, i masz znacznie większą kontrolę nad tym, jak mruganie przebiega szybciej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.