str 7

str 7



gra w statki

komputera. Podanie wartości NULL oznacza, iż otwierane gniazdo będzie nasłuchiwać. Jednak, aby serwer oczekiwał na połączenie, trzeba posłużyć się odpowiednią pętlą, której fragmenty zawiera Listing 3.

Pętla oczekuje na połączenie klienta. Jej działanie można przerwać klawiszem [Esc]. W takim przypadku program kończy swoje działanie. Funkcją SDLNet_Check-Sockets sprawdzamy, czy jakieś gniazdko, należące do zbioru, jest aktywne. Robimy to przez 50ms. Jeśli nie wystąpiła aktywność, powracamy na początek pętli, dzięki czemu możemy realizować inne czynności, np. animację czy po prostu zmieniać kolor napisu. Jeśli jednak jakieś gniazdo ze zbioru było aktywne, to drugą funkcją (SDLNet_ SocketReady) sprawdzamy, czy było to gniazdo server. Jeśli tak, to możemy zaakceptować połączenie za pomocą funkcji SDLNet_TCP_Accept. Jej wynikiem będzie jeszcze jedno gniazdko, tym razem reprezentujące połączenie z klientem. Taki sposób oczekiwania na połączenie jest typowy dla większości aplikacji TCP/IP. Polecam w tym miejscu stronę z dokumentacją do biblioteki SDL_Net, na której znajdują się przykłady prostych aplikacji sieciowych - można zobaczyć, jak należy pisać kod dla serwera bądź klienta.

Obsługa sieci - funkcja GameLoop

Po nawiązaniu połączenia, automatycznie następuje przejście do właściwej gry. Zajmuje się tym w całości funkcja GameLoop. Funkcja ta na samym początku swojego działania rysuje dwie plansze: naszą oraz przeciwnika (oczywiście są one ciągle uaktualniane, ponieważ gra toczy się w trybie rzeczywistym). Umieszczane są również podpisy pod planszami. Następnie przetwarzanie wchodzi w pętlę. Opuszczenie pętli następuje w dwóch przypadkach: gdy przeciwnik zatopi nam wszystkie statki bądź po naciśnięciu klawisza [Esc].

Dla nas najważniejsza jest komunikacja sieciowa. Schematycznie można przedstawić ją tak, jak prezentuje to Rysunek 4. Kolorem zielonym oznaczono dane wysyłane przez serwer, a pomarańczowym - od klienta. Jak widać, zarówno klient, jak i serwer, wysyłają dane według tego samego schematu. Wynika z tego, że jedyna różnica pomiędzy serwerem a klientem pojawia się w omówionej wcześniej funkcji GetYourName, gdy serwer czeka na zgłoszenie się klienta.

Ogólnie wymiana informacji pomiędzy serwerem i klientem przedstawia się następująco. Jeśli na planszy przeciwnika (zarówno w programie klienta, czy serwera) zostanie wskazane pole i naciśnięty lewy klawisz myszy, to następuje przesłanie do przeciwnika informacji o współrzędnych oraz kod zero, oznaczający zapytanie, czy strzał w coś trafił. W przypadku klienta wygląda to następująco:

msg.pos_x=pos_x; msg.pos_y=pos_y; msg.ack=0;

result=SDLNet_TCP_Send(Client, &msg, len_msg);

Listing 3. Fragment pętli serwera oczekującej na połączenie od klienta

whiie( remote_cl i ent_i s_ready=0) {

// pętla przetwarzająca zdarzenia SDL if(done=l) break;

// jeśli wciśnięto ESC, przerwij działanie pętli if(!SDLNet_CheckSockets(srv_set, 50)) continue; if($DLNet_SocketReady(server))

remote_client=SDLNet_TCP_Accept(server); if(!remote_cltent) continue; elsei

SDLNet_TCP_AddSocket(srv_set, remote_client): remotei p=SDLNet_TCP_GetPeerAddress(remote_

Client):

remote_cli ent_is_ready=l:

}}

Wersja dla serwera różni się tylko nazwą zmiennej reprezentującej socket - będzie to remote_client. Program przeciwnika odpowie nam, w co trafiliśmy. Zanim jednak odbierzemy dane, podobnie jak było to przypadku serwera, będziemy testować, czy określony socket jest aktywny. Kod dla klienta prezentuje się następująco:

if(PRG_TYPE==PRG_CLIENT && SDLNet_CheckSockets(clc_set.

50)) {

if(SDLNet_SocketReady(cl ient)){ msg.ack=-100;

result=SDLNet_TCP_Recv(client, &msg, len_msg); data_avai 1=1;

11

Jak widać w kodzie, celowo przed oczytaniem danych z gniazda w polu ack umieszczono wartość -100, aby mieć pewność, że odebraliśmy prawidłowe dane. Jeśli pojawią się błędy, to nie zostanie zmieniona zawartość zmiennej msg, a kod -100 zostanie zignorowany. Gdy wszystko pójdzie bez problemów, w zmiennej msg i polu ack znajdzie się odpowiedź. Wartość -1 oznacza pudło. Gdy znajdzie się tam wartość od jedności do czwórki, to trafiliśmy w statek. Trzeba oczywiście nanieść odpowiednie zmiany do planszy przeciwnika. Po stronie przeciwnej takie zmiany naniósł także przeciwnik na swojej planszy. Może on więc z niepokojem obserwować jak z „zimną krwią” eliminujemy jego statki.

Główna pętla, oprócz obsługi sieci, sprawdza także, czy nie przegraliśmy. Test polega na tym, że zliczamy ilość wystąpień zatopionych statków (w taki sposób działa funkcja i s Los t Ga me). Gdy na całej planszy pojawią się cztery jedenastki, sześć dwunastek (jeden dwumaszto-wiec zawiera dwie części, więc dlatego sześć) i tak dalej,

www.linux.com.pl

63



Wyszukiwarka

Podobne podstrony:
37311 str 5 gra w statki ta nie jest przypadkowa, gdyż dokładnie w takiej kolejności komputer wykonu
str( 29 gać w kształtowaniu hierarchii wartości i norm, a także dawać nam rzetelną wiedzę o rzeczywi
Egzam z Żelbetu semestr2 str 0022 bmp W powyższych wzorach przyjęto następujące oznaczenia: P0 - poc
skanuj0107 (24) 194    _____B. Cieślar Dodatnia wartość naprężenia oznacza naprężenie
img324 i po podaniu pewnego leku. Oznaczmy wyniki przez x]t .... Arfloraz x{, Powiemy, że / -te dośw
IMG 1306114614 Zadanie 6 Dowolną metoda znaleźć wartość całki oznaczonej z dokładnością 0.01 Zaznac
50. Edukacyjna gra przygodowa komputerowa jak np. „Klik Wielki wyścig" 2
Ekonomiczna wartość dodana oznacza nadwyżkę powstałą, gdy zwrot z zainwestowanego kapitału jest wyżs
Bit i: Jeśli bit i ma wartość logicznej "1" oznacza to, że dane W buforze odbiornika nie z
o podatek akcyzowy. W przypadku różnic kursowych oraz sprzedaży papierów wartościowych „netto” oznac
Tab. 1. Ocena biotopu korytowego - A Wartość oceny Oznaczenie Wyjaśnienie 1 Całkowicie
174 Grzegorz Śląski Wartość Fc oznacza siłę tarcia Coulomba, S$t - współczynnik Stribecka.a k -

więcej podobnych podstron