Systeme de progression pour membre

Petit nouveau ! | 6 Messages

23 déc. 2012, 12:45

Bonjour,
Je rencontre quelques difficultés dans la création de mon systeme de niveau pour mes membres.
Mon système se compose du niveau du membre , d'une barre d'experience et de l'affichage des points à atteindre en dessous de celle ci ( du style 500/1000 ).
Pour mon niveau 1 tous fonctionne ma barre d'experience évolue en fonction de mes actions et mes points en dessous évolue aussi.
Le probleme que je rencontre est lorsque je passe au niveau 2 ...
En effet il faut donc que la barre de progression reparte à zéro , et que mon maximum de point ( correspond a 1000 dans l'exemple ci dessus ) s'incremente de 1.5.
Le probleme est donc que lorsque je passe au niveau 2 ma barre de progression n'evolue plus et mon systeme de point non plus, ma valeur max s'increment bien de 1.5 mais ensuite si je fais encore une fois depasser mon nombre de points par rapport au points maximum pour passer au niveau 3 il ne s'incremente plus.
<?php
session_start();
if(empty($_SESSION['membre']))
{
  header('Location: index.php');
}
$nom = $_SESSION['membre'];


require("php/connection.php");

$req = $bdd->prepare('SELECT * FROM membre WHERE login=:login');
$req->execute(array('login'=>$_SESSION['membre']));
$data = $req->fetch();
$req->closeCursor();

$experience = $data['experience'];
$experienceMax = $data['experienceMax'];
$niveau = $data['niveau'];

$barreExperience = (($experience/$experienceMax)*100);

if(!empty($_POST['xp']))
{	
	$experience = $experience+20;
	$req = $bdd->prepare('UPDATE membre SET experience=:experience WHERE login=:login');
	$req->execute(array('experience'=>$experience,'login'=>$_SESSION['membre']));
    $req->closeCursor();
}

if($experience>=$experienceMax)
{
	$experienceMax *= 1.5;
	$req = $bdd->prepare('UPDATE membre SET experienceMax=:experienceMax WHERE login=:login');
	$req->execute(array('experienceMax'=>$experienceMax,'login'=>$_SESSION['membre']));
    $req->closeCursor();
}

if($barreExperience>=100)
{
	$barreExperience = 10;	
}
?>
Par contre quand je fais l'UPDATE pour la variable $experienceMax dans mon if($experience>=$experienceMax) ma variable n'est pas stockée du coup dans la BDD, je ne comprends pas c'est le même code en changeant juste les variable que dans le if du dessus qui dit si je clique sur POST lors alors j'incrémente mon expérience...
La y'a un truc qui m'échappe .
Ma variable $experienceMax de base vaut 100 , je passe au niveau suivant donc ça fait 100*1.5=150 ça m'affiche bien 150 mais dans la BDD il est affiché 100, je pense que c'est pour ça que du coup après mon if n'incremente plus ma variable $experienceMax.

Je mets un lien qui explique en image à quoi correspond chaque variable :
http://imageshack.us/photo/my-images/27/sdzm.jpg/

Mammouth du PHP | 2278 Messages

23 déc. 2012, 16:59

Bjr,
puisque tu incrémentes toujours $experience, il doit y avoir moyen de faire plus simple
if(!empty($_POST['xp']))
{      
        $experience = $experience+20;
       if($experience>=$experienceMax)
       {
            $NouvelexperienceMax = $experienceMax*1.5;
           $req = $bdd->prepare('UPDATE membre SET experienceMax=:experienceMax WHERE login=:login');
           $req->execute(array('experienceMax'=>$NouvelexperienceMax,'login'=>$_SESSION['membre']));             
           $req = $bdd->prepare('UPDATE membre SET experience=:experience WHERE login=:login');
            $req->execute(array('experience'=>$experience,'login'=>$_SESSION['membre']));
            $barreExperience = 10; //??????
            $req->closeCursor();
     }
}
Vanitas vanitatum et omnia vanitas
Mes derniers livres :
Sauvez les Mots chez BoD,
Tous les chemins mènent à ROM chez BoD

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 8758 Messages

23 déc. 2012, 20:24

salut,

je ne comprend pas trop ton soucis. Je viens de tester ce code (qui est le tiens adapté pour je puisse tester mais cela ne change l'algo)
<?php
session_start();
// if(empty($_SESSION['membre'])){
// 	header('Location: index.php');
// }
?>
<!doctype html>
<html>
<head>
<title>Test xenos 92</title>
</head>
<body>
	<pre>
<?php 
$_SESSION['membre'] = 'moogli';

// require("php/connection.php");
$bdd = new \PDO ( 'mysql:host=localhost;dbname=test;', 'root', '' );

$req = $bdd->prepare('SELECT * FROM membre WHERE login=:login');
$req->execute(array('login'=>$_SESSION['membre']));
$data = $req->fetch(PDO::FETCH_ASSOC);
$req->closeCursor();

var_dump($data);

$experience = $data['experience'];
$experienceMax = $data['experienceMax'];
$niveau = $data['niveau'];

if(!empty($_POST['xp'])){
	echo 'up xp<br />';
	$experience = $experience+20;
	$req = $bdd->prepare('UPDATE membre SET experience=:experience WHERE login=:login');
	$req->execute(array('experience'=>$experience,'login'=>$_SESSION['membre']));
	$req->closeCursor();
}

if($experience>=$experienceMax){
	echo 'lvl up<br />';
	$experienceMax *= 1.5;
	$req = $bdd->prepare('UPDATE membre SET experienceMax=:experienceMax, niveau=niveau+1 WHERE login=:login');
	$req->execute(array('experienceMax'=>$experienceMax,'login'=>$_SESSION['membre']));
	$req->closeCursor();
}
$barreExperience = (($experience/$experienceMax)*100);
var_dump($barreExperience);
if($barreExperience>=100){
	$barreExperience = 10;
}
?>
</pre>
<h1>tu est lvl : <?php echo $data['niveau']; ?></h1>
	<form action="" method="post">
		<input type="submit" name="xp" value=" Monter l'xp " /><br /> xp
		actuelle :
		<progress value="<?php echo $barreExperience; ?>" min="0", max="100" style="width: 400px; background-color: yellow;" />
	</form>
</body>
</html>
ce script fonctionne on change de niveau et la barre de progression aussi.
j'ai ajouter la monté de niveau dans le second update, parce que c'était fait nul part.

Ce que je te conseil :
- Modifier ton modèle pour ne pas stocker l'xp max dans la table membre (totalement inutile ici) et d'ajouter une table "niveau" qui contiendra l'xp max par niveau, comme ça tu est certain d'avoir la même pour tout le monde.
- Remettre l'xp a zéro au lvl up (enfin pas à zéro à xp - xpMaxDuLvlPrécedent ( normalement obligatoirement positif ;)) afin de garder l'xp gagné "en plus".

table
create table niveaux (
	niveau int unsigned not null primary key, -- pas d'auto increment pour éviter les boulettes de niveau manquant :)
	xpmax bigint unsigned not null default 100
);

create table membre (
	idmembre int unsigned not null auto_increment primary key,
	login varchar(25) not null,
	niveau int unsigned not null default 0,
	experience bigint unsigned not null default 0,
	foreign key (niveau) references niveaux(niveau)
);
-- reste a faire l'insertion des infos
coté php je ferais un truc dans le genre (a partir de ton code)
<?php
session_start();
// if(empty($_SESSION['membre'])){
// 	header('Location: index.php');
// }
?>
<!doctype html>
<html>
<head>
<title>Test xenos 92</title>
</head>
<body>
	<pre>
<?php 
$_SESSION['membre'] = 'moogli';

// require("php/connection.php");
$bdd = new \PDO ( 'mysql:host=localhost;dbname=test;', 'root', '' );
if(isset($_GET['init'])){
	$p = $bdd->prepare('insert into niveaux values(:lvl,:xp)');
	$xp = 100;
	for($i = 1; $i<101; $i++){
		$p->bindValue(':lvl', $i,PDO::PARAM_INT);
		$p->bindValue(':xp', $xp,PDO::PARAM_INT);
		$p->execute();
		$xp *= 1.5;
	}
}
$req = $bdd->prepare('SELECT idmembre, login, niveau,experience,xpmax
		FROM membre join niveaux using(niveau) WHERE login=:login');
$req->execute(array('login'=>$_SESSION['membre']));
$data = $req->fetch(PDO::FETCH_ASSOC);
$req->closeCursor();

var_dump($data);

$experience = $data['experience'];
$experienceMax = $data['xpmax'];
$niveau = $data['niveau'];


if(!empty($_POST['xp'])){
	echo 'up xp<br />';
	$experience = $experience+20;
	$req = $bdd->prepare('UPDATE membre SET experience=:experience WHERE login=:login');
	$req->execute(array('experience'=>$experience,'login'=>$_SESSION['membre']));
	$req->closeCursor();
}

if($experience>=$experienceMax){
	echo 'lvl up<br />';
	$experience = $experience - $experienceMax;
	$req = $bdd->prepare('UPDATE membre SET niveau=:lvl, experience = :xp WHERE login=:login');
	$lvl = $data['niveau']+1;
	$req->bindParam(':lvl', $lvl,PDO::PARAM_INT);
	$req->bindParam(':xp', $experience,PDO::PARAM_INT);
	$req->bindParam(':login', $_SESSION['membre']);
	$req->execute();
	$req->closeCursor();
}

$barreExperience = (($experience/$experienceMax)*100);
var_dump($barreExperience);
if($barreExperience>=100){
	$barreExperience = 10;
}
?>
</pre>
	<h1>
		tu est lvl :
		<?php echo $data['niveau']; ?>
	</h1>
	<form action="" method="post">
		<input type="submit" name="xp" value=" Monter l'xp " /><br /> xp
		actuelle :
		<progress value="<?php echo $barreExperience; ?>" min="0" , max="100"
			style="width: 400px; background-color: yellow;" />
	</form>
</body>
</html>
L'init c'est pour ne pas me faire chier a remplir la table niveau mais tu n'en a pas forcément besoin (au pire une fois).

Avec ça tu as ce que tu veux, changement de lvl automatique et tu garde les points au dessus du seuil max du lvl précédent.
Petit modif tu repars à zéro (ou le reliquat du lvl précédent) et non plus avec l'xp acquise (c'est limite d'avoir 100 points pour le 1er lvl et seulement 50 pour le 2 ;) )?

L'amélioration d'algo de Sirakawa est a prendre en compte bien entendu, ce code n'est qu'a titre d'exemple basé sur le tiens.

@+
Il en faut peu pour être heureux ......

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

24 déc. 2012, 01:15

Modération :
Le multipostage est interdit sur le forum.

Merci de prendre le temps de lire les règlements.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer