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:
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 Życie, Atak 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.
Dzięki
Nie ma sprawy! 🙂
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.