W tym wpisie przechodzimy już to implementacji funkcjonalności naszej gry. Stworzymy w bazie danych nową tabelę, która będzie przechowywać statystyki graczy a następnie zajmiemy się systemem dodawania statystyk za złoto w grze. W tym celu napiszemy klasę GameManager, która będzie zawierała metody dotyczące funkcjonalności gry.

Na początku przejdźmy do bazy danych i utwórzmy nową tabelę o nazwie stats. Posłuży ona do przechowywania statystyk. Wygląda ona tak:

tabela statystyk

Możesz kliknąć na powyższy obrazek by go powiększyć. W tabeli przechowujemy:

  • id użytkownika – identyczne jak w tabeli users
  • hp – punkty życia gracza,
  • attack – atak gracza
  • defense – obrona gracza
  • gold – złoto gracza
  • points – punkty gracza

Możemy teraz przejść do klasy ModuleLoader i uzupełnić moduł, który ładuje treść na stronie statystyki:

case 'statystyki':
             $select = DatabaseManager::selectBySQL("SELECT * FROM stats WHERE id={$_SESSION['uid']}");
             foreach($select as $arr) {
                $stats = $arr;
             }

            echo '
                <section class="content statystyki">  	
                    <div class="container">        
                    	 <h2>Statystyki:</h2>         
                         
                         <div class="row">
                            
                            <ul class="ul" id="u_'.$_SESSION['uid'].'">
                                <li><img src="images/punkty.png">Punkty: <span>'.$stats['points'].'</span></li>
                                <li><img src="images/serce.png">Życie: <span>'.$stats['hp'].'</span> <button class="add" name="hp" type="button"><img src="images/dodaj.png"></button></li>
                                <li><img src="images/miecz.png">Atak: <span>'.$stats['attack'].'</span> <button class="add" name="attack" type="button"><img src="images/dodaj.png"></button></li>
                                <li><img src="images/tarcza.png">Obrona: <span>'.$stats['defense'].'</span> <button class="add" name="defense" type="button"><img src="images/dodaj.png"></button></li>
                                <li><img src="images/zloto.png">Złoto: <span id="zloto">'.$stats['gold'].'</span> </li>
                            </ul>
                            <div id="result"></div>
                    	 </div>
                  
                    </div>   
                </section>
            ';
            break;

Powyższy kod tworzy listę, na której wyświetlane są wartości poszczególnych statystyk z bazy danych. W każdym punkcie listy wyświetlany jest odpowiedni obrazek i nazwa statystyki wraz z wartością. W punktach ŻycieAtak oraz Obrona jest przycisk. Klikając na niego będziemy zwiększali tą statystykę.

Przejdźmy teraz do pliku style.css i dodajmy style do tej listy. Na końcu pliku dodaj poniższy kod:

.statystyki ul {
    list-style: none;
    padding-left: 0px;
}

.statystyki ul li > img {
    float: left;
}

.statystyki ul li {
    width: 20%;
    margin: 0 auto;
    margin-top: 20px;
    position: relative;
    font-size: 22px;
}

.statystyki ul li button {
     background: none;
     border: none;
     float: right;
     position: absolute;
     right: -20px;
     bottom: 2px;
}

Style mogą być dowolne. Możesz wykorzystać te lub napisać swoje 🙂

Stwórzmy teraz klasę GameManager, w której metoda updateStats będzie aktualizowała statystyki. W folderze Managers utwórz plik o nazwie GameManager.class.php i wklej do niego poniższy kod:

<?php

class GameManager {
    
    public function updateStats($UID, $STAT) {
        
        if(isset($UID) && isset($STAT)) { 
            
                $select = DatabaseManager::selectBySQL("SELECT * FROM stats WHERE id={$UID}"); 
                foreach($select as $arr) {
                    $stats = $arr;
                }
                $gold_needed = $stats[$STAT] * 2; //potrzebne złoto do podniesienia statystyki
                
                if($gold_needed > $stats['gold']) { //niewystarczająca ilość złota
                    return false;
                    exit;
                }
                
                else {
                    $stats_inc = $stats[$STAT] + 1;
                    $gold_aft = $stats['gold'] - ($stats[$STAT] * 2);
                    $res = DatabaseManager::updateTable("stats", Array(''.$STAT.'' => ''.$stats_inc.'',
                                                                        'gold' => ''.$gold_aft.''),
                                                              Array('id' => ''.$UID.'')); //aktualizacja bazy danych
                    if($res) { 
                        return true;
                    } else {
                        return false; //niepowodzenie, zwracamy false
                    }
                }                                                               
      
        } else {      
            return false; // zwracamy false           
        }       
    }  
}

?>

To cała zawartość pliku GameManages.class.php. Na początku sprawdzane jest czy gracz ma wystarczająco złota by podnieść statystykę na wyższy poziom. Jeśli ma to baza danych zostaje zaktualizowana. Jeśli nie to zwracamy false.

Możemy teraz przejść do pliku wlasny.js i dodać kod jQuery odpowiedzialny za wysłanie żądania. Przed zamykającymi znacznikami }); dodaj poniższy kod:

zmienna = $('.ul').attr('id'); //pobranie id
 
$('.add').on('click', function() {
    var element = $(this);
    var uid = zmienna; //przekazanie do zmiennej uid id użytkownika
    var stat = $(element).attr('name'); //pobranie atrybutu name, który mówi o typie aktualizacji
    var posting = $.post( 'updateStats/', { user: uid, type: stat } ); //wysłanie żądania z parametrami uid i stat
   
    posting.done(function( data ) { //po zakończeniu żądania
        if(data != false){  //dodano statystykę
            var add_stat = parseInt($(element).parent().find('span').text()); //pobranie aktualnej statystyki
            var take_gold = parseInt($('#zloto').text()) - add_stat * 2; //obliczenie wydanego złota
            $(element).parent().find('span').text(add_stat + 1); //aktualizacja poziomu statystyki
            $('#zloto').text(take_gold); //aktualizacja poziomu złota
            $.smkAlert({text:'Pomyślnie dodano punkt!', type:'success'}); //wyświetlenie komunikatu o powodzeniu
        }
        else {
            $.smkAlert({text:'Nie masz wystarczająco złota!', type:'danger'}); //wyświetlenie komunikatu o niepowodzeniu
        }
  });   
 });

Całość zawiera komentarze, które tłumaczą co się dzieje. Korzystamy tutaj w wtyczki Smoke. Możesz ją pobrać z tej strony. Musisz go jeszcze podpiąć w odpowiednim module w klasie ModuleLoader, ale ja to w tym wpisie pominę 🙂

Żądanie zostaje wysłane pod adres updateStats więc stwórzmy teraz plik updateStats.library.php w folderze LIBRARY.

Plik updateStats.library.php:

<?php

if((isset($_POST['user']) && isset($_POST['type']))
                          && ($_POST['type'] == 'hp' ||
                              $_POST['type'] == 'attack' ||
                              $_POST['type'] == 'defense')
                          ) {
    
   $um = new GameManager;
      
      $id = ltrim($_POST['user'], 'u_'); //uzyskanie numeru id
      $res = $um->updateStats($id, $_POST['type']); //przesłanie argumentów do metody updateStats w klasie GameManager
      
      if($res) { //powodzenie
          echo "success";
          exit;
      } else {     
          return false;    
      }
 
    
} else {
    die("DOSTĘP DO TEJ STRONY ZOSTAŁ ZABLOKOWANY!"); //wejście poza formularzem
}

?>

Plik jest bardzo podobny do register.library.php. Dodajmy jeszcze ścieżkę do niego w klasie MainPage. Pod ostatnim case dodaj poniższy kod:

case 'updateStats':
            require_once $this->active_page.".library.php";
            break;

Od teraz zapytanie już działa. Musimy teraz jeszcze uzupełnić metodę CreateUser w klasie UserManager. W tym momencie rejestrujący się użytkownik nie tworzyłby rekordu w tablicy stats. Dopasujmy więc kod. Metoda CreateUser wygląda teraz tak:

public function CreateUser($POST) { //rejestracja użytkownika
        
        if(isset($POST) && is_array($POST)) { //sprawdzenie czy została przesłana tablica i czy jest tablicą
            
            
            $res = DatabaseManager::insertInto("users", array("username"=>addslashes($POST['username']), 
                                               "password"=>md5($POST['password']), "email"=>addslashes($POST['email']))); //dodanie użytkownika do bazy danych
            
            $res2 = DatabaseManager::insertInto("stats", array(
                                                "hp"=>100, 
                                                "attack"=>20,
                                                "defense"=>10,
                                                "gold"=>200,
                                                "points"=>0,
                                                )); //dodanie statystyk użytkownika do bazy danych                                   
                                               
            if($res && $res2) { 
                return true; //powodzenie, zwracamy true
            } else {
                return false; //niepowoedzenie, zwracamy false
            }
            
        } else {
            
            return false; // zwracamy false
            
        }       
    }

Dodane zostało zapytanie do bazy danych, które dodaje rekord w tablicy stats.

I to wszystko. Dodawanie statystyk już działa 🙂

Paczkę możesz pobrać tutaj.

Gotowy przykład możesz zobaczyć tutaj.

  • Filip Sutkowy

    Ktoś tu się obijał na bazach danych. Wiara w zachowanie spójności przy dwóch tabelach z a_i jest skazana na niepowodzenie. Tabele trzeba po ludzku połączyć kluczem obcym.