Poradnik: Jak napisać grę multiplayer RPG szybko i przyjemnie

Poradnik: Jak napisać grę multiplayer RPG

szybko i przyjemnie

Zasady

Pierwsza: nie zrobisz w ten sposób super hiper mega MMO

Druga: jest masa lepszych sposobów aby to zrobić, ten jest prosty i mój

Trzecia: możesz to traktować jako wstęp, ogólną ideę

Czwarta: używam C++ i SFML

Piąta: najpierw przeczytaj potem patrz kod na githubie 🙂

Pierwsze kroki

Zaczynamy od stworzenia klienta i serwera. Tutaj klient służy do komunikacji z serwerem i do wyświetlania świata gry. Serwer otrzymuje komendy od klienta i na ich podstawie aktualizuje świat gry i wysyła kopię do klienta. Świat składa się z graczy, przedmiotów, obiektów itd.

Na początek przygotowujemy połączenie. Skoro doszedłeś do etapu, gdzie chcesz programować swoją grę multiplayer to zakładam, że sobie poradzisz z tą prostą czynnością. Tutaj masz link: https://www.sfml-dev.org/tutorials/2.4/network-socket.php

Dodanie gracza do serwera

Zadania:

  • gracz potrzebuje unikalnego ID po stronie serwera
  • musimy dodać gracza do Świata
  • trzeba wysłać informacje o nowym graczu do klientów

Tak więc, kiedy klient łączy się z serwerem to on musi zrobić jakieś unikalne ID. Ja to zrobiłem w ten sposób:

std::string player_id = „player_id__” + std::to_string(reinterpret_cast<uint32_t>(client)); 

W ten sposób mamy ID dla gracza. Po prostu pobiera z pamięci adres clienta i robi z tego string. Wystarczająco dobre dla prostej, lokalnej gry.

world->addPlayer(Player(player_id, sf::Vector2f(100, 100), sf::Vector2f(66, 92), 100));

Tak dodajemy gracza do świata z wcześniej utworzonym id, pozycją, rozmiarem i życiem.

Następnie wysyłamy informację o graczu do klienta.

sf::Packet start_packet;
start_packet << "connect" << *world->getPlayer(player_id); 
client->send(start_packet);

Strona klienta:

– wydobywamy ID gracza z otrzymanego pakietu i przechowujemy go w kliencie (pozwoli nam to informować serwer kim jesteśmy)

Więc kiedy otrzymamy pakiet sprawdzamy czy to jest ‚connect’ i wydobywamy ID gracza i przypisujemy do client_player_id = received_id;

Logika

Reszta logiki jest podobna. Na przykład:

Klient wysyła komendę ‚update world’ – serwer po otrzymaniu tego wysyła cały świat do gracza

Kiedy klient otrzyma ‚update world’ podmienia świat na ten, który dostał z serwera

Klient wysyła ‚move player up’ i swój id do serwera, który przesuwa gracza o danym id w górę

Sprawa jest ogólnie prosta. Zobacz na mój przykładowy kod do komunikacji pomiędzy klientem i serwerem.

Klient:

void Client::runCommand(const std::string& command, const std::string& id)
{
  if(command == "player move")
    {
      sf::Packet packet;
      packet << "player move" << id << player_id;
      socket.send(packet);
    }
  if(command == "destroy item")
    {
      sf::Packet packet;
      packet << "destroy item" << id;
      socket.send(packet);
    }
} 

To jest część kodu z klasy Client. Używam tutaj prostej funkcji, która wysyła polecenia do serwera.

Serwer:

sf::Packet packet;
if(client.receive(packet) == sf::Socket::Done)
{
    std::string event;

    if(packet >> event)
    {
        if(event == "player move")
        {
            std::string player_id;
            std::string direction;
            if(packet >> direction >> player_id)
            {
                if(direction == "up")
                    world->getPlayer(player_id)->position.y -= 5;
                if(direction == "down")
                    world->getPlayer(player_id)->position.y += 5;
                if(direction == "left")
                    world->getPlayer(player_id)->position.x -= 5;
                if(direction == "right")
                    world->getPlayer(player_id)->position.x += 5;
            }
        }
        if(event == "update world")
        {
            sf::Packet send_packet;
            send_packet << "update world" << *world;
            client.send(send_packet);
        }
        if(event == "destroy item")
        {
            std::string item_id;

            if(packet >> item_id)
            {
                world->removeItem(item_id);
            }
        }
    }
}

Podsumowanie

Może nie jest to idealne  rozwiązanie. Może nie robi się tak gier. Nie takie jest zadanie tego postu. Ma on pokazać ogólną ideę stojącą za komunikacją w grach pomiędzy serwerem i graczem. Nawet jeśli nie jest to zrobione idealnie to dla mnie jest to kod z którego jestem dumny. Nie ma dobrych poradników, które za rękę poprowadzą kogoś jak się robi gry multiplayer. Przynajmniej nie było kiedy to programowałem (rok 2015). Jestem na tyle dumny z tego kodu, że często się nim posługuję pokazując, że jestem w stanie samemu wymyślić sposób aby rozwiązać jakiś problem.

Obiecany kod

Github: PMR – Patys MMO RPG

 

Please follow and like us:
0

Dodaj komentarz

3 komentarzy do "Poradnik: Jak napisać grę multiplayer RPG szybko i przyjemnie"

Powiadom o
avatar
Sortuj wg:   najnowszy | najstarszy | oceniany
kordian
Gość

Jest to już coś grywalnego? Masz jakieś screeny?

Michał
Gość

Wielkie dzięki, że wrzuciłeś kod, bardzo mi pomogłeś.