Développement de personnages de jeu
Fait partie de la section Programmation Orientée Objet du Journey Java de Coddy — leçon 86 sur 87.
Ce défi vous propose de construire un système de développement de personnages de jeu qui illustre la puissance de la POO dans la modélisation d'entités complexes et interactives.
Concevez une hiérarchie de personnages où une classe de base Character définit des attributs communs tels que la santé, le nom et le niveau. Des classes spécialisées telles que Warrior, Mage et Archer étendent cette base avec des capacités et des styles de combat uniques.
Les interfaces fonctionnent naturellement ici : Attackable pourrait définir des méthodes de combat, tandis que Healable gère les capacités de restauration. Un Mage pourrait implémenter les deux, alors qu'un Warrior se concentre uniquement sur l'attaque.
Envisagez d'utiliser le patron Strategy pour différents comportements d'attaque, permettant aux personnages de changer de style de combat de manière dynamique. Le patron State pourrait gérer les conditions des personnages comme les états normal, empoisonné ou étourdi qui affectent le comportement.
Pensez à la composition pour les systèmes d'équipement où les personnages « possèdent » des armes et des armures plutôt que d'en hériter. Utilisez des enums pour les classes de personnages ou les types de dégâts, et appliquez l'encapsulation pour protéger les statistiques contre les modifications invalides.
Défi
FacileConstruisons un système de développement de personnages de jeu qui met en avant la puissance de la POO pour modéliser des entités de jeu complexes et interactives ! Vous allez créer une hiérarchie de personnages avec différents styles de combat, des capacités spéciales et un système d'état qui affecte le comportement des personnages.
Vous organiserez votre code sur sept fichiers :
DamageType.java: Créez un enum représentant les différents types de dégâts dans le jeu. Incluez les valeursPHYSICAL,MAGICAL, etRANGED. Ajoutez un champ privédescription(String), un constructeur qui l'initialise, et un getter. Les dégâts physiques doivent avoir la description "brute force", les magiques doivent avoir "arcane energy", et à distance doivent avoir "precision strike".Attackable.java: Créez une interface définissant les capacités de combat. Déclarez les méthodesattack(Character target)qui retourne une String décrivant l'attaque, etgetDamageType()qui retourne un DamageType.Healable.java: Créez une interface pour les capacités de restauration. Déclarez une méthodeheal(int amount)qui retourne une String décrivant l'action de soin.Character.java: Créez une classe de base abstraite pour tous les personnages du jeu. Incluez des champs privés pourname(String),health(int),maxHealth(int), etlevel(int). Le constructeur prend name, maxHealth, et level, en initialisant health à la valeur de maxHealth. Incluez des getters pour tous les champs. Ajoutez une méthode protégéesetHealth(int health)qui garantit que la santé reste entre 0 et maxHealth. Créez une méthodetakeDamage(int damage)qui réduit la santé et retourne"[name] takes [damage] damage! Health: [health]/[maxHealth]". Ajoutez une méthodeisAlive()retournant true si la santé est supérieure à 0. Déclarez une méthode abstraitegetCharacterClass()retournant une String.Warrior.java: Créez une classe étendant Character et implémentant Attackable. Ajoutez un champ privéstrength(int). Le constructeur prend name, maxHealth, level, et strength. ImplémentezgetCharacterClass()pour retourner"Warrior". ImplémentezgetDamageType()pour retournerPHYSICAL. Implémentezattack(Character target)pour infliger des dégâts égaux à strength plus level, appeler la méthode takeDamage de la cible, et retourner"[name] strikes with [damageType description] for [damage] damage!"suivi d'un saut de ligne et du résultat de takeDamage.Mage.java: Créez une classe étendant Character et implémentant à la fois Attackable et Healable. Ajoutez des champs privésintelligence(int) etmana(int). Le constructeur prend name, maxHealth, level, intelligence, et mana. ImplémentezgetCharacterClass()pour retourner"Mage". ImplémentezgetDamageType()pour retournerMAGICAL. Implémentezattack(Character target)pour infliger des dégâts égaux à intelligence multipliée par 2, en suivant le même format que Warrior. Implémentezheal(int amount)pour restaurer la santé (en utilisant setHealth) et retourner"[name] channels healing magic! Health: [health]/[maxHealth]".Main.java: Donnez vie à votre système de jeu ! Vous recevrez une chaîne de commandes séparées par des virgules :CREATE_WARRIOR:name:maxHealth:level:strengthCREATE_MAGE:name:maxHealth:level:intelligence:manaATTACK:attackerName:targetNameHEAL:mageName:amountSTATUS:characterName
Maintenez une collection de personnages. Traitez chaque commande et affichez :
- CREATE_WARRIOR/CREATE_MAGE :
[name] the [characterClass] joins the battle! - ATTACK : Affichez le résultat de l'attaque (la String retournée par la méthode attack)
- HEAL : Affichez le résultat du soin, ou
[name] cannot healsi le personnage n'est pas un Mage - STATUS :
[name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]
Après toutes les commandes, affichez
--- Battle Summary ---suivi du statut de chaque personnage.
Vous recevrez une seule entrée : la chaîne de commandes séparées par des virgules.
Par exemple, avec l'entrée CREATE_WARRIOR:Thorin:100:5:15,CREATE_MAGE:Gandalf:80:7:12:50,ATTACK:Thorin:Gandalf,HEAL:Gandalf:25,STATUS:Gandalf, votre sortie serait :
Thorin the Warrior joins the battle!
Gandalf the Mage joins the battle!
Thorin strikes with brute force for 20 damage!
Gandalf takes 20 damage! Health: 60/80
Gandalf channels healing magic! Health: 80/80
Gandalf (Mage) - Level 7 - Health: 80/80 - Alive
--- Battle Summary ---
Thorin (Warrior) - Level 5 - Health: 100/100 - Alive
Gandalf (Mage) - Level 7 - Health: 80/80 - AliveCe défi combine l'héritage (hiérarchie Character), l'implémentation d'interfaces multiples (Mage implémente à la fois Attackable et Healable), les enums avec méthodes (DamageType), le polymorphisme (traiter différents types de personnages de manière uniforme) et l'encapsulation (gestion protégée de la santé) dans un système de jeu captivant !
Aide-mémoire
La programmation orientée objet (POO) permet de modéliser des systèmes complexes à travers des classes, l'héritage, les interfaces et les patrons de conception.
Hiérarchie de classes
Créez une classe de base avec des attributs communs et étendez-la avec des classes spécialisées :
public abstract class Character {
private String name;
private int health;
private int maxHealth;
private int level;
public Character(String name, int maxHealth, int level) {
this.name = name;
this.maxHealth = maxHealth;
this.health = maxHealth;
this.level = level;
}
protected void setHealth(int health) {
this.health = Math.max(0, Math.min(health, maxHealth));
}
public abstract String getCharacterClass();
}Interfaces
Définissez des contrats pour des comportements spécifiques que les classes peuvent implémenter :
public interface Attackable {
String attack(Character target);
DamageType getDamageType();
}
public interface Healable {
String heal(int amount);
}Énumérations avec des champs
Les énumérations peuvent avoir des champs, des constructeurs et des méthodes :
public enum DamageType {
PHYSICAL("brute force"),
MAGICAL("arcane energy"),
RANGED("precision strike");
private String description;
private DamageType(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}Implémentation d'interfaces multiples
Une classe peut implémenter plusieurs interfaces :
public class Mage extends Character implements Attackable, Healable {
private int intelligence;
private int mana;
@Override
public String attack(Character target) {
// Implémentation
}
@Override
public String heal(int amount) {
// Implémentation
}
}Encapsulation
Utilisez des champs privés avec des setters protégés pour contrôler l'accès et valider les données :
protected void setHealth(int health) {
this.health = Math.max(0, Math.min(health, maxHealth));
}Polymorphisme
Traitez différents types de personnages de manière uniforme via leur classe de base commune ou leurs interfaces, permettant des collections et des appels de méthodes flexibles.
Essayez vous-même
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
import java.util.LinkedHashMap;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
// TODO: Utiliser une collection pour maintenir les personnages (LinkedHashMap préserve l'ordre d'insertion)
// LinkedHashMap<String, Character> characters = new LinkedHashMap<>();
// TODO: Diviser l'entrée par virgule pour obtenir les commandes individuelles
// String[] commands = input.split(",");
// TODO: Traiter chaque commande :
// - CREATE_WARRIOR:name:maxHealth:level:strength
// Afficher : "[name] the Warrior joins the battle!"
//
// - CREATE_MAGE:name:maxHealth:level:intelligence:mana
// Afficher : "[name] the Mage joins the battle!"
//
// - ATTACK:attackerName:targetName
// Afficher le résultat de l'attaque à partir de la méthode attack
//
// - HEAL:mageName:amount
// Afficher le résultat du soin, ou "[name] cannot heal" s'il ne s'agit pas d'un Mage
//
// - STATUS:characterName
// Afficher : "[name] ([characterClass]) - Level [level] - Health: [health]/[maxHealth] - [Alive/Defeated]"
// TODO: Après toutes les commandes, afficher "--- Battle Summary ---"
// Puis afficher le statut de chaque personnage
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Fondamentaux de la POO
Fichiers externesIntroduction à la POOClasses vs ObjetsLe mot-clé thisMéthodesChamps (Attributs)Méthode constructeurSurcharge de constructeurRécapitulatif - Calculatrice simple4Héritage
Héritage de base (extends)Le mot-clé superRedéfinition de méthode (@Override)Chaînage de constructeursLa classe ObjectHéritage simple et multiniveauPourquoi pas d'héritage multiple de classesRécapitulatif - Hiérarchie des employés7Méthodes spéciales et classe Object
Méthode toString()equals() et hashCode()Méthode clone()compareTo() et ComparableInterface ComparatorRécapitulatif - Tri personnalisé2Modificateurs d'accès et Encapsulation
Aperçu des niveaux d'accèsMéthodes Getter et SetterMasquage d'informationsLe mot-clé finalRécapitulatif - Gestionnaire de compte bancaire5Polymorphisme
Bases de la surcharge de méthodesRedéfinition de méthodes (Run-Time)Upcasting et DowncastingL'opérateur instanceofClasses et méthodes abstraitesRécapitulatif - Calculateur de formes8Concepts avancés de la POO
Composition vs HéritageAgrégation vs CompositionClasses internes, imbriquées et anonymesEnums et méthodes d'EnumRecords (Java 16+)Classes scellées (Java 17+)11Patrons de conception, partie 1
Introduction aux patrons de conceptionPatron SingletonPatron FabriquePatron MonteurPatron ObservateurPatron Stratégie14Défis finaux
Plateforme d'E-LearningSystème bancaireDéveloppement de personnages de jeuService de location de véhicules3Propriétés de classe et membres statiques
Variables d'instance vs variables statiquesMéthodes statiquesBlocs statiquesConstantes (static final)Récapitulatif - Compteur et utilitaire6Interfaces et Classes Abstraites
Introduction aux InterfacesImplémentation d'InterfacesImplémentation d'Interfaces MultiplesDefault et Static dans les InterfacesClasses Abstraites vs InterfacesInterfaces FonctionnellesRécapitulatif - Système de Paiement9La généricité
Introduction à la généricitéClasses génériquesMéthodes génériquesParamètres de type bornésWildcards (?, extends, super)Récapitulatif - Conteneur générique12Patrons de conception, partie 2
Patron CommandePatron AdaptateurPatron DécorateurPatron Template MethodPatron ÉtatPatron CompositePatron Itérateur