2011-11-30 4 views
12

Próbuję znaleźć najlepszą metodę, aby to zrobić, biorąc pod uwagę turę cross-plateform na komórkę (szerokość pasma 3G) z pociskami i spadającymi blokami.Jak zsynchronizować fizykę w grze wieloosobowej?

Zastanawiam się, czy jedno urządzenie (obecny gracz = rola serwera) może uruchomić fizykę i wysłać dane "kluczowych klatek" (położenie, orientacja bloków) do drugiego urządzenia, które po prostu interpoluje od bieżącego stanu do otrzymane "klatki kluczowe". Dzięki tej metodzie obawiam się ogromnej ilości danych, które gwarantują ten sam obraz na urządzeniu innego gracza.

Inną metodą powinno być wysyłanie danych fizyki (siła, przyspieszenie ...) i uruchamianie fizyki również na drugim urządzeniu, ale obawiam się, że nigdy nie uzyskałem tego samego wyniku.

+0

Czy obiekty nie miałyby dokładnie tego samego wyniku na obu urządzeniach, jeśli obiekty mają tę samą pozycję początkową i te same dane fizykochemiczne? – Kjetil

+0

@Kjetil tylko, jeśli masz ustalony czas tykania. Zasadniczo nie będzie tak, jeśli zaktualizujesz fizykę każdej ramki graficznej. –

+0

Right Rob. Nie jestem pewien, ale powinny pojawić się problemy, biorąc pod uwagę wiele platform (różne architektury) i obliczenia zmiennoprzecinkowe, nie? –

Odpowiedz

9

Moja obecna implementacja działa tak:

  1. Server zarządza symulację fizyki
  2. W każdej poważnej kolizji dowolnego obiektu, bezwzględne położenie, obrót, i prędkość/przyspieszenie/siły na obiektu są wysyłane do każdego klienta .
  3. Klient ustawia każdy obiekt na pozycji wraz z ich prędkością i stosuje wymagane siły.
  4. Klient oblicza opóźnienia i przesuwa system fizyczny, aby uwzględnić czas opóźnienia o tę wartość.

To dla mnie działa całkiem dobrze. Mam system fizyczny działający na kilkudziesięciu podsystemach (mapach).

Niektóre z kluczowych rzeczy o moim realizacji:

całkowicie ignorować żadnego obiektu, który nie jest oznaczony jako „konieczne”. Na przykład cząsteczki brudu i pyłu, które reagują na ruch gracza lub trawę i wodę, gdy reagują na ruch gracza. Zasadniczo nieistotne rzeczy.

Wszystko to jest przesyłane przez UDP przy okazji. Byłoby przerażające na TCP.

6

Będziesz chciał wysłać absolutne pozycje i obroty.

Masz rację, jeśli wyślesz tylko siły, to nie zadziała. Można to zrobić, ale jest o wiele trudniejsze niż wysyłanie pozycji. Potrzebujesz obu urządzeń do wykonywania swoich obliczeń w ten sam sposób, dlatego przed każdą klatką musisz czekać na dane z drugiego urządzenia, musisz użyć tego samego kroku czasowego, skrypty muszą działać w tej samej kolejności lub być przemienne i można używać tylko instrukcji procesorów gwarantowanych, aby dać taki sam wynik na obu komputerach.

to ostatni, który sprawia, że ​​jest szczególnie problematyczny, ponieważ oznacza to, że nie można używać liczb zmiennoprzecinkowych (zmiennoprzecinkowych/pojedynczych lub podwójnych). musisz używać liczb całkowitych lub przetasować własny format liczb, aby nie korzystać z wielu istniejących narzędzi.

Wiele gier korzysta z modelu klient-serwer z prognozą po stronie klienta. jeśli twoja gra jest oparta na turach, możesz być w stanie uciec, nie używając przewidywania po stronie klienta. zamiast tego można opóźnić klienta o pewien czas, aby można było mieć pewność, że dane wejściowe serwera będą już dostępne podczas renderowania. przewidywanie po stronie klienta jest ważne tylko wtedy, gdy klient może wprowadzić zmiany, na których zależy serwer (np. przenoszenie).

+0

Czekając na wejście dla każdej ramki, rozumiem, że masz na myśli każdą ramkę fizyki? – RobotRock

+0

Mam na myśli każdą ramkę wejściową, która może być 1-do-1 z ramkami fizyki, lub nie. najłatwiej byłoby mieć ramki wejściowe i klatki fizyki od 1 do 1, ale można było zaktualizować fizykę dwukrotnie za każdym razem, gdy próbkowałeś wejście, jeśli chcesz. – notallama