Architektura gry multiplayer

0

Próbuję stworzyć prostą grę multiplayer, niech to będzie nawet kółko i krzyżyk, czy cokolwiek innego. Zakładam na początek, że będzie to tylko rozgrywka między dwoma komputerami, żeby uprościć sprawę.
O ile łatwo jest napisać jakąś aplikację, gdzie komunikacja klient-serwer odbywa się w formie tekstowej (np czat, gdzie można sobie w pętli wrzucić po prostu warunek odczytujący dane od użytkownika), tak nie mogę sobie wyobrazić architektury dla takiej prostej gry.
Powiedzmy, że mam klasy:
LogikaGry
PanelGry extends JPanel implements MouseListener
JFrame z PanelemGry

No i niech to na razie będzie to kółko i krzyżyk (no i swing). W PaneluGry mam 9 pól po kliknięciu na któreś wywołuję mousePressed, tam odpowiednio modyfikuję obiekt LogikaGry.

Jak rozumiem wypadałoby zrobić dodatkowo dwie klasy np:
Server
Client
które zawierają odpowiednio ServerSocket oraz Socket służące do komunikacji (jeden z klientów ma możliwość założenia gry).

Zasadnicze pytanie: gdzie i w jaki sposób odbierać/wysyłać dane generowane przez użytkownika? Chyba bez sensu byłoby otwieranie nowego połączenia do serwera za każdym razem, gdy drugi użytkownik wygenerował jakieś zdarzenie?

Za wszelkie sugestie z góry dzięki.

0

Zainteresuj się RMI, być może da się zastosować.

0

Połączenie można utrzymywać cały czas i w momencie zdarzenia wysłać info do drugiego kompa. W drugim w przypadku odebrania konkretnego komunikatu wykonać jakieś akcje i tak w kółko.

Ale tak jak wspomniał do zabawy w kółko i krzyżyk RMI się sprawdzi.

0

Dzięki za odpowiedzi. Jednak udało się zrobić tradycyjnie na socketach, ale RMI na tyle mnie zaciekawiło, że dostarczy mi rozrywki na kilka najbliższych dni.

0

sory za post pod postem, ale chcę podbić z jeszcze jednym pytaniem.
Jest jakiś wzorzec projektowy, który rozwiązuje problem komunikacji dwukierunkowej między dwoma obiektami? W grze muszę mieć zarówno możliwość wysyłania zdarzeń z paneli do socketa i z socketa do paneli. Naiwnym i moim zdaniem brzydkim rozwiązaniem jest:
Stworzenie panelu i w konstruktorze przekazanie obiektu z socketem.
W obiekcie z socketem ustawienie panelu w metodzie typu setPanel().

Kilka razy już się spotkałem z tym problemem, podobna sytuacja występuje, gdy chcę, aby komunikowały się między sobą np dwa panele (jakiś z kontrolkami i drugi z rysowaniem i interakcją użytkownika).
Używanie rozwiązania podanego powyżej wydaje mi się niechlujne, da się to zrobić "ładniej"?

0

GUI musi być zmieniane w EDT: http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html
Dlatego nie możesz ot tak zmieniać sobie GUI kiedy chcesz, bo może wyjść kiszka.

Twoim problemem jest przekazanie referencji do siebie parze obiektów nawzajem? Najprościej przekazać w konstruktorze jednego obiektu, a potem ustawienie setterem w drugim. Bardziej eleganckim i skalowalnym rozwiązaniem jest skorzystanie ze wstrzykiwania zależności: http://code.google.com/p/google-guice/

Zamiast korzystać z RMI możesz korzystać z mechanizmu Aktorów: http://akka.io/ (to te same z których zaleca się korzystać w Scali). Rozwiązanie bardziej kompletne i elastyczne niż RMI.

Poza tym nie umieszczaj dużo logiki w JPanelu (tzn twojej podklasie). JPanel ma służyć do wyświetlania danych, trochę konfiguracji, delegowanie zdarzeń etc Odbieranie zdalnych zdarzeń niech odbywa się w osobnym wątku (osobny wątek dlatego, że Swing nie jest wielowątkowy), a potem ten wątek może ustawiać zadania modyfikacji GUI w kolejce EDT za pomocą invokeLater/ invokeAndWait.

0

Logika jest całkowicie oddzielona w obiekcie klasy LogikaGry, w paintComponencie Panelu pobieram jedynie referencję do tablicy z kółkami i krzyżykami. JPanel implementuje Runnable i wszelkie zmiany są wywoływane właśnie przy pomocy SwingUtilities tak jak wspomniałeś.
Rozwiązanie z setterem właśnie wydawało mi się zawsze brzydkie, za pozostałe informacje dzięki, poczytam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1