Przykład: gra multiplayer w SFML

W tym przykładzie zajmiemy się zrobieniem prostej gry sieciowej dla 2 osób. Naszą grą będzie znana wszystkim gra „Kółko i krzyżyk”, także pod nazwą „Tic Tac Toe”. Ten przykład jest robiony częściowo „na żywo” tzn. kod jest pisany równolegle z pisaniem artykułu, jeżeli chcielibyście zobaczyć lekcje w stylu kursu Unity na YT to napiszcie o tym w komentarzach.

Na początku oczywiście przygotowujemy sobie projekt pod SFML, ja zlinkowałem swój statycznie. Jeżeli nie wiesz w jaki sposób należy przygotować swoje IDE do pracy z SFML zapraszam do podstawowego kursu SFML do działu Zaczynamy (instalacja SFML).

Ten przykład będzie raczej dosyć mocno przeze mnie opisany więc się nie zraź ewentualną jego długością bo w dużej części będą to rzeczy wyjaśnione przeze mnie w poradnikach, które możesz znaleźć na tym blogu.

Zaczynamy oczywiście od dołączenia nagłówków do naszej gry:

Następnie przechodzimy do funkcji main(), w której m.in tworzymy okno, a także jeżeli jesteśmy leniwi wczytujemy ip znajomego z pliku aby nie musieć go wpisywać za każdym razem.

Kolejnym krokiem jest wyświetlenie komunikatu z zapytaniem czy chcemy być serwerem czy klientem.

Skorzystałem tam z czcionki robotastic dostępnej m.in tutaj.

Jeżeli nie wczytujemy ip z pliku to pojawi się nam kolejny komunikat z prośbą o podanie ip, którego podanie zatwierdzamy klawiszem Enter (Return).

Komunikaty

Skoro mamy już informację kto jest serwerem, a kto klientem, a także znamy IP osoby, z którą będziemy grali to czas zacząć pisać właściwi kod.

Nasze próbne połączenie działa, tylko że jest 1 mały problem: nie może się nie udać. Tzn. będzie istniała próba nawiązania połączenia dopóki ono nie wystąpi, a to tego czasu nasze okno będzie nieaktywne i nieklikalne co rozwiążemy nieco później.

Na razie połączmy się sami ze sobą i zobaczmy jak nasze okno będzie wyglądało:

 

Moim zdaniem jest całkiem ok, po prawej stronie będzie można dodać informację z ilością wygranych gracza, czasem gry, itd. Teraz zajmiemy się nieco tym nieszczęsnym blokowaniem okna, przez co sprawia wrażenie że gra się zawiesiła.

Aby przeciwdziałać temu skorzystamy wątków (threads), o których możesz poczytać np. TUTAJ. Przy okazji wszelkie ustawienia przed pętlą główną gry.

Oraz funkcje odpowiadające za wysyłanie/odbieranie danych.

Pętlę główną rozbijemy sobie na kilka fragmentów bo jest ona dość spora.

Zaraz po rozpoczęciu pętli głównej mamy fragment, który odpowiada za odbieranie danych o ile jest taka potrzeba. Jeżeli jest ruch przeciwnika to jest uruchamiany wątek odpowiadający za odebranie danych i następnie zostaje w odpowiedni sposób wykorzystany.

Polecam tutaj na przeanalizowanie kodu. Kolejnym fragmentem jest pętla zdarzeń, gdzie w trochę winny sposób zakańczamy pracę naszego programu, przede wszystkim zakańczamy działanie wątków.

Następnym krokiem jest oczywiście sposób w jaki program ma się zachować gdy jest nasza tura, który jednocześnie kończy pętlę zdarzeń.

Oraz końcowa część kodu:

Jeżeli chciałbyś cały kod w 1 kawałku to będzie on dostępny poniżej w wersji na gitHub. Teraz zajmiemy się takimi czynnościami jak sprawdzenie wygranej.

Oto nasza funkcja sprawdzająca wygraną, jeżeli zwraca 0 to nic się nie dzieje, jeżeli 1 to wygrał serwer, jeżeli 2 to klient, jeżeli 3 to mamy remis.

Pod pętlą zdarzeń doszło nam właśnie sprawdzenie pól:

Jest tutaj także nowa zmienna exit, która decyduje o tym że po zmianie na true po 2 sekundach zakańcza działanie programu.

Zrobienie ewentualnych liczników i restartów programów pozostawiam wam, jeżeli chcecie możecie pochwalić się swoim kodem w komentarzach (np. umieszczając link do niego do pastebin, itp).

Powiedzcie też co sądzicie o tym abym pisał i komentował kod w formie filmu.

GitHub | .EXE


  • Hejter Naczelny

    Więcej porad o tworzeniu serwera ale na większą skalę a także proszę o dokończenie w miarę możliwości poradnika nt. pisania gry RPG. Dzięki 😀

    • Napisanie porad odnośnie tworzenia serwera wymagałoby jakiejś znajomości tego tematu, najlepiej napisania wcześniej gry wykorzystującej multiplayer na szerszą skalę, na co w moim wypadku na razie się nie zanosi.
      Co do kursu RPG, to nie mam weny na pisanie gier w SFML, następnie wyjaśnienie tego co zrobiłem we wpisie (zakończenie tego poradnika stanęło pod znakiem zapytania).

      • Hejter Naczelny

        Liczę na skończenie tego, bo właśnie na taką grę czekam. Oczywiście opis nie musi być obszerny, jedno zdanie wystarczy (np. „pętla sprawdzająca czy tekstura zawiera kolejną część, jeśli jest kolejna część to ją ładujemy a po załadowaniu szukamy następnej, jeśli jest następna to ładujemy i szukamy kolejnej a jeśli nie ma to rysujemy element na ekranie”)

        Liczę na jakąś grę typu Tibia z prosty serwerem na kilka osób i statystykami graczy.
        Ewentualnie proszę o poradnik nt. pisania gier 3D w trybie multiplayer. 😀

        • Tylko, żeby napisać kilka słów o czymś to musiałbym jakiś kod napisać, a obecnie tematyka kursu wyszła poza mój obszar zainteresowań, więc obecnie nie istnieje żaden bodziec, który by mnie motywował do kontynuacji tego kursu.

          Co do tego multi to jak pisałem wymaga głębszego zbadania tej tematyki, 3D multi odpada całkowicie, jest to dość mocno skomplikowane (mówimy o zrobieniu tego w dobry sposób, a nie „aby działało”), moje doświadczenie z 3D nie jest za duże gdy dorzucimy jeszcze multiplayer to znowu musiałbym odrzucić swoje własne projekty na rzecz prowadzenia kursu na bloga.

          Dopóki blogowanie mogę traktować tylko i wyłącznie jako hobby tak Państwo musicie być świadomi tego, że będą na blogu pojawiały się tylko te rzeczy, którymi się obecnie interesuję i zajmuję.

          • Hejter Naczelny

            W takim razie, odrzucam propozycję gry 3d na rzecz dokończenia poradnika Piszemy Grę RPG. A w ramach praktyki połączę to z multiplayerem. A czas to nie problem, jednak czekamy na kontynuacje. 😉

          • Zapomniałeś zdefiniować wyrażenie „czas to nie problem”, w najbliższym podsumowaniu miesiąca zasugeruję propozycję nie do odrzucenia odnośnie tego poradnika (znaczy odrzucić możecie, ale wtedy nie macie co liczyć na kontynuację wspomnianej serii), największy problem z tym kursem jest taki, że SFML mi się „przejadł”.

          • Hejter Naczelny

            W takim razie zmieniamy środowisko i wszyscy dostosowują się do tego co aktualnie jest na blogu. SFMLa za dokładnie nie poznałem, a skoro autor bloga emigruje no inny silnik, to ja razem z nim.:D

  • Johny Bravo

    Aplikacja działa przez internet na różnych komputerach tylko wtedy jeżeli używamy innego programu np. Hamachi, który nam to umożliwia, lecz niestety i wtedy pojawia się problem i aplikacja nie działa poprawnie. Grając na własnym komputerze jednocześnie na serwerze i kliencie wszystko jest ok. Jeśli kto zna powód to prosiłbym o wyjaśnienie problemu, bo to naprawdę ciekawa sprawa napisać taką grę. Pozdrawiam.

    • A masz odblokowane porty?

      • Johny Bravo

        Nie denerwuj się, ale nie do końca wiem o co Ci chodzi? Jeśli mam je w jakiś sposób zablokowane to jak mam je odblokować ?