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.
@+