Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP][MySQL] Jak rozmieszczać "potwory"
Forum PHP.pl > Forum > PHP
ols1994
Pisząc grę RPG natknąłem się na przeszkodę w postaci rozmieszczenia potworów na mapie. Wiadomo mapa nie jest duża i mogłoby być od kilku do kilkunastu potworów na jednym polu. Zastanawia mnie tylko możliwość jak to zrobić. Widzę jedno wyjście:
1) Nowa tabela w bazie danych z potworami, na każdym polu. Jednak przy mapce z 625 rekordami niech będzie min 10 potworów na jedno pole(rekord) to już jest 6250 potworów na całą mapę. Później gdybym robił nowe mapy to byłoby jeszcze więcej. Ciągłe operacje na bazie przez graczy też raczej nie byłyby optymalnym wyjściem.

Chciałbym również żeby pokonane potwory znikały a po jakimś czasie dochodziły nowe. I tak wkoło... Macie jakieś pomysły? Czy jest coś lepszego od używania bazy danych tak jak to wyżej przedstawiłem?
Pozdrawiam
DiH
Cytat
Jednak przy mapce z 625 rekordami niech będzie min 10 potworów na jedno pole(rekord) to już jest 6250 potworów na całą mapę.

Torchę tego nie rozumiem, ale mogę za to powiedzieć jak ja bym to zrobił. Ma to być gra na przeglądarkę, czy będzie miała jakiegoś klienta? Zakładam, że przeglądarkowa.


Zależy, czy gra będzie zbudowana w ten sposób, że tą samą mapę może przmierzać kilku graczy na raz, czy jeden. Jeżeli jeden, to sprawa jest dość prosta. Na początku, przy ładowaniu mapy, pobierasz po prostu wszystkie pozycje potworów na mapie, tak by po przejściu do nowego sektora nic z bazy nie pobierać (bo zakładam, że mapa będzie większa niż część widzialna). Po zabiciu potwora wystarczy wtedy ajaxem wysłać do bazy info do tabelki odpowiedzialnej za rozmieszczenie monstrów na mapie, dodając przy tym czas kiedy został zabity. W sesji możesz przechowywać godzinę i np. co 10 minut robić respawn zabitych potworów, co spowoduje po prostu wczytanie potworów na mapę od nowa (oczywiście tylko tylko tych, które już odpowiednio długo nie żyją.

Natomiast, jeżeli chcesz, aby w grę mogło grać kilku graczy jednocześnie, to sprawa odrobinę się komplikuje. Zakładająć, że online jest np. 3 graczy i każdy znajduje się w innym sektorze mapy można by to zrobić tak:
- Zabicie potwora nadal powoduje wysłanie ajaxem update do bazy
- Przy zmianie sektora mapy przez gracza trzeba sprawdzić czy ktoś inny nie znajduje się w sektorze na który wchodzi. Jeżeli tak, to reload pozycji potworów (ponieważ inny gracz mógł w tym sektorze jakieś zabić). Tu dodatkowo musi być sprawdzony ostatni punkt wersji dla jednego gracza, czyli kiedy i jakie potwory mają mieć respawn.

Edit: nie tylko czy gracz jest w danym sektorze, ale także czy był. Alternatywnie przejście do nowego sektora także powinno powodować update zabitych potworów
ols1994
Robię tak że na mapie może być największa możliwa liczba graczy(przy jakimś level up'ie przechodzą na inną). Tak naprawdę ajaxem się jeszcze nie posługuje więc tego raczej nie zrobię. Mapa również w obecnej chwili nie jest "płynna" jednak to poprawię jak zagłębie się w tajniki ajaxa.

A taka opcja jest dobra?
- Tworząc mapę, dodaję również do tabeli z potworami rekordy(10 potworów na jedno pole na mapie = 6250 potworów na całej mapie) gdy gracz wejdzie na pole pobieram żywe lub te monsterki gdzie czas zgonu(czas zgonu+5min) >= czasu aktualnemu.
To jest najlepsza możliwość?
Oczywiście DiH Twój post dał mi do myślenia smile.gif
DiH
Nie taki AJAX straszny. Używając jQuery jest to naprawdę góra paręnaście linijek kodu (jeżeli chodzi o sam AJAX oczywiście). Jeżeli już coś robimy, to róbmy to dobrze.
Cytat
- Tworząc mapę, dodaję również do tabeli z potworami rekordy(10 potworów na jedno pole na mapie = 6250 potworów na całej mapie) gdy gracz wejdzie na pole pobieram żywe lub te monsterki gdzie czas zgonu(czas zgonu+5min) >= czasu aktualnemu.

Wydaje się, że tak właśnie powinno się to odbywać. Jeżeli liczba graczy będzie naprawdę duża, to na pewno zdarzy się taka sytacja, kiedy powiedzmy 3 lub 4 graczy znajdzie się w jednym sektorze mapy. Co wtedy? Poruszają się cały czas po jednym i tym samym miejscu, więc reload potworów po zmianie sektora nie zadziała. Myślę, że wtedy konieczne będzie jedno zapytanie ajaxem, które wyśle info do bazy o po każdym zabitym potworze (lub grupie potworów), oraz drugie, które będzie sprawdzało, czy coś w danym sektorze się zmieniło. Jeżeli tak, to reload mapy dla każdego gracza. Wymagałoby to oczywiście jakiegoś timera, który co jakiś czas będzie owo zapytanie do bazy wysyłał.

Żeby nie zjeść dużo transferu, mógłbyś pokusić się o stworzenie kodów odpowiedzi. Np. wysyłasz ajaxem do bazy zapytanie czy coś się zmieniło. Jeżeli tak, to trzymujesz 1, jeżeli bez zmian to 0.
Crozin
@DiH: To co opisałeś to najlepsza droga do nadużyć. Wszelkie akcje, które mają wpływ na świat gry wykonywane są na serwerze.

O tym czy użytkownik przesunie się w lewo decyduje serwer, o tym czy pocisk poleci w prawo czy w lewo również decyduje serwer. To czy potwór został zraniony czy nie również należy do kompetencji serwera. Klient jedyne co robi to wysyła do serwera prośby o możliwość wykonania danej akcji (ruch, strzał itp. itd.) i dopiero gdy serwer zezwoli na taką akcję gracz się porusza czy strzela.

Generalnie jeżeli to ma być gra czasu rzeczywistego dla wielu osób to robienie jej na chwilę obecną w przeglądarce jest złym pomysłem. To środowisko się jeszcze nie nadaje do takich zastosowań.
DiH
Cytat
@DiH: To co opisałeś to najlepsza droga do nadużyć. Wszelkie akcje, które mają wpływ na świat gry wykonywane są na serwerze.

Jakie zatem podasz rozwiązanie tego problemu? To, że nie powinno się tego robić w przeglądarce, cóż, prawda ale skoro ma chłopak chęć do pracy to niech działa. Możesz zarzucić mi brak doświadczenia na tym polu, ale naprawdę nie widzę innego rozwiązania, które nie wymagałoby przeniesienia gry poza czysty javascript i php/mysql.
ols1994
Jest taka gra jak: kosmiczni.pl tam jest ajaxowa mapa plus potwory na każdym polu. Ta gra jest już spory czas w sieci i z tego co widać nieźle działa.
Crozin
@DiH: Powiedzmy, że chcesz strzelić z jakiejś broni. Klikasz "strzał" i cała machina do obsługi tego rusza:
1. Klient wychwytuje zdarzenie i rozpoczyna się jego obsługa.
2. Do serwera wysyłana jest informacja o tym, że gracz wcisnął strzał.
3. Serwer (po sprawdzeniu czy do takiej akcji może w ogóle dojść - gracz musi mieć wystarczająco amunicji) wysyła informację zwrotną do klienta w stylu "ok, możesz strzelać".
4. Serwer wysyła do wszystkich graczy - którzy w tym przypadku znajdują się wystarczająco blisko miejsca akcji - trochę informacji o nowym obiekcie - naboju. W tym przypadku będą to informacje o tym jaki to obiekt i jaki jest jego wektor ruchu.
5. Klient każdego z graczy renderuje wszystkie animacje.
6. Po upływie sekundy pocisk dociera do celu - jakiegoś potworka.
7. Serwer po sprawdzeniu czy wszystko się zgadza decyduje o tym czy pocisk trafił cel i jeżeli tak to jakie zadał obrażenia, czy potwór zginął itp.
8. Informacje o trafieniu wędrują do wszystkich klientów, którzy są odpowiednio blisko miejsca akcji.
9. Po stronie użytkownika renderowana są animacje.

Tak naprawdę jest to jeszcze nieco bardziej skomplikowane, bo z reguły jest tak, że klient - by polepszyć wrażenia użytkownika - rozpoczyna renderowanie pewnych rzeczy jeszcze zanim otrzyma informacje zwrotną z serwera, później jeżeli jest taka potrzeba synchronizuje to co już wyświetla z tym co otrzymał z serwera.

Generalnie - jeżeli to ma być gra czasu rzeczywistego przez sieć to trzeba naprawdę w cholerę niezbyt ciekawych problemów rozwiązać. A praca w środowisku jakim jest przeglądarka dodaje jedynie nowych problemów.
DiH
Wybacz, o rozwiązanie nie tego problemu mi chodziło. Miałem na myśli obsługę mapy. Ale co do samego strzału, to myślę, że da się to w dużej mierze uprościć:
Cytat
1. Klient wychwytuje zdarzenie i rozpoczyna się jego obsługa.
2. Do serwera wysyłana jest informacja o tym, że gracz wcisnął strzał.
3. Serwer (po sprawdzeniu czy do takiej akcji może w ogóle dojść - gracz musi mieć wystarczająco amunicji) wysyła informację zwrotną do klienta w stylu "ok, możesz strzelać".
4. Serwer wysyła do wszystkich graczy - którzy w tym przypadku znajdują się wystarczająco blisko miejsca akcji - trochę informacji o nowym obiekcie - naboju. W tym przypadku będą to informacje o tym jaki to obiekt i jaki jest jego wektor ruchu.
5. Klient każdego z graczy renderuje wszystkie animacje.
6. Po upływie sekundy pocisk dociera do celu - jakiegoś potworka.

Nie wiem jak skomplikowana będzie gra ols1994, ale nie porywajmy się z motyką na słońce. Jak sam wspomniałeś, przeglądarka to niezbyt ciekawe miejsce na tego typu ewolucje, dlatego pójdźmy po najmniejszej linii oporu.
1. Wciśnięcie strzału będzie owocowało zapytaniem do bazy. Każdy gracz ma określoną siłę strzału.
2. Po co wysyłać ruch pocisku, a raczej informację o tym do innych graczy? Zakładamy, że to prosta gra, nie mogą więc "nadziać" się na zbłąkaną strzałę, czy pocisk. Również sama animacja w tym przypadku jest zbędna. Można by to rozwiązać tak jak w Heroes of Might and Magic, czyli widzimy się na mapie tylko chodząc, a walka toczy się w zupełnie innej perspektywie i środowisku.
Cytat
7. Serwer po sprawdzeniu czy wszystko się zgadza decyduje o tym czy pocisk trafił cel i jeżeli tak to jakie zadał obrażenia, czy potwór zginął itp.
8. Informacje o trafieniu wędrują do wszystkich klientów, którzy są odpowiednio blisko miejsca akcji.
9. Po stronie użytkownika renderowana są animacje.

3. Naciśnięcie przycisku strzału wysłało zapytanie do bazy, teraz samo php generuje losowo celność i obrażenia tegoż strzału z użyciem danych o sile rażenia gracza. pkt. 8 i 9 odpada, bo mamy od tego inne środowisko.

Absolutnie nie twierdzę, że nie masz racji. Mamy po prostu w głowach gry o zupełnie innym stopniu zaawansowania.
Crozin
@DiH: To tylko podstawy tego typu aplikacji. Pójściem po najmniejszej linii oporu byłoby skorzystanie i dostosowanie gotowego narzędzia, a nie omijanie podstawowych problemów. Niezbyt wygodne środowisko to również nie pretekst do jakiś dziwnych "uproszczeń". Wygląda jednak na to, że myślimy o zupełnie innych rzeczach. Dopóki autor nie doprecyzuje dokładnie czego oczekuje od gry wszystkie te rozważania można sobie o ... rozbić. wink.gif
ols1994
Hmm... Nie oczekuje niczego nadzwyczajnego. Będzie to prosta gra. Chodzisz po mapie walczysz z innymi graczami, potworami, wykonujesz misje, zbierasz doświadczenie. Myśląc teraz tak spokojnie opcja z dodatkową tabelą zawierającego id potwora, poziom, czas ostatniego zgonu, pole x i pole y powinno wystarczyć. Mapa nie będzie pusta jak łąka Microsofta będą na niej budynki, drzewa, kamienie czy woda. Czyli już praktycznie liczba potworków do zabicia się zmniejsza. Wyświetlając potwory bym dał warunek żeby pokazywało potwory gdzie czas zgonu jest mniejszy niż aktualny czas.
Crozin
Czyli jak rozumiem ma to być coś w stylu... Tibii?


Opisałeś co ma być w grze, a teraz podaj nam jak widzisz "działanie" całego świata gry. Tak jak w grze, którą podałem powyżej czy może coś w stylu tych kosmicznych.pl?
lukaskolista
Nie wiem gdzie jest problem, 6250 rekordow to nic.
ols1994
@Crozin:
W stylu kosmiczni.pl
Crozin
Widzę, że w takim razie o coś zupełnie innego Ci chodzi. Myślałem, że za MMORPG chcesz się brać, a tutaj wychodzi na to, że jedynie o pewne elementy RPG chodzi. wink.gif Generalnie przy tak prymitywnym świecie gry* zbyt wielu problemów pewnie nie będzie. Przy każdej zmianie pozycji czy co dwie aktualizuj sobie informacje o świecie gry. Serwer może przechowywać informacje o rozmieszczeniu postaci i przeciwników bezpośrednio w pamięci oraz robić co jakiś czas jej zrzut do bazy zapisującej dane na dysku.

* chociaż przy dzisiejszych standardach nawet po najprostszej grze z serii 4fun spodziewałbym się zdecydowanie więcej do czego też Cię zachęcam.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.