Autor Wątek: Odliczanie czasu w grze  (Przeczytany 5192 razy)

Offline castro12321

  • Użytkownik

  • +2
# Październik 02, 2014, 17:52:26
Rzeczywiście w tym momencie doszliśmy do podobnego rozwiązania, w pierwszym poście bardziej chciałem pokazać jak używanie samego Timera może być zabójcze, szczególnie, gdy nie przygotujesz się na crashe/migracje. Nie pomyślałem też o offsetach.

A potem się rozchulała święta przepychanka "moje lepsiejsze" :D
@Edit: Gdzieś doczytałem stwierdzenie "Ile programistów, tam tyle+1 rozwiązań"
« Ostatnia zmiana: Październik 02, 2014, 17:55:27 wysłana przez castro12321 »

Offline Mr. Spam

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

Offline jdev

  • Użytkownik

# Październik 02, 2014, 22:03:22
Fajnie, że temat się rozkręcił i padło kilka pomysłów, na pewno z tego skorzystam kiedyś.

Podoba mi się pomysł castro z własnym czasem, gdzie co 1 sek tworzę 1 jednostkę swojego czasu. Według mnie gra przy crashach powinna pauzować, testowałem wiele gier i szczerze mówiąc nie pamiętam, w której byłoby inaczej. Nawet jeśli serwer jest offline parę minut to przez ten czas może się naprawdę wiele wydarzyć, weźmy np. grę Clash of Clans, która jest teraz na topie i wyobraźcie sobie sytuację gdzie trwa wojna, do końca zostało niewiele czasu, powiedzmy 1h, a wiadomo, że sporo graczy, szczególnie tych lepszych atakuje na końcu, serwer pada i po 2h się podnosi, a tam koniec wojny, niektórzy gracze nie zaatakowali bo nie zdążyli przez crash serwera i wojna jest przegrana. To byłoby bardzo niesprawiedliwe, a poza tym już były podobne sytuacje i wiem, że gra w tym czasie pauzuje.

Pomysł Xirdusa, czyli kolejka zdarzeń oraz offset czasu również jak najbardziej trafione i przydatne, ale dalej nie rozwiązaliśmy głównego problemu, czyli...
Ja bym po prostu pobierał aktualny czas systemowy funkcją time() lub analogiczną zależnie od języka, i sprawdzał czy pierwszy rekord w bazie ma czas mniejszy czy większy - jeśli mniejszy, wykonuję tą akcję i natychmiast pobieram następną, a jeśli większy, to usypiam wątek do czasu tego zdarzenia lub do czasu następnej zmiany w bazie danych.
Co znaczy, że usypiasz wątek do czasu tego zdarzenia? Kto będzie pilnował czy wątek powinien już się obudzić? Czyli tak czy inaczej musisz co sekundę sprawdzać czy już wykonać akcję czy jeszcze nie. Fakt, że w tym wypadku już nie obciążamy bazy (nie robimy zapytań co 1 sek) bo sprawdzanie odbędzie się wysokopoziomiowo czyli w samej aplikacji, ale dalej musimy odliczać np. timerem 1sek i sprawdzać kolejkę :)

EDIT:
Pomysł z kolejką ma oczywiście zastosowanie tylko wtedy kiedy będziemy mieć ją aktualną, czyli jak user kliknie na budowę koszar, to od razu musimy pobrać nową kolejkę do sprawdzania, inaczej możemy pominąć jego koniec budowy (gdy czas budowy jego koszar będzie mniejszy niż wartość pierwszego elementu z kolejki).
« Ostatnia zmiana: Październik 02, 2014, 22:12:07 wysłana przez jdev »

Offline Xirdus

  • Redaktor

# Październik 02, 2014, 23:05:32
Co znaczy, że usypiasz wątek do czasu tego zdarzenia? Kto będzie pilnował czy wątek powinien już się obudzić?
Wątek blokuje się na semaforze. Większość bibliotek do wielowątkowości ma semafory z funkcją czekania na sygnał tylko przez określony czas - po tym czasie wątek się wybudza niezależnie od tego czy ktoś podniósł semafor czy nie. A jeśli później okaże się, że trzeba go wybudzić wcześniej (np. drugi wątek, bo u mnie przyjmowaniem poleceń od graczy zajmuje się inny wątek niż ich wykonywaniem, dostanie jakąś nową komendę i doda do kolejki), to po prostu ten inny wątek podnosi semafor, i nasz wątek się wybudza.

Poczytaj o wątkach i metodach synchronizacji - wiedza o tym to must have w drugiej dekadzie dwudziestego pierwszego wieku.

Offline jdev

  • Użytkownik

# Październik 02, 2014, 23:30:06
Jeśli chodzi o wielowątkowość aplikacji to faktycznie niewiele z tym pracowałem, dzięki za wyjaśnienie, poczytam o tym.