Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Mapa gry przeglądarkowej - dyskusja.
h3xed
post
Post #1





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


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ł (IMG:style_emoticons/default/smile.gif)

Zapraszam do dyskusji !

Ten post edytował h3xed 30.01.2012, 15:10:57
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 18)
wookieb
post
Post #2





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




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)
Go to the top of the page
+Quote Post
Sephirus
post
Post #3





Grupa: Zarejestrowani
Postów: 1 527
Pomógł: 438
Dołączył: 28.06.2011
Skąd: Warszawa

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/smile.gif)


Go to the top of the page
+Quote Post
ShadowD
post
Post #4





Grupa: Zarejestrowani
Postów: 1 333
Pomógł: 137
Dołączył: 25.03.2008
Skąd: jesteś??

Ostrzeżenie: (0%)
-----


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ę.

Ten post edytował ShadowD 30.01.2012, 10:58:50
Go to the top of the page
+Quote Post
Niktoś
post
Post #5





Grupa: Zarejestrowani
Postów: 1 195
Pomógł: 109
Dołączył: 3.11.2011

Ostrzeżenie: (10%)
X----


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ń.
Go to the top of the page
+Quote Post
phpion
post
Post #6





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




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.
Go to the top of the page
+Quote Post
h3xed
post
Post #7





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


Dziękuje za zainteresowanie tematem (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/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 (IMG:style_emoticons/default/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.

Ten post edytował h3xed 30.01.2012, 15:15:11
Go to the top of the page
+Quote Post
wookieb
post
Post #8





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




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ę.
Go to the top of the page
+Quote Post
h3xed
post
Post #9





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
wookieb
post
Post #10





Grupa: Moderatorzy
Postów: 8 989
Pomógł: 1550
Dołączył: 8.08.2008
Skąd: Słupsk/Gdańsk




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.
Go to the top of the page
+Quote Post
h3xed
post
Post #11





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/wink.gif)

Ten post edytował h3xed 30.01.2012, 13:32:44
Go to the top of the page
+Quote Post
#luq
post
Post #12





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
h3xed
post
Post #13





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


@luq

Dzięki za link i uwagi, na pewno się przydadzą (IMG:style_emoticons/default/smile.gif)

Czy masz jakieś doświadczenie nt. przechowywania mapy w sql ? Jak tak, czy płynnie wczytuje Ci się mapa z sql ?

Ten post edytował h3xed 30.01.2012, 15:13:57
Go to the top of the page
+Quote Post
Niktoś
post
Post #14





Grupa: Zarejestrowani
Postów: 1 195
Pomógł: 109
Dołączył: 3.11.2011

Ostrzeżenie: (10%)
X----


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.

Ten post edytował Niktoś 30.01.2012, 15:19:19
Go to the top of the page
+Quote Post
h3xed
post
Post #15





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/smile.gif)

Ten post edytował h3xed 30.01.2012, 15:23:09
Go to the top of the page
+Quote Post
#luq
post
Post #16





Grupa: Zarejestrowani
Postów: 589
Pomógł: 91
Dołączył: 22.05.2008
Skąd: Gliwice

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/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".

Ten post edytował #luq 31.01.2012, 00:09:01
Go to the top of the page
+Quote Post
h3xed
post
Post #17





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
Rysh
post
Post #18





Grupa: Zarejestrowani
Postów: 821
Pomógł: 111
Dołączył: 11.09.2006
Skąd: Biała Podlaska

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
h3xed
post
Post #19





Grupa: Zarejestrowani
Postów: 21
Pomógł: 7
Dołączył: 30.01.2012

Ostrzeżenie: (0%)
-----


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 (IMG:style_emoticons/default/wink.gif)

Ten post edytował h3xed 17.04.2012, 14:03:18
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 23.08.2025 - 18:52