Mécanique de base de l'expérience et des niveaux
Tout système de progression repose sur une idée simple : le joueur effectue des actions, acquiert de l'expérience et, lorsque l'expérience accumulée est suffisante, il passe à un nouveau niveau. Commençons par la version la plus simple en JavaScript :
class Player {
constructor() {
this.level = 1;
this.experience = 0;
this.experienceToNextLevel = 100;
}
gainExperience(amount) {
this.experience += amount;
while (this.experience >= this.experienceToNextLevel) {
this.levelUp();
}
}
levelUp() {
this.experience -= this.experienceToNextLevel;
this.level++;
this.experienceToNextLevel = Math.floor(this.experienceToNextLevel * 1.5);
console.log(`Congratulations! You have reached ${this.level} level!`);
}
}
const player = new Player();
player.gainExperience(150); // Nous acquérons de l'expérience et améliorons le niveauFaites attention à la formule de calcul de l'expérience pour le niveau suivant. Nous multiplions la valeur actuelle par 1,5, ce qui crée une courbe de croissance exponentielle. C'est un point important : si chaque niveau nécessite la même quantité d'expérience, le jeu deviendra rapidement ennuyeux.
Différentes courbes de progression
Il existe plusieurs approches populaires pour calculer l'expérience requise. La progression linéaire, lorsque chaque niveau nécessite un nombre fixe d'expérience supplémentaire, convient aux jeux courts. La courbe exponentielle, comme dans l'exemple ci-dessus, crée une sensation de complexité progressive. La courbe logarithmique rend les premiers niveaux rapides et les suivants plus lents.
Voici un exemple avec différentes formules :
class ProgressionSystem {
// Progression linéaire : 100, 200, 300, 400 ...
static linear(level, baseXP = 100) {
return baseXP * level;
}
// Exponentielle : 100, 150, 225, 337,5 ...
static exponential(level, baseXP = 100, multiplier = 1.5) {
return Math.floor(baseXP * Math.pow(multiplier, level - 1));
}
// Polynomial : 100, 400, 900, 1600 ...
static polynomial(level, baseXP = 100) {
return baseXP * Math.pow(level, 2);
}
// Formule hybride (comme dans Pokemon)
static hybrid(level) {
return Math.floor(1.2 * Math.pow(level, 3));
}
}
// Voyons comment la demande d'expérience augmente
for (let level = 1; level <= 5; level++) {
console.log(`Level ${level}:`);
console.log(` Linear: ${ProgressionSystem.linear(level)}`);
console.log(` Exponential: ${ProgressionSystem.exponential(level)}`);
console.log(` Polynomial: ${ProgressionSystem.polynomial(level)}`);
}Quelle formule choisir ?
Cela dépend de votre jeu. Pour les jeux occasionnels sur mobile, une progression rapide est souvent utilisée au début pour capturer le joueur, puis le rythme ralentit. Dans les RPG hardcore, la progression peut être lente et exigeante dès le début.
Ajout de récompenses pour le niveau
Monter de niveau sans récompense est une occasion manquée. Les joueurs doivent sentir que leurs progrès signifient quelque chose. Ajoutons un système de récompenses :
class Player {
constructor() {
this.level = 1;
this.experience = 0;
this.health = 100;
this.attack = 10;
this.defense = 5;
this.skillPoints = 0;
}
levelUp() {
this.level++;
// Augmenter les caractéristiques de base
this.health += 20;
this.attack += 3;
this.defense += 2;
this.skillPoints += 5;
// Chaque 5ème niveau donne une récompense spéciale
if (this.level % 5 === 0) {
this.unlockNewAbility();
}
// Restauration de la santé lors de l'augmentation du niveau
this.currentHealth = this.health;
console.log(`
🎉 Level ${this.level}!
Health: ${this.health}
Attack: ${this.attack}
Defense: ${this.defense}
Skill points: ${this.skillPoints}
`);
}
unlockNewAbility() {
const abilities = [
'Fireball',
'Ice Arrow',
'Shield of Power',
'Lightning strike'
];
const abilityIndex = Math.floor(this.level / 5) - 1;
if (abilityIndex < abilities.length) {
console.log(`✨ Ability unlocked: ${abilities[abilityIndex]}`);
}
}
}Visualisation de la progression
Il ne suffit pas de stocker des chiffres, les joueurs ont besoin de voir leur progression. Créons une barre de progression simple :
class ProgressBar {
static draw(current, required, width = 20) {
const percentage = current / required;
const filledWidth = Math.floor(percentage * width);
const emptyWidth = width - filledWidth;
const filled = '█'.repeat(filledWidth);
const empty = '░'.repeat(emptyWidth);
const percentText = Math.floor(percentage * 100);
return `[${filled}${empty}] ${percentText}% (${current}/${required})`;
}
}
const player = new Player();
console.log('Experience:', ProgressBar.draw(player.experience, player.experienceToNextLevel));
player.gainExperience(75);
console.log('Experience:', ProgressBar.draw(player.experience, player.experienceToNextLevel));Pour les jeux en ligne, vous pouvez utiliser HTML et CSS pour créer des barres de progression plus belles. Voici un exemple rapide :
class UIManager {
static updateExpBar(player) {
const percentage = (player.experience / player.experienceToNextLevel) * 100;
const expBar = document.getElementById('exp-bar');
const expText = document.getElementById('exp-text');
expBar.style.width = `${percentage}%`;
expText.textContent = `${player.experience} / ${player.experienceToNextLevel} XP`;
}
static showLevelUp(player) {
const notification = document.createElement('div');
notification.className = 'level-up-notification';
notification.textContent = `Level ${player.level}!`;
document.body.appendChild(notification);
// Animation de l'apparition et de la disparition
setTimeout(() => notification.classList.add('show'), 10);
setTimeout(() => {
notification.classList.remove('show');
setTimeout(() => notification.remove(), 300);
}, 2000);
}
}Système de prestige et de renaissance
De nombreux jeux modernes utilisent un système de prestige : lorsque le joueur atteint le niveau maximum, il peut recommencer, mais avec des bonus. Cela ajoute de la rejouabilité :
class PrestigeSystem {
constructor() {
this.prestigeLevel = 0;
this.prestigePoints = 0;
}
canPrestige(player) {
return player.level >= 100;
}
prestige(player) {
if (!this.canPrestige(player)) {
console.log('Insufficient level for prestige!');
return false;
}
this.prestigeLevel++;
this.prestigePoints += Math.floor(player.level / 10);
// Nous réinitialisons le joueur, mais conservons les bonus
const expBonus = 1 + (this.prestigeLevel * 0.1); // +10% d'expérience pour chaque prestige
const statBonus = this.prestigeLevel * 5; // +5 aux caractéristiques de départ
player.reset(expBonus, statBonus);
console.log(`
🌟 Prestige ${this.prestigeLevel}!
Experience bonus: +${(expBonus - 1) * 100}%
Bonus to characteristics: +${statBonus}
Prestige points: ${this.prestigePoints}
`);
return true;
}
// Améliorations constantes pour les points de prestige
buyPermanentUpgrade(upgrade) {
const upgrades = {
'double_xp': { cost: 10, effect: 'Double experience' },
'start_level_10': { cost: 15, effect: 'Start from level 10' },
'bonus_gold': { cost: 20, effect: '+50% gold' }
};
const selected = upgrades[upgrade];
if (!selected) return false;
if (this.prestigePoints >= selected.cost) {
this.prestigePoints -= selected.cost;
console.log(`Purchased: ${selected.effect}`);
return true;
}
return false;
}
}Équilibrage de la progression
La partie la plus difficile est d'équilibrer correctement le système. Le joueur doit sentir la progression, mais pas trop vite. Quelques conseils : les cinq premiers niveaux doivent être complétés rapidement pour capturer le joueur et montrer la mécanique. Les niveaux moyens sont le contenu principal, ici le rythme doit être confortable. Les derniers niveaux peuvent nécessiter des efforts sérieux, ce qui crée un sentiment d'accomplissement.
Il est important de tester sur de vrais joueurs. Ce qui semble équilibré pour un développeur peut être trop rapide ou trop lent pour un joueur moyen. Utilisez l'analyse pour suivre les niveaux auxquels les joueurs sont bloqués ou abandonnent le jeu.
Voici un système de journalisation simple pour l'analyse :
class Analytics {
static logLevelUp(player, timeSpent) {
const data = {
level: player.level,
timeSpent: timeSpent,
timestamp: new Date().toISOString()
};
// Dans le jeu réel, nous envoyons au serveur
console.log('Analytics:', data);
// Enregistrer localement pour analyse
const history = JSON.parse(localStorage.getItem('levelHistory') || '[]');
history.push(data);
localStorage.setItem('levelHistory', JSON.stringify(history));
}
static getAverageLevelTime() {
const history = JSON.parse(localStorage.getItem('levelHistory') || '[]');
if (history.length === 0) return 0;
const total = history.reduce((sum, entry) => sum + entry.timeSpent, 0);
return total / history.length;
}
}Techniques avancées
Les jeux modernes utilisent souvent plusieurs systèmes de progression parallèles. Par exemple, le niveau du personnage, le niveau de compétence, le classement de combat, la progression saisonnière. Chaque système donne au joueur quelque chose de nouveau et maintient l'engagement à différentes étapes du jeu. Les objectifs quotidiens et hebdomadaires sont également populaires, offrant une expérience et des récompenses supplémentaires, encourageant les joueurs à revenir régulièrement dans le jeu.
N'oubliez pas les commentaires. Chaque action du joueur doit montrer des progrès : nombre d'expériences, animations, effets sonores, effets visuels lorsque le niveau augmente. Tout cela crée un sentiment de satisfaction et motive à continuer à jouer.
Conclusion : Le système de niveaux et de progression est une science à part entière qui combine la programmation, la conception de jeux et la psychologie du joueur. Un système correctement mis en œuvre maintient les joueurs impliqués pendant des heures, créant ainsi l'effet « un autre niveau ». Expérimentez avec des formules, testez sur de vrais joueurs et n'ayez pas peur de changer l'équilibre après la sortie.
🎓 Continuez votre formation !
Vous pouvez étudier ce sujet plus en profondeur, ainsi que maîtriser le développement de jeux, d'applications Web et bien plus encore dans Codique — notre plateforme éducative avec des cours pour les développeurs débutants.
Et nous avons aussi un super chaîne Telegram avec une communauté amicale où les développeurs discutent du code, partagent leurs expériences et s'entraident pour se développer.
