To już ostatnia część serii „Tworzenie gry przeglądarkowej”. Napiszemy bardzo prosty ranking, w którym gracze zostaną posortowani według liczby punktów. Zaczynajmy 🙂

Pierwszą rzeczą jaką zrobimy będzie całkowite wyczyszczenie wszystkich tabel. W dalszej części zmienimy nieco szyfrowanie haseł. Musimy to zrobić ponieważ hasła, które są w tym momencie szyfrowane algorytmem md5 nie będą później działać. Prostym sposobem na opróżnienie tabel jest zaznaczenie ich i wybranie opcji Opróżnij.

oproznij tabele

Po kliknięciu na Opróżnij potwierdzamy opróżnienie tabel.

Przejdźmy teraz do klasy ModuleLoader i uzupełnijmy treść strony Ranking. Zdecydowałem wykorzystać w tym celu metodę loadUserList, którą wykorzystywaliśmy już w trakcie tworzenia strony Walka. Musimy ją trochę zmodyfikować (nie chcemy wyświetlać przycisków Zaatakuj). Jeśli chcesz to możesz to zrobić tworząc osobną metodę.

Najpierw modyfikujemy metodę loadUserList:

static public function loadUserList($uid, $username, $points, $button, $rank) {
            echo '<li>';
                if($rank) {
                    echo $rank.'. ';
                }
                echo $username.' ('.$points.' pkt.)';
                if($button) {
                  echo '<button type="button" class="attack" name="'.$uid.'">Zaatakuj</button>';
                }
                echo '</li>';
}

Do metody dodałem dwa nowe parametry. Jest to $button, który przyjmuje wartości true (jeśli wyświetlamy przycisk) lub false (jeśli go nie wyświetlamy) oraz $rank który odpowiada za wyświetlanie pozycji na liście.

Aby wszystko działało jak wcześniej musimy na chwilę wrócić do case walka i dodać brakujące parametry.

ModuleLoader::loadUserList($user['id'], $username, $user['points'], true, false);

Jest to jedyna linia, którą zmieniamy. Dodajemy możliwość wyświetlania przycisku i wyłączamy numerację. Wszystko będzie działało jak dawniej.

Teraz możemy przejść do case ranking i dodać kod odpowiedzialny za wyświetlenie rankingu.

case 'ranking':
            echo '
                <section class="content ranking">
                    <div class="container">
                    	 <h2>Ranking:</h2>

                         <div class="row">

                         <div class="col-xs-10 col-sm-6 col-md-6 col-lg-4 col-lg-offset-4 col-md-offset-3 col-sm-offset-3 col-xs-offset-1">
                          <ul class="user_list">
                          ';

                   $select_users = DatabaseManager::selectBySQL("SELECT * FROM stats ORDER BY points desc");

                             if($select_users) {
                                $i = 1;
                                 foreach($select_users as $user) {
                                  $username = UserManager::getUsernameById($user['id']);
                                  ModuleLoader::loadUserList($user['id'], $username, $user['points'], false, $i);
                                  $i++;
                                 }
                             }

                  echo ' </ul></div></div>

                    </div>
                </section>
            ';
break;

Ten case jest bardzo podobny do poprzedniego. Różni się zapytaniem do bazy (które od razu sortuje wyniki), brakiem buttona oraz numeracją. Korzystamy z wcześniej już zdefiniowanych stylów. W pliku style.css nadpiszmy jedną regułę:

.ranking .user_list li {
	text-align: center;
}

To wszystko, ranking będzie już działał.

Zajmiemy się teraz zmianą algorytmy szyfrującego, o którym wspominałem na początku. W tym celu przejdźmy do klasy UserManager i zmodyfikujmy metodę CreateUser. Zmodyfikujemy tylko pierwsze zapytanie:

$res = DatabaseManager::insertInto("users", array("username"=>addslashes($POST['username']), 
                                                              "password"=>password_hash($POST['password'], PASSWORD_BCRYPT),
                                                              "email"=>addslashes($POST['email']))); //dodanie użytkownika do bazy danych

Zamiast funkcji md5 używamy tutaj password_hash. To jedyna zmiana w tej metodzie, którą musimy przeprowadzić.

W tym miejscu warto się zastanowić czy nasza tabela users nadal jest przystosowana do przechowywania danych użytkownika. Algorytm md5 generuje 128 bitowy ciąg (32 znaki). Do tej długości ograniczyliśmy pole password w tabeli users. Funkcja password_hash generuje zawsze ciąg o długości 60 znaków. Musimy zatem wprowadzić drobną poprawkę w ustawieniach pola password.

W widoku tabeli wybierz opcję Zmień, która znajduje się w kolumnie Działanie. Następnie zmień ustawienia:

ustawienia hasla

Ta drobna zmiana wystarczy by hasła były zapisywane poprawnie. Nadal jednak podczas logowania sprawdzane jest hasło jakby było zakodowane w md5. Aby to zmienić wróćmy do metody isExist aby zmienić weryfikację użytkownika:

protected function isExist() { //sprawdzenie czy użytkownik o podanej kombinacji nazwy i hasła istnieje
        
        $arr = DatabaseManager::selectBySQL("SELECT * FROM users WHERE username='".$this->login."' LIMIT 1");
        
        if($arr) {
            foreach($arr as $row) {
                if(password_verify($this->password, $row['password'])){
                   return $arr; //zwrócenie tablicy 
                } else {
                    return false;
                }
            }
        } 
   
}

Po pierwsze – zmieniamy zapytanie do bazy. Teraz wybieramy tylko rekord, w którym występuje podana nazwa użytkownika. Jeśli rekord zostanie znaleziony to przy pomocy funkcji password_verify weryfikujemy podane hasło. Funkcja zwróci true jeśli hasło będzie się zgadzało. W tym przypadku zwracamy tablicę. W przeciwnym wypadku zwracamy false.

W tym momencie wszystko będzie już działało.

Zbliżamy się już do końca tego poradnika. Jeśli dobrnąłeś/aś do tego momentu – gratuluję.

W ciągu dwóch miesięcy napisaliśmy kompletną grę przeglądarkową. Jest prosta, ale napisaliśmy ją od zera. Zachęcam Cię abyś przy pomocy zdobytej wiedzy napisał kolejną grę lub rozbudował tą. Będzie to świetna okazja do utrwalenia wiedzy.

Mam nadzieję, że poradnik czytało Ci się tak dobrze jak mi się go pisało.

Do zobaczenia w kolejnych wpisach! 🙂

Przykład możesz zobaczyć tutaj.

Paczkę możesz pobrać tutaj.

  • marcin

    Pomoze ktos ?? mam nadzieje ze ktos tu szybko zajrzy 😀

    pobralem paczke cała , ale przy odpaleniu go juz na przegladarce , mam problem z polaczeniem z baza , na poczatku moglem sie zalogowac, ale prz yzalogowaniu nie pobralo mi statystyk gracza hp pkt itd , no i listy graczy z rankingu , no i probowalem poszukac bledu bez skutku , do tego teraz nie moge sie nawet zalogowac i zarejestrowac nowego uzytkownika , probowalem z samym rejestracja uzytkownikow , i non stop bez zmian to samo przy logowaniu , w bazie sa dane , ale nie wyszukuje z bazy …

    z localhost / gra sie laduje ale do bazy ciezko dojsc ;(

    podpowie ktos co musze zrobic ?? problem mam z kompem , czy jak ?? pliki wszystko to samo co tu z paczki a nie moge nic zdzialac ;/ probowalem sie laczyc z baza nie tylko z tje paczki co tu pobralem , ale nadal to samo jest ;/;/ wszystko co potrzeba z polaczeniem z baza , wsio jest dobrze wpisywane, mimo to jest jakis blad ;(

    pomocy 😉

  • Wojciech Piwowarski

    Mam problem z przesłaniem danych metodą $_GET mianowicie kiedy dołączam do adresu zmienną to skrypt jej nie czyta np …gra/statystyki?id=1 gra to jest folder główny strony, plik htaccess jest identyczny jak z tego przykładu

  • Jan Nowak

    Na WAMP’ie wszystko działa, tylko mam problem ze zmuszeniem tego do pracy na VPSie z zainstalowanym ‚apache2’ na ubuntu 16.04.

    włączyłem, mod_rewrite (‚sudo a2enmod rewrite’) oraz zrestartowałem usługę (‚service apache2 restart’).
    Po czym w pliku ‚000-default.conf’ dodałem następującą regułkę:

    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Require all granted

    coś pominąłem ? a może coś źle zrobiłem ?

  • Patryk Iksde

    Nie mogłem poradzić sobie z loginem i rejestracją, ponieważ po próbie logowania przekierowywało mnie na stronę główną i pokazywała sie tabela główna. STwierdziłęm więc że pobiorę paczkę z ostatniego odcinka i poprostu pozmieniam detale. Nie rozumiem tylko dlaczego nawet w końcowej paczce gdy próbuje się zalogować jest ten sam błąd! POMOCY!

    • Bartłomiej Mąkina

      Sama paczka z plikami nie wystarczy. Musisz jeszcze utworzyć odpowiednie tabele w bazie danych. Zrobiłeś to już?

  • dervil

    W twoim kursie gry jest

    class MainPage {

    private $active_page;

    public function __construct($ACTIVE_PAGE) {

    $this->active_page = $ACTIVE_PAGE;

    switch($this->active_page) {

    case ‚home’:

    require_once $this->active_page.”.library.php”;

    break;

    } } }

    i ustawiasz każdą stronę tak jak tą home

    a jak wyciągnąć/pobrać zmienne jeżeli chciałbym przesyłać zmienne metodą GET w linku

    np: http://strona.pl/home?zmienna1=100&zmienna200=2&zmienna3=300

    normalnie byłoby

    $zmienna1 = $_GET[‚zmienna1’];

    $zmienna2 = $_GET[‚zmienna2’];

    $zmienna3 = $_GET[‚zmienna3’];

    ale gdy są klasy to wyskakuje błąd bo jest to

    $mp = new MainPage($_GET[‚page’]);
    no i w pliku .htcacces $1

  • dervil

    świetne, ale przydałaby się weryfikacja formularza rejestracyjnego
    pozdrawiam 😉

  • Krzysiek

    Dzięki za serie!