Gra sieciowa w c++ - pytania teoretyczne.

Odpowiedz Nowy wątek
2010-01-15 15:35
0

Witajcie,

na wstępie chciałbym zaznaczyć, że jestem początkującym użytkownikiem forum i się przywitać.
Jestem studentem IT i mam do zrobienia na przedmiot 'Programowanie obiektowe' zrobić grę sieciową z wykorzystaniem biblioteki Allegro.

Allegro już kiedyś używałem, w c++ może nie wymiatam, ale proste aplikacje na obiektach jestem w stanie napisać bez problemu.

W przypadku powyższego projektu największym problemem jest brak wiedzy na temat pisania aplikacji sieciowych w c++. Słyszałem o programowaniu socketów, zaczynam się dokształcać w tym temacie.
Interesuje mnie przede wszystkim w jaki sposób należy podejść do zrobienia takiego projektu. Bo napisać samą aplikację od strony użytkownika (np. jakiegoś pacmana) to nie problem. Nie wiem natomiast jak zaimplementować tą "sieciowość". Czy do tego używa się jakichś serwerów dla c++ (coś jak apache dla php z możliwością instalacji na localhoście)? Czy może pisze się taką aplikację w taki sposób, aby u dwóch graczy aplikacje komunikowały się bezpośrednio (choć w tym przypadku jakoś nie widzę tego rozwiązania).

Za wszelkie odpowiedzi z góry serdeczne dzięki.
Łukasz


Jeśli starasz się za coś wziąć, rób to z należytą starannością.
--------------------------------------------
Kupić kupon chybił-trafił 2zł, napisanie programu losującego liczby jako pierwszego programu w C++ - bezcenne :)

Pozostało 580 znaków

2010-01-15 16:36
0

Na Twoim miejscu zainteresowałbym się ICEm albo jakimś innym middleware do komunikacji sieciowej. Sockety też będziesz musiał kiedys przerobić, ale wierz mi, nie chcesz się irytować o to, że "nie działa i nie wiesz czemu". Jeśli będziesz potrzebował pomocy z ICEm, chętnie służę pomocą


Jeśli Ci pomogłem, postaw piwo:)

Pozostało 580 znaków

2010-01-15 20:53
0

Rozumiem, że ICE nie wyklucza użycia Allegro do zaimplementowania interfejsu? :)

Może na początek, zanim cokolwiek napiszę, prosiłbym o nakierowanie, jak wygląda struktura takiej aplikacji (czy ICE się winstalowuje) itd. Następnie poczytam dokumentację i w razie jakichś problemów odezwę się... Bo nie wiem nawet od czego zacząć.


Jeśli starasz się za coś wziąć, rób to z należytą starannością.
--------------------------------------------
Kupić kupon chybił-trafił 2zł, napisanie programu losującego liczby jako pierwszego programu w C++ - bezcenne :)

Pozostało 580 znaków

2010-01-15 21:18
Its not me
0

Google->Beej's guide to network programming

Pozostało 580 znaków

2010-01-15 22:17
0
Its not me napisał(a)

Google->Beej's guide to network programming

Wielkie dzięki za linka.. :) Sporo mi pomoże.... [browar]


Jeśli starasz się za coś wziąć, rób to z należytą starannością.
--------------------------------------------
Kupić kupon chybił-trafił 2zł, napisanie programu losującego liczby jako pierwszego programu w C++ - bezcenne :)

Pozostało 580 znaków

2010-01-15 23:38
0

Maksymalny skrót:
Masz aplikację robiącą za serwer i aplikację robiącą za klienta. Konfigurujesz parametry połaczenia (ip, protokół, port), rejestrujesz na serwerze obiekty (poprzez przypisanie im unikalnej nazwy). Masz więc czwórkę: ip, protokół, port, nazwa. Teraz z poziomu klienta podłączasz się pod wspomnianą czwórkę, dostając proxy (proxy w sensie wzorca). Może asciirysunek:

Server                                      Client
[obiekt]       <------sieć-----------> [obiektProxy]

obiektproxy ma takie same metody jak obiekt. Wywołując jakąś metodę na obiektproxy, argumenty są jakoś serializowane, przesyłane przez sieć, następnie na serwerze odserializowywane i wywoływana jest metoda. Po skończeniu wywołania rezultat funkcji wraca do klienta.

Różnica dla Ciebie: zamiast kminić jakis protokół przesyłu danych przez sockety, możesz pisac program w sposób czysto obiektowy, a'la
gameBoardPrx.getBishop(0).moveTo(x,y);

ICE zasadniczo wspiera Javę, C++, Pythona, Rubiego i C#


Jeśli Ci pomogłem, postaw piwo:)

Pozostało 580 znaków

2010-01-16 01:56
0

Jeśli dobrze zrozumiałem, implementuję obiektowo kod tak jak normalnie, a później przesyłam dane do socketów? Czyli, dla przykładu, mając grę w warcaby implementuję planszę, ruch i po dokonaniu ruchu lokalnie i zaktualizowaniu danych gry są one przesyłane do serwera (oczywiście muszę to sam zaimplementować, żeby działało)?

ruch zawodnika -> wyświetlenie zmian -> zapisanie zmian w danych -> przeslanie -> odczyt przez klienta drugiego zawodnika -> wczytanie -> aktualizacja ekranu u drugiego gracza


Jeśli starasz się za coś wziąć, rób to z należytą starannością.
--------------------------------------------
Kupić kupon chybił-trafił 2zł, napisanie programu losującego liczby jako pierwszego programu w C++ - bezcenne :)

Pozostało 580 znaków

2010-01-16 13:09
0

Pozwolę sobie poilustrować kodem. Będą to fragmenty jednej z laborek na studiach. Źródła są w Javie, ale z powodzeniem można pisać w C++.

Serwer:

public class Server {

    public static void main(String args[]) {
        String port = args[0];
        String host = "tcp"; //innymi słowy - nasłuchuj zewsząd, ktokolwiek będzie się łączył to tcp
        String service = "FTPloth"; //to ten identyfikator, o którym pisałem w poprzednim poście
        String connectionString = host + " -p " + port;

        Ice.Communicator ic = null;
        try {
            ic = Ice.Util.initialize(args); // Weź argumenty z linii poleceń, a nuz będzie coś dla ICE'a

            Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints(service, connectionString); //tworzymy adapter

             Ice.Object object = new CoreI(); //tworzymy sobie obiekt CoreI();

             adapter.add(object, ic.stringToIdentity("FTPloth")); // i rejestrujemy go jako usługa FTPloth

            adapter.activate(); //aktywujemy adapter

            ic.waitForShutdown(); // i czekamy, aż nas user zabije

        } catch (Ice.LocalException e) {
            e.printStackTrace();
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

I klient:

private CorePrx cp; //obiekty proxy, czyli formalnie rezydujące na serwerze
private DirectoryPrx rDir;
/* ... */
public Client(String[] argv) throws FileException, IOException {
        host=argv[0];
        port=argv[1];
        ic = Ice.Util.initialize(argv);

        String connectionString = name + ":tcp -h " + host + " -p " + port;

        Ice.ObjectPrx base = ic.stringToProxy(connectionString); //Tutaj się łączymy na podstawie nazwausługi:protokół -h host -p port 

        cp = CorePrxHelper.checkedCast(base); //I rzutujemy obiekt na naszą klasę CorePrx

        if (cp == null) {
            throw new Error("Unsuccessful connection.");
        }
        rDir = cp.getDir(rDirPath); //voila!, cokolwiek zrobimy na kliencie, zostanie zrobione na serwerze!

To, co jest tutaj wystarczy Ci, by nawiązać połączenie. Wywołując metody na obiekcie cp w kliencie, wywołujesz je na serwerze (obiekt klasy CoreI()).


Jeśli Ci pomogłem, postaw piwo:)

Pozostało 580 znaków

2010-01-20 16:41
0

To mi dużo rozjaśniło :) Dzięki wielkie.

I jeszcze jedno małe pytanie: jeśli chodzi o postawienie serwera ICE, to się normalnie winstalowuje na kompie, który ma służyć za serwer i następnie kod serwera się wrzuca do któregoś z katalogów ICE (tak jak dla Apache wrzuca się pliki php do htdocs), a klienta normalnie na kompie klienckim odpala...?


Jeśli starasz się za coś wziąć, rób to z należytą starannością.
--------------------------------------------
Kupić kupon chybił-trafił 2zł, napisanie programu losującego liczby jako pierwszego programu w C++ - bezcenne :)

Pozostało 580 znaków

2010-01-20 17:57
0

Nie.
Ice z punktu widzenia programowania to tylko biblioteka (znaczy ma też właśne programy, jak np. IceStorm).

Korzystając z biblioteki piszesz serwer. Tak jak na tym listeningu, czyli Ty musisz wymyślić, co on robi (w naszym wypadku udostępnia obiekt CoreI klientom, u Ciebie będzie to pewnie jakiś chessboard czy coś. Klienci łączą się z tym serwerem i dostają CorePrx, czyli coś, co się zachowuje identycznie jak CoreI. Wywołując metodę na CorePrx, wywołują ją w rzeczywistości na CoreI().

Taki szkic dla Ciebie:

class ChessboardI() extends Chessboard{
  String[][] board; //np. do trzymania informacji, jaki pionek gdzie jest, to równie dobrze zamiast stringa może być obiekt
  void movePiece(String pieceId, int xpos, int ypos) throws NotAllowedMoveException{
    //....
  }

  String[][] getState(){
    return board;
  }

  //... i co Ci jeszcze przyjdzie do głowy.
}

Klient z drugiej strony łączy się z serwerem, dostaje proxy do serwanta ChessboardI:

CheeseboardPrx board;
//łączenie
gui.display(board.getState()); // wyświetlasz pozycję
// pobierasz ruch usera
board.movePiece(id,x,y);

Czyli rozumiesz, klient działa na obiekcie proxy, który wszystkie wywołania pakuje w sieć i wysyła do serwanta (chessboardI).


Jeśli Ci pomogłem, postaw piwo:)

Pozostało 580 znaków

2010-02-07 00:12
0

Albo skorzystaj z gotowej warstwy połączeniowej :
http://www.boost.org/doc/libs[...]html/boost_asio/examples.html
Na potrzeby gry klient serwer polecam kod chat_server i chat_client. serwer koordynuje wysyłanie komunikatów do każdego klienta - w nim nic nie musisz zmieniać.
Pozostaje ci tylko obsługa przychodzących od serwera komunikatów i wysyłanie nowych komunikatów z klienta do serwera. Serwer po otrzymaniu komunikatu automatycznie zrobi "broadcast" do wszystkich pozostałych podłączonych klientów. Na koniec dołączasz bibliotekę allegro i gotowe.


Nie ma ludzi zdrowych psychicznie, są tylko źle zbadani...

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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