Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [mysql/php] gra i czasowe dodawanie
Forum PHP.pl > Forum > Bazy danych > MySQL
empuszek
pisze gre w php i mysql i chcialbym poznac najprostrzy sposob rozwiazania mojego problemu:

otoz chce zeby kazdemu uzytkownikowi co minute dodawala sie jakas wartosc (automatycznie) do danego wiersza w tabeli z danymi
(np. drewno +5 co minute)


sry za chaotyczne pisanie
prosze o szybka odpowiedz
ActivePlayer
musisz uzyc narzędzia 'cron'.
robisz skrypt w phpie, w nim zwykłe zapytanie
update ... drewno = drewno + 5
a cronem stawiasz by uruchamiał co 5 minut ten skrypt, i po problemie.
Piniek
tez się nad tym problemem zastanawiałem (tez kiedyś miałem zamiar zrobić grę) i doszedłem do wniosku ze pomysł z cron'em nie jest za bardzo wydajny ponieważ wywoływać ten sam skrypt co 5 minut i znając życie ten skrypt nie będzie zawierał jednego zapytania do bazy doliczając do tego wszystkich userów hmm raczej bym tego nie polecał

Przepraszam ze nie zmiaescilem innego rozwiazania ale jeszcze na nie wpadlem chcialem przedstawic sowje zdanie
pozdrawiam
lord_t
Ja bym to zrobił tak:

Mam zapisane w bazie danych kiedy user ostatnio widział ile ma drewna (czasDrewna) oraz ile wtedy tego drewna miał.
User loguje się 2. raz (tzn chodzi mi o to, że powinien zobaczyć już zaktualizowaną wartość drewna) to sprawdzam czy to 'logowanie' ma miejsce 5 minut lub więcej od czasuDrewna. Jeśli tak to obliczam (nie chce mi się teraz myśleć, ale nie powinno być najmniejszego problemu, żeby to obliczyć) ile powinien mieć tego drewna więcej od czasu kiedy widział je ostatnio. Po obliczeniu aktualizujemy ilość drewna w bazie oraz czas kiedy to było.

PS. Jest tu tylko trochę do przemyślenia z czasem: jeśli np. od ostatniego widzenia drewna do nast. minęło 5min i 12 sek. to zamiast dodawać 5,jakieś_grosze_po_przecinku to wg mnie lepiej dać 5 i do czasu zapisanego w bazie dodać tylko to 5 minut.

PS2. Mam nadzieję, że pomogłem:) Pzdr.
empuszek
Z tym ostatnim widzeniem drewna jest ciezko a dodawane drewno nie będzie sprawiedliwe.
Za dużo kombinujemy. Ale jak robią to w innych grach?? Np. Ogame, plemiona?questionmark.gif

z góry dziękuję

PS. Chciałbym też żeby ilość produkowanego drewna była zależna od poziomu mojego tartaku tongue.gif

Dajcie jakieś rady!
Szczególnie rady Ekspertów
kitol
Rozwiązanie z zapamiętywaniem czasu jest najprostsze, nie obciąża praktycznie bazy. W swoim projekcie używam takiego zapytania:

  1. UPDATE surowce SET
  2. stan_metal =stan_metal +(TIMESTAMPDIFF(SECOND,czas_surowce,NOW())*przyrost_metal),
  3. czas_surowce=NOW();


gdzie: czas_surowce to czas ostatniego "widzenia" surowców
przyrost_metal - przyrost w jednostkach na sekundę

Myślę że analogicznie jest w oGame i innych
empuszek
Jeszcze 2 pytania:

rozumiem ze mam dopisac warunek where z id?

przyrost_metal to kolumna?

czas_surowce ma miec typ Date?

thx za pomoc!
lord_t
Cytat(empuszek @ 31.12.2007, 14:16:31 ) *
Z tym ostatnim widzeniem drewna jest ciezko a dodawane drewno nie będzie sprawiedliwe.[...]


Jak to nie bedzie sprawiedliwie? Wszystko bedzie ok. A co do tego czasu widzenia drewna to nie ma najmniejszego problemu. Wystarczy w kazdym miejscu, gdzie user widzi stan drewna wywoływac funkcję.

A w tej funkcji zrobic to sprawdzanie czy uplynelo to 5 minut, w niej także dodawać drewno (jesli minelo to 5 minut lub więcej) .

A co do uzależnienia ilosci dodawanego drewna w zależności od stanu np. tartaku to tak bym przykładowo zmodyfikował ten wzór:

stan_metal =stan_metal +(TIMESTAMPDIFF(SECOND,czas_surowce,NOW())*(przyrost_metal*(5+poziom_tartaku))) ,....

PS. No widzisz sam, że to moje rozwiazaniejest dobre:)
kitol
przyrost_metal to kolumna. Wartość w niej zapisana jest obliczana ze wzoru który uwzględnia poziom kopalni.
czas_surowce jest typu Date. Wydaje mi się że warunek where nie jest konieczny - stan surowców będzie aktalizowany dla wszystkich graczy. Jedynym ograniczeniem może być różnica czasu wykonywania zapytania dla jednego/wszystkich graczy. Trzeba by to było sprawdzić.
Jeżeli chcesz aby gracze na urlopie nie mieli wydobycia wóczas musisz to umieścić w WHERE
empuszek
Dziękuję, rozwiązaliście mój problem, teraz surowce bdb się dodają i jest git;

PAPA

PS> czas_surowce nie powinien być typu DATETIME? U mnie chodzi na Datetime;
kitol
Racja. Pisząc date miałem na myśli datetime U mnie też działa na timestamp
empuszek
Następny problem:

chce żeby przyrost nie był aż tak duży jak 1drewno/1sek.
przy_metal będzie musiał mieć typ FLOAT
ale stan_metal nie akceptuje ułamkow i sie wiesza.
stan_metal może być float?

Czy w Timestampdiff interwał mozna ustawic na 5 sek?
kitol
Myślę że lepiej jest to zrobić na liczbach całkowitych. stan_metal powinien być nawet BIGINT. Funkcja TIMESTAMPDIFF(SECOND,x,y) zwraca różnicę czasu między dwiema datami w sekundach. Możesz spróbować zmienić SECOND na minuty lub godziny. Ale lepiej jest:
  1. stan_metal =stan_metal +(TIMESTAMPDIFF(SECOND,czas_surowce,NOW())*przyrost_metal/3600)

wówczas przyrost jest w jednostkach na godzinę.
empuszek
jeśli stan_metal to INT lub BIGINT to dodawane do niego ułamki z powstałego przy_metal/3600 zawieszą stan_metal poniewaz INT nie przyjmuje ułamków
kitol
Nie dodawaj ułamków. Zaokrąglaj dodawane wartości do INT. Aby uniknąć gubienia częci ułamkowych można zmodyfikować czas_surowce=NOW() na taki czas w którym podstawiana do stanu wartość była dokładnie równa zaokrąglonej. Można też modyfikować stan jak najrzadziej wystarczy tylko przy logowaniu oraz przy rozbudowaniu kopalni o kolejny poziom. Aby wyświetlić aktualny stan przy odświeżaniu strony użyj wzoru podanego przeze mnie na początku. Odradzałbym użycie typu FLOAT.
empuszek
a jak to zaokrąglić?
sledziu1
Ja też borykałem się z podobnymi problemami przy tworzeniu gry i rozwiązałem to tak, że w każym pliku na początku dołączałem plik update.php.

W pliku update znajdowało się zapytanie które z mysql pobierało czas ostatniej aktualizacji (była to osobna tabela z różnymi pierdołami i tam też to się znajdowało) i potem następowało dodawanie surowca tyle ile potrzeba oraz zmiana daty aktualizacji na NOW(). Działało to tak, że gdy nikogo nie było online liczba surowca się nie zmieniała ale gdy ktoś się pojawił było to na bierząco aktualizowane.
empuszek
heh, o tym to wiem ale jak zaokrąglić liczbę typu float z poziomu MYSQL.....
spójrz do góry
sledziu1
Niewiem jak w mysql ale w php funkcje do zaokrąglania to:

round() - zaokrąglanie normalne
floor() - zaokr. w dół
ceil() - zaokr. w górę

http://dev.mysql.com/doc/refman/5.0/en/mat...-functions.html
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.