Od pewnego czasu pisze gre online. Prosty dwuwymiarowy mmorpg. I mam klopot z synchronizacja graczy na ekranie. Na razie wszystko względnie dziala kiedy po zalogowaniu n-graczy jest na jednym ekranie (Czyli wszystkich widac na raz).
Mniej wiecej mozna to tak przedstawic:
Jest zalogowanych N graczy. Łączy się klient A. Serwer sprawdza po wszystkich klientach zalogowanych na danej mapie i liczy ze wzoru:
(gdzie x1,y1 = pozycja gracza, x2=y2 = pozycja N-tego gracza na mapie)
Jesli rx lub ry miesci sie w polu widzenia danego gracza to wyslij graczowi A pozycje graczy w polu widzenia, a kazdemu N-temu graczowi ktory miesci sie w polu widzenia wyslij pakiet o pokazaniu sie gracza A na ekranie.
Przy poruszaniu gracza jest analogicznie tzn serwer szuka wszystkich zalogowanych graczy w poblizu i wysyla pakiet o poruszeniu danego gracza. A graczowi ktory sie poruszyl wyslij pakiet z listą graczy w poblizu (j/w).
No i niby dziala. Problem jest kiedy dla przykladu Gracz A jest na pozycji 0,0 a Gracz B na drugim koncu mapy. Gracz B idzie w kierunku Gracza A, i idac w jego kierunku w koncu powinien zobaczyc w rogu ekranu Gracza A. Nie jest tak, uzywajac "algorytmu" takiego jak opisalem. Klient albo w ogole sie nie pokazuje albo zle sie synchronizuja pozycje.
Choc logicznie myslac powinno być wszystko ok dla każdego przypadku :/ Ma ktos doswiadczenie w pisaniu takich rzeczy?
Tutaj kawałek kodu serwera:
function playersNear($hclient) {
global $clients;
$list=array();
for ($i=0;$i<count($clients);$i++) {
if (($clients[$i]->sock != NULL)&&($clients[$i]->loggedin)&&($clients[$i]->InGame)&&($i != $hclient)&&($clients[$hclient]->character["location"]==$clients[$i]->character["location"])) {
$x1=$clients[$hclient]->character["x"];
$y1=$clients[$hclient]->character["y"];
$x2=$clients[$i]->character["x"];
$y2=$clients[$i]->character["y"];
$rx=abs($x1-$x2);
$ry=abs($y1-$y2);
if (($rx<=11)&&($ry<=11)) {
echo($clients[$hclient]->character["name"]." widzi ".$clients[$i]->character["name"]." $x1 $y1 $x2 $y2 [$rx $ry]\n");
$list[]=array($i,$clients[$i]);
}
}
}
return $list;
}
//Tak, serwer pisze w PHP. A klienta w Delphi.
playersNear jest wywolywana przy poruszaniu/polaczeniu nowego klienta/itp. Wydaje mi sie ze powinienem to zrobic zupełnie inaczej... Kazdy klient po zalogowaniu powinien trafic na odpowiednie miejsce w komórkach mapy, i playersNear powinien lecieć w pętli od X-10 do X+10, Y-10 do Y+10...
Nie mam juz zielonego pojęcia. Zgłupiałem. Moze mi to ktos łopatologicznie wytlumaczyc jak to powinienem zrobic wszystko?