Skocz do zawartości
  • Ogłoszenia

  • Gdzie świętować urodziny GMCLANu   27 użytkowników zagłosowało

    1. 1. Gdzie świętować urodziny GMCLANu


      • Warszawa (bo w centrum)
      • Szczecin (bo tam mieszka Ranma i narodził się GMCLAN)

    Żeby zagłosować w tej ankiecie, prosimy się zalogować lub zarejestrować. Zobacz temat
  • 0
oLuju

Wysyłanie informacji o pociskach - Multiplayer

Pytanie

oLuju    0

Hej, otóż ostatnio przeczytałem sobie manual tłumaczący zasadę działania multiplayer'a w GM 8.1. Udało mi się stworzyć prototyp w którym jest 6 ludzików (graczy) 3 w drużynie niebieskiej i 3 w drużynie czerwonej. System przydzielający nowego gracza do danego ludzika w grze działa, komunikowanie z serwerem i synchronizacja "prawie" też. Prawie ponieważ napotkałem pewną trudność, której nie potrafię rozwiązać. Otóż postacie te mogą strzelać. Generalnie wygląda to tak że każdy ludzik jest innym objectem (player1, player2, etc.) tak jak ich pociski (bullet1, bullet2, etc.). Niestety problem pojawia się w momencie strzału, gdyż trzeba wysłać wiadomość na serwer, która stworzy ten pocisk u wszystkich innych graczy. Generalnie udało mi się to ale niestety po strzale następuje dłuuuuuuga linia tego pocisku bez końca.

Generalnie wygląda to tak (jak coś jest to obraz z widoku gracza 1, ludzik który strzela to gracz 2):

8b2465e42a1d6.png

Pocisk w Creat'ie zawiera taki kod:

GML
///Kontrola kierunku strzalu i szybkosci pocisku

if global.nextplayer != 1 //Definiowanie ID gracza (gracz1, gracz,2)

{ //Jesli nie

x = mplay_data_read(4); //Pobierz pozycje x

y = mplay_data_read(5); //Pobierz pozycje y

speed = mplay_data_read(6); //Pobierz szybkosc objektu

direction = mplay_data_read(7); //Pobierz kierunek obiektu

exit;

}

else

{//Jesli tak

direction=point_direction(x,y,mouse_x,mouse_y); //Wez kierunek lotu z pozycji myszki

speed=15 //Ustal szybkosc

mplay_data_write(6,obj_pocisk1_team1.speed); //Wyslij dane o szybkosci pocisku

mplay_data_write(7,obj_pocisk1_team1.direction); //Wyslij dane o kierunku pocisku

}

 

Kod wystrzału wygląda tak:

GML
if global.nextplayer != 1

{ //Jesli nie

y = mplay_data_read(2); //Pobierz pozycje gracza x

x = mplay_data_read(3); //Pobierz pozycje gracza y

image_single = mplay_data_read(38); //Pobierz kierunek gdzie patrzy sie gracz

while mplay_message_receive(0); //Gdy zostanie odebrana wiadomosc...

{

if (mplay_message_id() == 100) instance_create(self.x, self.y, obj_pocisk1_team1); //Jesli to wiadomosc o ID=100 stworz obiekt pocisku

}

exit;

}

else

{

if mouse_check_button(mb_left)

{

if przeladuj=0

{

if magazynek>0

{

if strzelac=1

{

strzelac=0

instance_create(self.x, self.y, obj_pocisk1_team1) //Stworz obiekt u siebie

mplay_message_send(0, 100, obj_pocisk1_team1); //Wyslij wiadomosc o wystrzale do innych

mplay_data_write(4,obj_pocisk1_team1.x); //Wyslij pozycje x , gdzie stworzyl sie pocisk

mplay_data_write(5,obj_pocisk1_team1.y); //Wyslij pozycje y , gdzie stworzyl sie pocisk

magazynek-=1

alarm[1]=20

}

}

}

}

}

Zaznaczam też że większość kodu uciąłem żeby nie zawalać posta. Reszta działa i jedynym problemem jest ten duplikujący się pocisk.

Jakieś pomysły jak to poprawić lub zrobić to lepiej???

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

7 odpowiedzi na to pytanie

Rekomendowane odpowiedzi

  • 0
I am vader    25

Niestety moja wiadomość nie wniesie nic do postu, chciałbym tylko nadmienić, kilka rzeczy do Twojej uwagi:

 

Wszyscy przenieśliśmy się do GMS, wątpię abyś znalazł kogoś kto będzie z głowy pamiętać stary mplay (który już nie istnieje i został zastąpiony przez Async Networking).

Dodatkowo nawet za czasów GM 7/8/8.1 mplay byl bardzo niepopularny ze względu na toporność i powolność działania.

 

Zalecam Ci przenieść się na GMS lub GMS 2 i zaczęcie tam od nowa. Owszem, po przeanalizowaniu kodu zapewne znajdziemy wspólnymi siłami rozwiązanie, ale im dalej zajdziesz z kodem tym mniej będziemy mogli pomóc.

 

 

Co do samego problemu:

1. Tworzysz pocisk.

2. Create się odpala, wysyłając pakiet o stworzenie pocisku.

3. Tworzysz pocisk na podstawie tego pakietu.

4. Create nowego pocisku się odpala, wysyłając pakiet o stworzenie pocisku.

5. itd

6. itp.

 

Edit: Teraz widze ze to prawdopdoobnie nie to, ale na wypadek upewnij sie.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
oLuju    0

Próbowałem się przerzucić na GMS'a ale przez kilka zmian w GML'u oraz kilka ogólnikowych "usprawnień"/zmian wydaje mi sie on trochę toporny i nie mogłem się przyzwyczaić.

Co do odpowiedzi - nie to nie to, pocisk tworzy dany gracz po naciśnięciu LPM i wysyła informacje gdzie utworzyć ten że pocisk (w miejscu gdzie aktualnie się znajduję gracz), a pocisk wysyła informacje o szybkości i kierunku (gdzie u innych graczy po prostu pobiera te dane).

Sam zapomniałem też wspomnieć o 2 rzeczach:

1.Problem nie leży w złym ustawieniu szybkości strzelania, bo pociski wystrzeliwane są co 20 kroków.

2.Gracz który strzel widzi swoje pociski normalnie, tylko reszta ma je "zbugowane".

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
I am vader    25

Czy jest możliwość, że odbiorca nie ma sposobu identyfikacji pocisku więc tworzy nowy przy każdym update pozycji? Czy raz stworzony pocisk sie tworzy i sobie leci jak mu sie podoba bez 'poprawek' ze strony serwera?

Edit: Na pewno regularnie czyścisz buffer wiadomości?

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
I am Lord    13

Każdy musiał przebrnąć przez te zmiany wprowadzone w GMS i ty też musisz bo nikt już z pamięci nie pomoże, GM8 nie działa na win10 tak btw. Więc ja mimo że posiadam GM8 to nie mogę ci pomóc tak czy siak.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
oLuju    0

Odbiorca dostaje wiadomość o stworzeniu pocisku i tworzy go u siebie. Wydaje mi się że korekcja nie istnieje, bo jeśli pocisk zostanie utworzony u wszystkich graczy w tej samej pozycji, nada mu sie kieeunek i szybkość to dalej już poleci tak samo u wszystkich. Manual, który czytałem opisywał używanie mplay'a na przykładzie ponga. Piłka w tej grze nie dostaje caly czas informacji o jej pozycji bo przez zgubione pakiety (bądź opóźnione) teleportowała by się, dlatego wszystkie dane (pozycja, szybkosc, kierunek) wysyłane są tylko gdy piłkę uderzy deska, a później wysyła tylko część info (kierunek, szybkość) którą ustala raz. Pomyślałem że podobnie będzie w przypadku pocisku, bo gdy będzie ich dużo i zaczną co ,np. 1s. wysyłać swoją pozycję by zrobić korektę gdzie się znajdują to przez to ze na mapie bedzie kilka pocisków tego samego gracza, zaczną teleportować się do siebie na wzajem. Ponadto gracze nie wysyłaliby aż tyle danych.

Co do buffera to nie. Dane o ID 1 są wysyłane, a następnie odbierane, tyle. Co prawda informacja o stworzeniu pocisku to tak zwany Message, a nie Data shared jak wszystko i nie wiem czy gdy mplay_message wysyła pakiet, to gdy go ktoś odbierze zobaczy go jako 'pojedyńczy impuls' czy potraktuje jak zmienną z wartością true przez co faktycznie tworzy ciągle nowe pociski.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
oLuju    0

OK udało mi się wszystko w miarę naprawić. Gdy gracze Teamu 1 strzelają to pociski pojawiają się normalnie.

7c1a78fa8a763.png

Jednak teraz jest inny problem, bo strzelanie nie działa w Teamie 2:

bb7535e472df8.png

Pocisk u gracza strzelającego (z teamu 2) pojawia się normalnie, za to u innych nie ma po nim śladu.

 

Kod strzelania dla gracza 1 z teamu 1:

GML
//===================JESLI JESTEM KIMS INNYM==========================

while mplay_message_receive(0)

{

if mplay_message_id() == 100 and mplay_message_value() == 1

{

mplay_message_send(0, 100, 0);

instance_create(self.x, self.y, obj_pocisk1_team1);

}

}

 

//=====================JESLI NIM JESTEM==============================

if mouse_check_button(mb_left)

{

if przeladuj=0

{

if magazynek>0

{

if strzelac=1

{

strzelac=0

instance_create(self.x, self.y, obj_pocisk1_team1)

mplay_message_send(0, 100, 1);

mplay_data_write(4,obj_pocisk1_team1.x);

mplay_data_write(5,obj_pocisk1_team1.y);

magazynek-=1

alarm[1]=20

}

}

}

}

 

Kod strzelania dla gracza 1 z teamu 2:

GML
//===================JESLI JESTEM KIMS INNYM==========================

while mplay_message_receive(0)

{

if mplay_message_id() == 103 and mplay_message_value() == 1

{

mplay_message_send(0, 103, 0);

instance_create(self.x, self.y, obj_pocisk1_team2);

}

}

 

//=====================JESLI NIM JESTEM==============================

if mouse_check_button(mb_left)

{

if przeladuj=0

{

if magazynek>0

{

if strzelac=1

{

strzelac=0

instance_create(self.x, self.y, obj_pocisk1_team2)

mplay_message_send(0, 103, 1);

mplay_data_write(22,obj_pocisk1_team2.x);

mplay_data_write(23,obj_pocisk1_team2.y);

magazynek-=1

alarm[1]=50

}

}

}

}

 

Przewertowałem cały kod i wszytko jest dokładnie tak samo u każdego gracza, wszystkie ID się zgadzają.

Chce dokończyć ten projekt do końca i tyle (nie lubię porzucać niedokończonych projektów).

Zacząłem już szukać GM'a Studio. Więc prawdopodobnie niedługo się na niego przeniosę.

 

I am Lord - Jeśli faktycznie mój post umrze bo NIKT tego nie pamięta to dam se spokój <_<

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  • 0
pablo1517    0

Stary mplay potrafił najprostrzy pakiet po TCP przesyłać przez 5 sekund z tego co pamiętam, więc w ogóle nie widze sensu marnowania na to czasu.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się tutaj.

Zaloguj się tutaj

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników, przeglądających tę stronę.

×