Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Mapa gry przeglądarkowej - dyskusja.
Forum PHP.pl > Inne > Hydepark
h3xed
Witam !

Jako, że dyskusja będzie zawierała w sobie elementy języka php, js, mysql, oraz technologie takie jak ajax nie pasowała do żadnego działu prócz tego.

Od jakiegoś czasu, po pracy, dla przyjemności rozważam stworzenie gry przeglądarkowej. Na razie sam projekt, rozwiązania czysto techniczne. Gra miła by się opierać o grafikę 2D.


W chwili obecnej doszedłem do następujących ustaleń:

Mapa złożona z grafik (pixel art) 32x32 px oparta o współrzędne układu kartezjańskiego, płaszczyzny x, y, z. Gdzie z odpowiada za poziom powierzchni na którym obecnie się znajdujemy.

Okno gry panoramiczne, 30x14 kratek, co daje nam odpowiednio 420 kratek na obraz (licząc jedynie wypełnienie gruntu) oraz wymiary okna 960x448 px.

Mapa zapisana w bazie MySQL o następującej strukturze:


Kod
+-----------+-----------------+--------+-----------+-----------+---------------+
|   Field   |       Type      |  NULL  |    Key    |  Default  |      Extra    |
+-----------+-----------------+--------+-----------+-----------+---------------+
|     x     |     smallint    |   NO   |  PRIM.    |           |               |
|     y     |     smallint    |   NO   |  PRIM.    |           |               |
|     z     |     smallint    |   NO   |  PRIM.    |           |               |
|  item_id  |     smallint    |   NO   |  PRIM.    |           |               |
|   index   |     tinyint     |   NO   |           |     0     |               |
|  step_on  |      bool       |   NO   |           |     0     |               |
+-----------+-----------------+--------+-----------+-----------+---------------+


item_id => id grafiki w danej pozycji
index => z-index dla pozycjonowania wyświetlenia
step_on => 0 bohater nie może wejść na to pole / 1 może wejść na to pole

Dzięki Sephirus-owi mamy pomysł na buforowanie w celu płynności przewijania:

Kod
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOAAAOOO
OOOAAAOOO
OOOAAAOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO


Cytat
Gdzie A to widoczna część - wówczas ten nadmiar "O" pozwala na przewinięcie mapki odrobinę w każdym kierunku bez czekania na doładowanie... jeśli odpowiednio dobierze się szybkość pobierania/generacji mapki i przewijania to można uzyskać płynne przewijanie i brak oczekiwania na ładowanie



I teraz nad czym się zastanawiam:
Jak optymalnie pobrać z bazy wszystkie elementy dla danej pozycji w jednym zapytaniu ?

Oraz logikę pobierania nowego kawałka mapy - czyli jeżeli gracz przesunie się o y->y+1 czyli kratkę do góry to należy pobrać jedynie wiersz 30 kratek na samej górze widocznej przez gracza mapy.


Może ktoś ma doświadczenie w tej materii, albo gdzieś już o tym słyszał smile.gif

Zapraszam do dyskusji !
wookieb
Za Primary Key uznałbym kombinację x,y,z - id w tym przypadku jest całkowicie zbędne i nadmiarowe.
Jeżeli może być więcej niż 1 item na danym polu to trzymałbym je w oddzielnej tabeli. Jednakże wszystko to trzymaj w pamięci (memcache albo najlepiej REDIS to przechowywania zakresów pól)
Sephirus
Co do przewijania to proponuje

pobierać w ten sposób:


Kod
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOAAAOOO
OOOAAAOOO
OOOAAAOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO


Gdzie A to widoczna część - wówczas ten nadmiar "O" pozwala na przewinięcie mapki odrobinę w każdym kierunku bez czekania na doładowanie... jeśli odpowiednio dobierze się szybkość pobierania/generacji mapki i przewijania to można uzyskać płynne przewijanie i brak oczekiwania na ładowanie smile.gif


ShadowD
Ktoś tutaj już pisał mapkę, tylko nie pamiętam kto, ktoś bardziej udzielający się, miał brata i tworzył snake, ale nie pamiętam nicku - poszukaj sobie jego tematu sporo już zrobił i prezentował nawet mini grę. :-)

Edit: bim2 jeśli się nie mylę.
Niktoś
Cytat
Jednakże wszystko to trzymaj w pamięci (memcache albo najlepiej REDIS to przechowywania zakresów pól)

Ja bym zaproponował sql space-przynajmniej mi się na tym bardzo dobrze pracuje.Można łączyć się z aplikacją za pomocą klienta poprzez bezpieczne porty ssl.
REDIS też jest dobry,ale na Linuxy ,na windowsie to jest CYGWIN.Nie jestem zbytni przekonany co do takich rozwiązań.
phpion
Cytat(wookieb @ 30.01.2012, 10:30:52 ) *
Za Primary Key uznałbym kombinację x,y,z - id w tym przypadku jest całkowicie zbędne i nadmiarowe.
Jeżeli może być więcej niż 1 item na danym polu to trzymałbym je w oddzielnej tabeli. Jednakże wszystko to trzymaj w pamięci (memcache albo najlepiej REDIS to przechowywania zakresów pól)

Jeśli na 1 polu może być N obiektów, to jako klucz główny można spokojnie dać x + y + z + item_id. Nie widzę większego sensu rozbijania tego na osobną tabelę. Oczywiście z punktu widzenia normalizacji można się tak bawić (łącząc tabelę zwykłym ID bo przy PK x + y + z mija się to z celem), ale czy jest to konieczne? Nie wydaje mi się. Przy pobieraniu danych z bazy odpada przynajmniej złączenie tabel.
h3xed
Dziękuje za zainteresowanie tematem smile.gif

@wookkieb

id faktycznie jest nadmiarowe, zostanie usunięte.

Natomiast nadanie wspólnego Primary Key dla x,y,z, sprawia pewien problem. Na jednej pozycji może znajdować się kilka elementów oddzielonych polem index (z-index). Np. trawa i drzewo stanowią 2 elementy o z-index 1 oraz dla drzewa z-index 2.

Stworzenie 2 tabel ograniczy nas natomiast do 2 elementów na pozycje.

Rozumiem, że należy trzymać mapę w bazie i wczytywać całość przy starcie serwera do pamięci ?

@Sephirus

Dzięki za pomysł, faktycznie wydaje się zdać swoją role smile.gif

@Niktoś

Czym różni się sql space od REDISA, że będzie odpowiedniejszy ?

Oczywiście omawiany projekt będzie pracował pod kontrolą pigwina smile.gif

@theard

Wszystkie nowe pomysły będę wprowadzał w pierwszym poście aby panował porządek.

Edit:

Cytat
Jeśli na 1 polu może być N obiektów, to jako klucz główny można spokojnie dać x + y + z + item_id. Nie widzę większego sensu rozbijania tego na osobną tabelę. Oczywiście z punktu widzenia normalizacji można się tak bawić (łącząc tabelę zwykłym ID bo przy PK x + y + z mija się to z celem), ale czy jest to konieczne? Nie wydaje mi się. Przy pobieraniu danych z bazy odpada przynajmniej złączenie tabel.


Myślę, że to bardzo dobry pomysł, można założyć, że nigdy nie będzie 2 takich samych obiektów na jednej pozycji. Łączenie 2 tabel, myślę opóźniło by znacznie czas wykonania zapytania.
wookieb
Zgodzę się z @phpion. Choć nadal się zastanawiam czy baza danych to odpowiednie miejsce na trzymanie tego typu danych - od tego jest raczej pamięć z możliwością zrzutu na dysk co jakiś czas.
Idealnie w tym przypadku przydałby się program/skrypt działający w tle i obsługujący mapę.
h3xed
Cytat(wookieb @ 30.01.2012, 13:04:03 ) *
Zgodzę się z @phpion. Choć nadal się zastanawiam czy baza danych to odpowiednie miejsce na trzymanie tego typu danych - od tego jest raczej pamięć z możliwością zrzutu na dysk co jakiś czas.
Idealnie w tym przypadku przydałby się program/skrypt działający w tle i obsługujący mapę.


Na pewno przetrzymując mapę w pamięci uzyskujemy szybszy dostęp, ale musimy założyć, że gracz będzie mógł wprowadzać zmiany w mapie, tj. porzucić coś na mapie tak aby inny gracz mógł to znaleźć.

Do tego trzeba będzie robić co jakiś czas backup, tak aby nie utracić zmian podczas awarii/crashu serwera.
wookieb
No więc skoro rzuci coś na mapie to uwzględnisz tą zmianę w pamięci.
Zrzut danych nie jest taki trudny i ciężki. Nawet backup sprzed minuty będzie bardzo dobrym rozwiązaniem.
h3xed
I rozumiem, że damy radę to uzyskać za pomocą REDIS ?

Muszę przyznać, że pierwszy raz o nim słyszę, ale zaraz sobie przybliżę jego temat wink.gif
#luq
Może Ci w jakiś sposób pomogą moje wpisy na blogu

2 rzeczy:

1 - zadbaj o możliwość definiowania po czym można chodzić a po czym nie - np. po trawie będzie można a po wodzie już nie, pytanie czy jeśli na danym polu leży item to czy mogę na niego wejść (zbierając go) czy nie.

2 - co do doładowywania mapy. Pobieraj następny zakres pół kiedy bohater jest na kilka pól od krańca załadowanego obszaru. Usprawnieniem może też być próba przewidzenia gdzie user będzie chciał pójść. tzn. jeśli będziemy

Kod
OOOOOOOOO
OOOOOAAAO
OOOOOAXAO
OOOOOAAAO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO


Gdzie X oznacza pozycje bohatera, i teraz co pobierać jeśli pójdziemy w góre tj.

Kod
OOOOOOOOO
OOOOOAXAO
OOOOOAAAO
OOOOOAAAO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO


Czy pobieramy obszar o tych samych kolumnach co poprzednio?


Kod
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOAXAO
OOOOOAAAO
OOOOOAAAO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO


czy może troche obszaru z góry i trochę z prawej?

Kod
----OOOOOOOO
----OOOOOOOO
----OOOOOOOO
OOOOOOOOOOOO
OOOOOAXAOOOO
OOOOOAAAOOOO
OOOOOAAAOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO
OOOOOOOOO


Bo pobierając zawsze obszar wg. pozycji bohatera będziesz w sporej mierze pobierał pola które już miałeś pobrane wcześniej.
h3xed
@luq

Dzięki za link i uwagi, na pewno się przydadzą smile.gif

Czy masz jakieś doświadczenie nt. przechowywania mapy w sql ? Jak tak, czy płynnie wczytuje Ci się mapa z sql ?
Niktoś
Użyj Redisa pod linuxa będzie idealny,na winde już nie gdyż budowany na cygwinie.

PS.Interesującą opcją w SQLSpace jest sposób połączenia z aplikacją ,można użyć bezpiecznego połączenia ssl.Do gierki raczej nie wiem czy to Tobie będzie potrzebne.Mi się przyjemnie z tym pracuje-zrobiłem na tym koszyczek.
h3xed
Do obsługi mapy SSL jest raczej zbyteczne, nie obawiam się podsłuchiwania połączenia, zwłaszcza, że PHP będzie łączyć się lokalnie z SQLSpace/Redis.

Po powrocie do domu zapoznam się z dokumentacją obu rozwiązań aby móc coś powiedzieć/zapytać. Gdyby ktoś miał doświadczenie z w/w rozwiązaniami prosił bym o wyrażenie swojego zdania smile.gif
#luq
Cytat(h3xed @ 30.01.2012, 15:13:33 ) *
Czy masz jakieś doświadczenie nt. przechowywania mapy w sql ? Jak tak, czy płynnie wczytuje Ci się mapa z sql ?


Ale skąd te pytanie? ;>
Nie kumam dlaczego miałby być to jakiś problem, przecież zapytanie po fragment mapy niczym nie różni się od zapytaniem o fragment (stronę) np. tematów na tym forum smile.gif Cudów nie ma należy jedynie pamiętać o tym że te zapytania będą częste a więc należy zadbać z kilku stron o ich optymalizajce.

1. Dobre rozplanowanie bazy (indexy)
2. Buforowanie danych po stronie przeglądarki (pobieranie większych fragmentów niż widać, doładowywanie przydatnego fragmentu mapy który nie będzie dublował pól już wcześniej pobranych)
3. Minimalne zapytanie SQL, a kiedy będzie trzeba to operacje jeśli chodzi o pobieranie dobrego fragmentu mapy przerzucić na PHP a nie liczyć tego w samym MySQL
4. Cachowanie wyników zapytań.

Aha bo zapomniałem wcześniej zadać to pytanie.
W jakim celu w bazię jest pole "z"? Mapa 2d a więc 2 wymiary x, y. Jedynie co mi przychodzi do głowy to jedynie z-index ale do tego masz pole "index".
h3xed
Cytat(#luq @ 31.01.2012, 00:06:29 ) *
Aha bo zapomniałem wcześniej zadać to pytanie.
W jakim celu w bazię jest pole "z"? Mapa 2d a więc 2 wymiary x, y. Jedynie co mi przychodzi do głowy to jedynie z-index ale do tego masz pole "index".


Pole 'z' określa poziom mapy, 7 to powierzchniom, 6 jeden poziom pod powierzchniom, 8 jeden nad itd.
Rysh
Ostatnio też właśnie rozmyślam nad wydajnością samej mapy.
Tylko w moim założeniu moja mapa posiada wymiary:
Y: -100x100
X: -100x100
Czyli razem ponad 40 401 pól.

Dziś naszła mnie myśl, aby pobierać wszystkie rekordy z bazy danych raz na 5 minut, a następnie wrzucić je do cache. Przy każdym przeładowaniu mapy wystarczyło by pobrać te rekordy które zmieniły się od czasu wrzucenia danych do cache, będą to drobne zmiany czasem.

Tylko nachodzi mnie też pytanie czy nie lepiej zamiast cache użyć przykładowo $_SESSION?

Mam nadzieję, że autor tematu nie obrazi się że się doczepiłem do tematu.
h3xed
Cytat(Rysh @ 15.03.2012, 17:43:02 ) *
Tylko nachodzi mnie też pytanie czy nie lepiej zamiast cache użyć przykładowo $_SESSION?


Cache robisz jeden dla wszystkich. Natomiast sesja jest z osobna tworzona dla każdego połączenia, więc przetrzymywanie w sesji mija się z celem.

Cytat
Mam nadzieję, że autor tematu nie obrazi się że się doczepiłem do tematu.


Jest to otwarta dyskusja, jak najbardziej zapraszam wszystkich do przestawiania swoich myśli wink.gif
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.