Autor Wątek: Przekazywanie zmiennej globalnej do funkcji  (Przeczytany 3850 razy)

Offline MDW

  • Użytkownik
    • www.encore-games.com

# Sierpień 11, 2016, 19:17:53
Ja autorytetem na pewno nie jestem i na pewno należę do mniej rozgarniętych osób na tym forum. Jednak dziubię w tych tematach już baaardzo długo (pierwszy znak w Atari Basic postawiłem w 1990 roku i od razu była to "gra"). Raczej niewiele korzystam z cudzych rozwiązań, doświadczeń i zupełnie nie mógłbym się zmusić do używania gotowych silników. Do do prawie wszystkiego dochodzę sam (dlatego mam takie mizerne efekty).

Piszę ten przydługawy wstęp po to żeby napisać, że po tych wszystkich latach i tysiącach błędnych rozwiązań doszedłem do dokładnie takiego samego wniosku. Też nie wyobrażam sobie używania czegoś innego niż delty czasu jaki minął od ostatniego przebiegu. Gdzieś tam w głównej pętli jest obliczana deltaTime i potem jest ona przekazywana obiektowi gry, a ten przekazuje wszystkim obiektom, które tego potrzebują. Żadnego "podbierania" sobie aktualnego czasu przez jakieś zmienne globalne, statyczne czy singletony nie wchodzi w grę. Zresztą nawet nie jest to potrzebne.

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline koirat

  • Użytkownik

# Sierpień 12, 2016, 00:57:12
Zaznaczam, że wszędzie, gdzie napisałem "prawie zawsze", świerzbiło mnie, żeby napisać "zawsze", bo nie potrafię wyobrazić sobie sensownej sytuacji, kiedy zachodziła by inna sytuacja, jakkolwiek dopuszczam taką możliwość - jeśli bym jednak na taką sytuację trafił, co najmniej kilkakrotnie zastanowiłbym się, czy nie mam gdzieś  błędu w logice/architekturze aplikacji.
Jednak przydaje się czasem też coś innego niż delta.
Np gdy chcemy mieć dokładny pomiar czasu od pewnego momentu. Jeśli będziemy sumować te delty to czas może być obarczony sporym błędem.

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

  • +2
# Sierpień 12, 2016, 01:03:14
Ja w swoim obecnym kodzie mam te zmienne dotyczące aktualnego czasu - CurrTime, DeltaTime itp. - zamknięte w strukturę i tę strukturę przekazuję z funkcji do funkcji. Wcześniej miałem ją dostępną globalnie jako g_App->GetTime(), ale stwierdziłem, że tak jest bardziej elegancko, z następującego powodu:

Kiedy struktura jest dostępna globalnie, to jest dostępna zawsze, a w moim programie nie zawsze jest poprawna. Pobieranie bieżącego czasu ma sens w funkcji Update, Draw/Render, OnKeyDown, OnMouseClick i innych takich, ale już nie np. podczas inicjalizacji czy zamykania programu, kiedy symulacja świata gry jeszcze/już nie jest uruchomiona.

Poza tym, tak jak napisaliście wyżej, dzięki przekazywaniu tych danych można je po drodze modyfikować. U mnie akurat one nie są modyfikowane w taki dosłowny sposób przed przekazaniem do obiektu potomnego, ale mogę mieć na raz w pamięci kilka równocześnie symulowanych scen i każda scena dostaje czas od chwili wystartowania danej sceny, a nie całej aplikacji (co jest z kolei fajne z dwóch powodów: 1. mamy dostęp do czasu od uruchomienia sceny, 2. dla mniejszych wartości tracimy mniej precyzji).

Ale udostępnienie tych danych jako zmienne globalne moim zdaniem też jest OK...

Offline hashedone

  • Użytkownik

# Sierpień 12, 2016, 21:46:21
@koirat - liczenie różnicy czasu przez sumowanie delt jest zawsze złym rozwiązaniem - jeśli potrzebujemy takiej funkcjonalności to wtedy faktycznie może mieć sens przekazywania dodatkowo aktualnego czasu, ale być może lepiej po prostu pracować na fixed step loop. Natomiast nie wiem po co ktoś miałby przekazywać poprzedni czas.

@ Reg - udostępnianie ich jako zmienne globalnie NIE jest ok właśnie z powodu, jaki podałeś - w szczególności "a w moim programie nie zawsze jest poprawna". I innych powodów opisanych w artykule podlinkowanym przez Xiona. Na tych problemach ze zmiennymi globalnymi przejedzie się prędzej czy później każdy.

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Sierpień 15, 2016, 23:38:38
OK, masz rację, ale nie zawsze wszystko musi być w kodzie idealne. Czas nie powinien być dostępną wszędzie zmienną globalną, tak samo jak czas bezwzględny od startu gry nie powinien być typu float, bo po kilku godzinach traci precyzję, a Unity robi jedno i drugie i jakoś z powodzeniem na tym silniku powstaje cała masa (większość?) gier :)

Offline koirat

  • Użytkownik

# Sierpień 16, 2016, 00:01:34
@koirat - liczenie różnicy czasu przez sumowanie delt jest zawsze złym rozwiązaniem - jeśli potrzebujemy takiej funkcjonalności to wtedy faktycznie może mieć sens przekazywania dodatkowo aktualnego czasu, ale być może lepiej po prostu pracować na fixed step loop. Natomiast nie wiem po co ktoś miałby przekazywać poprzedni czas.
Poza fixed step loop zazwyczaj używamy również variable step loop.
Ja jestem za przekazywaniem poprzez argument, ale gdzieś musimy również przechowywać te inne dane. Pytanie czy jest efektywnym również przekazywanie ich przez argument jeśli będziemy używać ich raczej sporadycznie.

Możesz sprecyzować o co chodzi z tym poprzednim czasem ?