Podstawy tworzenia gier online z 39dll
Działa to w taki sposób - każdy z graczy wysyła dane o sobie na serwer, a ten z kolei rozsyła te dane do innych graczy. Dzięki temu my widzimy co robią inni, a inni widzą co robimy my. A wszystko za pośrednictwem biednego serwera którego łącze siada od ilości fanów naszej gry exp-iących na potworkach. Tak czy siak, zacznijmy od kliku podstawowych funkcji 39dll:
koddllinit(nazwa dlla, ładowanie funkcji socketow, ładowanie funkcji operacji na plikach); //inicjuje dlla
/*
nazwa dlla - ustawiamy na 0 jeżeli chcemy użyć domyślnej "39dll.dll"
ładowanie funkcji socketow - na true jeżeli chcemy je załadować ( raczej chcemy tongue2.gif )
ładowanie funkcji operacji na plikach - na true jeżeli chcemy je załadować ( jeżeli potrzebujemy )
*/
tcpconnect( ip,port,tryb blokowania ); //proba polaczenia
/*
ip - adres ip serwera
port - port serwera
tryb blokowania - domyślnie na true
zwraca id socketa
*/
tcplisten( port, liczba ludzi, tryb blokowania ); //nasluchiwanie na polaczenia ( serwer )
/*
port - port na którym ma oczekiwać połączeń
liczba ludzi - liczba l. którzy mogą się połączyć
tryb blokowania - domyślnie na true
zwraca id socketa lub kod błedu
*/
tcpaccept( socket, tryb blokowania ); //akceptacja polaczenia
/*
socket - socket z którego nadeszło połączenie
tryb blokowania - domyślnie na true
zwraca id nowo utworzonego socketa
*/
closesocket( socket );
/*
zamyka i 'czyści' dany socket
*/
dllfree( );
/*
zwalnia dlla z pamięci
*/
To tyle jeśli chodzi o podłączanie i inicjowanie połączeń. Teraz trochę o przesyłaniu danych i odbieraniu wiadomości. Dane przekazujemy za pomocą kilku prostych funkcji:
kodwritebyte( wartosc );
/*
wysyła 1 bajt. wartość może być pomiędzy 0 a 255
tej funkcji używamy zazwyczaj jeżeli chcemy wysłać ID wiadomości lub gracza.
*/
writeshort( wartosc );
/*
wysyła 2 bajtową wartość liczbową. może być pomiędzy -32768 a +32767
tej z kolei funkcji uzywamy najczesciej do wysylania zmiennych. Jednak jeśli musimy wsłac zmienną mającą większą wartość możemy użyć np.
*/
writeint( wartosc );
//lub
writedouble( wartosc );
/*
Jezeli natomiast chcemy wysłac łańcuch znaków ( string ) czyli np. imię gracza albo inną wiadomość tekstową, użyjemy:
*/
writestring( string );
/*
Pamiętaj aby przed wysłaniem pakietu danych użyć funkcji:
*/
clearbuffer( );
/*
Ta funkcja czyści bufor,
Aby wysłać nasz pakiet zmiennych czy innych wartości musimy użyć funkcji, odpowiedzialnej za wysłanie wiadomości. Jest to funkcja:
*/
sendmessage( socket );
/*
Wysyła wiadomość do wskazanego przez nas socketa.
zwraca liczbę bajtów w wiadomości
*/
Tak więc przykładowy kod wysyłania danych o naszym graczu na serwer wyglądałby tak:
kodclearbuffer( ); //czyscimy bufor
writebyte( NAGLOWEK ); //o tym za chwilę
writebyte ( naszeID ); // ID naszego gracza
writestring ( name ); //zmienna w stringu - imię
writeshort( x ); //pozycja x
writeshort( y ); //pozycja y
wrteshort( life ); //jakaś zmienna - life
sendmessage( serversocket ); //wysyłamy wiadomość
Czym jest NAGLOWEK ? Ano, już tłumaczę - każda wysłana wiadomość musi posiadać swoje ID, aby serwer/klient wiedział co robić po odebraniu danej wiadomości. W tym celu używa się 'nagłówków', czyli jakiejś liczby używanej do rozpoznania naszej wiadomości ( ID ). W tym celu najlepiej używać stałych.
Dobra, wysłaliśmy nasze wiadomości, ale teraz jak je odebrać? Teraz wytłumaczę najważniejsze funkcje potrzebne przy odbieraniu wiadomości:
kodreceivemessage( socket );
/*
odbiera wiadomość z danego socketa.
zwraca liczbę odebranych bajtów
*/
readbyte( );
/*
czyta jeden bajt ( np. ID wiadomosci )
*/
readshort( );
/*
czyta zmienną short
*/
readstring( );
/*
czyta łańcuch znaków ( string )
*/
readint( );
/*
czyta zmienną int
i tak dalej
*/
Dobra, jak teraz odbieramy wiadomości? Najlepiej oczywiście w stepie.
Trzeba w tym celu utworzyć pętlę i odbierać w niej wiadomości z socketa:
kodwhile ( 1 )
{
wiadomosc = receivemessage( socket ); //odbieramy wiadomośc
if ( wiadomosc <= 0 ) break; //jezeli jest mniejsza bądź równa 0, wyłamujemy się z pętli
_ID = readbyte( ); //odbieramy nagłówek wiadomości
switch ( _ID )
{
case NAGLOWEK: //nagłówek naszej wiadomości
{
playerID = readbyte( ); //czytamy id gracza który przysłał wiadomość
/* teraz należałoby znaleźc ID tego gracza
w naszej, np. tablicy graczy */
for ( i=0; i<liczba_graczy; i+=1 )
{
if ( i == playerID ) //jeżeli aktualny indeks tablicy równa sie odebranemu ID
{
with ( i )
{
/* odbieramy zmienne */
name = readstring( );
x = readshort( );
y = readshort( );
life = readshort( );
}
}
}
break;
}
}
}
Teraz 'gracz' na serwerze odebrał swoje dane. No ale co z innymi graczami? Do nich przecież teraz musimy je wysłać aby oni również zobaczyli zmiany naszego gracza. No więc w 'kliencie' ( tym na serwerze - odpowiedzialnym za danego gracza w grze ) musimy umieścić taki sam kod jak w kliencie tym na którym gramy, czyli musimy wysłać wiadomości, z tą różnicą, że do innych graczy:
kod/* zasada identyczna jak przy
wysyłaniu wiadomości z klienta */
clearbuffer( );
writebyte( NAGLOWEK );
writebyte ( naszeID );
writestring ( name );
writeshort( x );
writeshort( y );
wrteshort( life );
with ( objClient )
{
if ( clientID != naszeID ) //jezeli ID tego klienta nie równa sie naszemu
{
sendmessage( playersocket ); //wysyłamy wiadomość
}
}
Teraz należy w kliencie odebrać te wiadomości, a następnie przypisać je obiektowi przedstawiającemu innego gracza. Tak więc w obiekcie odbierającym dane umieszczamy kod podobny jak na serwerze:
kodwhile ( 1 )
{
wiadomosc = receivemessage( socket ); //odbieramy wiadomość
if ( wiadomosc <= 0 ) break; //jeżeli jest mniejsza bądź równa 0, wyłamujemy się z pętli
_ID = readbyte( ); //odbieramy nagłówek wiadomości
switch ( _ID )
{
case NAGLOWEK: //nagłówek naszej wiadomości
{
playerID = readbyte( ); //czytamy id gracza który przysłał wiadomośc
/* teraz należałoby znaleźc ID tego gracza
wśród obiektów przedstawiających innych graczy */
with ( objPlayerOther )
{
if ( jegoID == playerID ) //jeżeli ID tego gracza równa sie temu ID które odebraliśmy
{
/* odbieramy zmienne */
name = readstring( );
x = readshort( );
y = readshort( );
life = readshort( );
}
}
}
break;
}
}
}
Tak to mniej więcej wygląda. Nasz system powinien działać - odbierać zmienne i przekazywać innym graczom. Wydawałoby się że to na razie takie 'nic', ale wierz mi - większość innych rzeczy ( walka, wysyłanie przedmiotów, grafik ) opiera się na tym właśnie co opisałem. Jeżeli to zrozumiesz, nie będziesz miał już problemów.
Trzeba się z tym oswoić i trochę potrenować, ale myślę że ten artykuł ci to ułatwi.