Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Java Discussion :

Rpg en Java // ArrayList et confettis


Sujet :

Java

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : septembre 2019
    Messages : 3
    Points : 1
    Points
    1
    Par défaut Rpg en Java // ArrayList et confettis
    Bonjour à tous, c'est mon premier post ici, je me surnomme Etigau, j'ai commencé Java il y a 2 semaines en formation dev, et j'essaye de m'amuser à faire un petit rpg.
    Je rencontre quelques difficultés, si jamais ça intéresse quelqu'un de m'apporter un peu d'aide je serai ravi !

    Alors en gros j'ai crée une classe Character.
    Et j'ai crée une classe CharaStats pour définir si le perso est un tank, mage etc , ce qui inclus des données de pv,defense etc.
    Pour ça j'ai utilisé une ArrayList, je vous passe la déclaration des variables mais en gros ça donne ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        public static final
        ArrayList <CharaStats> specie = new ArrayList <CharaStats>();
        {
            // Tank
            specie.add(new CharaStats("Tank", 12500,750,600,95,120));
            // Epeiste
            specie.add(new CharaStats("Swordsman", 10200,640,800,105,150));
            // Archer
            specie.add(new CharaStats("Archer", 9180,540,900,120,130));
            // Mage
            specie.add(new CharaStats("Magus", 11000,600,500,110,200));
        }
    }
    Voilà à priori je pense que c'est fonctionnel. Mon soucis, c'est comment intégrer à ma classe Character ?
    Faut il que je redéfinisse mes variable (life, defense etc) dans Character ?
    Mon intégration au constructeur est-elle bonne ?
    Et je n'arrive pas à l'utiliser dans le main (la dernière ligne de code), je ne sais pas comment appeler mon ArrayList et sélectionner un perso en particulier. Si quelqu'un peut m'éclairer ça serait top
    Merci d'avance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class Character {
     
     
        // Pseudo
        private String nickname;
        // Genre 
        private final Gender gender;
     
        private ArrayList<CharaStats> specie;
     
        public Character(String nickname, Gender gender, ArrayList<CharaStats> specie) {
            this.nickname = nickname;
            this.gender = gender;
            this.specie = specie;
        }
     
        public static void main(String[] args) {
            Character newChamp = new Character("David",Gender.MALE, ArrayList<>.specie(1)) ;
        }
    }

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    septembre 2009
    Messages
    11 794
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2009
    Messages : 11 794
    Points : 27 819
    Points
    27 819
    Billets dans le blog
    2
    Par défaut
    Salut,

    Il me semble qu'il y a une erreur ici, non ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        public Character(String nickname, Gender gender, ArrayList<CharaStats> specie) {
    ce n'est pas plutôt

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       // Pseudo
        private String nickname;
        // Genre 
        private final Gender gender;
     
        private CharaStats specie;
     
    public Character(String nickname, Gender gender,  CharaStats  specie) {
    Parce que un personnage n'est que d'une seule espèce à priori, non ?


    1. S'il n'y a pas d'erreur, il suffit de référencer la variable specie, en partant du principe que specie est déclarée dans Character (on peut le faire ailleurs), donc comme ça :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      public class Character {
       
       public static final
          ArrayList <CharaStats> specie = new ArrayList <CharaStats>();
       
      /*ici code remplissage de specie, voir ci-après*/
       
       public static void main(String[] args) {
              Character newChamp = new Character("David",Gender.MALE,  specie ) ;
          }
    2. S'il y'a bien une erreur...


      Pourquoi utiliser une liste pour stocker les différents "species", puisque chacune d'entre-elles est affectable séparément ?

      Quoi qu'il en soit, si specie est déclarée dans Character, donc comme ça :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      public class Character {
       
       public static final
          ArrayList <CharaStats> specie = new ArrayList <CharaStats>();
       
      /*ici code remplissage de specie, voir ci-après*/
       
       public static void main(String[] args) {
              Character newChamp = new Character("David",Gender.MALE, Character.specie.get(1)/* on prend le deuxième élément dans la liste*/) ;
          }
      Attention, ton remplissage de liste devrait être static :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      static {
      	        // Tank
      	        specie.add(new CharaStats("Tank", 12500,750,600,95,120));
      	        // Epeiste
      	        specie.add(new CharaStats("Swordsman", 10200,640,800,105,150));
      	        // Archer
      	        specie.add(new CharaStats("Archer", 9180,540,900,120,130));
      	        // Mage
      	        specie.add(new CharaStats("Magus", 11000,600,500,110,200));
      	    }
      Déjà, c'est plutôt logique puisque specie est static, mais surtout un bloc {} s'exécute à chaque instanciation de la classe, donc tu risques de te retrouver soit avec une liste vite (si la classe n'est jamais instanciée), soit avec plusieurs fois les 4 CharaStats...

      D'ailleurs, tu peux faire plus simplement :

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      public static List<CharaStats> SPECIE = Arrays.asList(
                       // Tank
      	        new CharaStats("Tank", 12500,750,600,95,120),
      	        // Epeiste
      	         new CharaStats("Swordsman", 10200,640,800,105,150),
      	        // Archer
      	         new CharaStats("Archer", 9180,540,900,120,130),
      	        // Mage
      	         new CharaStats("Magus", 11000,600,500,110,200)         
      );
      Ou encore mieux :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      public static List<CharaStats> SPECIE = Collections.unmodifiableList(Arrays.asList(
                       // Tank
      	        new CharaStats("Tank", 12500,750,600,95,120),
      	        // Epeiste
      	         new CharaStats("Swordsman", 10200,640,800,105,150),
      	        // Archer
      	         new CharaStats("Archer", 9180,540,900,120,130),
      	        // Mage
      	         new CharaStats("Magus", 11000,600,500,110,200)         
      ));
      Ce qui évite que la liste puisse être modifiée.




    (A noter que pour respecter les conventions , specie devrait être en majuscules)


    Mais pour gérer ce genre de choses, je te conseille plutôt d'utiliser une enum :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public enum CharaStats {
    	        TANK("Tank", 12500,750,600,95,120),
    	        SWORDSMAN("Swordsman", 10200,640,800,105,150),
    	        ARCHER("Archer", 9180,540,900,120,130),
    	        MAGUS("Magus", 11000,600,500,110,200),
    	        ;
    	private final String name;
    	private final int pv;
    	private final int defense;
     
    	private CharaStats(String name, int pv, int defense, int chepasquoi1, int chepasquoi2, int chepasquoi3) {
    		this.name=name;
    		this.pv=pv;
    		this.defense=defense;
    	}
     
    	public int getName() {
    		return name;
    	}
     
    	public int getPV() {
    		return pv;
    	}
     
            /*...etc...*.
     
    }
    Avec, si un personnage peut être de plusieurs espèces :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class Character {
     
     
        // Pseudo
        private String nickname;
        // Genre 
        private final Gender gender;
     
        private Set<CharaStats> specie;
     
        public Character(String nickname, Gender gender, Set<CharaStats> specie) {
            this.nickname = nickname;
            this.gender = gender;
            this.specie = specie;
        }
     
        public static void main(String[] args) {
            Character newChamp = new Character("David",Gender.MALE,  EnumSet.of(CharaStats.TANK, CharaStats.SWORDSMAN)) ;
        }
    }
    Il est plus logique d'utiliser un set parce que je doute qu'on puisse affecter deux fois une même espèce...

    Avec, si un personnage peut être d'une seule espèce :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    public class Character {
     
     
        // Pseudo
        private String nickname;
        // Genre 
        private final Gender gender;
     
        private CharaStats specie;
     
        public Character(String nickname, Gender gender,  CharaStats  specie) {
            this.nickname = nickname;
            this.gender = gender;
            this.specie = specie;
        }
     
        public static void main(String[] args) {
            Character newChamp = new Character("David",Gender.MALE,   CharaStats.SWORDSMAN) ;
        }
    }
    En tout cas, avec l'enum, c'est beaucoup plus clair de voir l'espèce (ou les espèces) affectée, que de se souvenir qu'à l'index 3 il y a le mage...
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : septembre 2019
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Wow Merci pour cette super réponse !
    C'est détaillé et bienveillant

    Alors à la base j'étais parti sur une enum, et mon formateur m'a dit pourquoi tu fais ça, tu devrais faire une liste haha.
    Peut être parce qu'on avait vu les ArrayList la veille et qu'il voulait que je m'exerce dessus, je ne sais pas.

    Quoi qu'il en soit en apportant tes judicieuses corrections, je me retrouve avec une erreur à la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 0<3
    J'ai essayé plusieurs solution comme rajouter un index à ma liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    specie.add(1, new CharaStats("Tank", 12500,750,600,95,120));
    C'est pris en charge mais ça ne résout pas le problème.

    Autre question, pourquoi dans ta suggestion d'utiliser List plutôt qu'ArrayList, tu écris specie en uppercase ?
    Tu m'explique que c'est la convention, mais c'est à dire ? Quand je l'appel dans Character, je dois aussi déclarer ma variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private CharaStats SPECIE;
    donc?

    Ta solution avec l'enum est effectivement plus judicieuse à mon sens, ça fait plaisir de voir de quoi on parle dans le main plutôt qu'un chiffre.
    Et pour le coup elle a l'air de fonctionner haha. Mais j'ai une question un peu bête, comment afficher le resultat ?
    Je dois creer une méthode ?
    Actuellement je ne peux pas utiliser un return newchamp vue que le main est un void, et si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     public static void main(String[] args) {
           Character newChamp = new Character("David",Gender.MALE,   CharaStats.SWORDSMAN) ;
            System.out.println("Your name is : "+ nickname + ", your genre is :"+ Gender + ", your specie is " + CharaStats.SWORDSMAN);
    nickname et Gender ne sont pas reconnu et CharaStats.SWORDMAN affiche SWORDMAN.
    Haha merci d'avance.

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    septembre 2009
    Messages
    11 794
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2009
    Messages : 11 794
    Points : 27 819
    Points
    27 819
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par etigau Voir le message
    Peut être parce qu'on avait vu les ArrayList la veille et qu'il voulait que je m'exerce dessus, je ne sais pas.
    Même si ce n'est pas la meilleure solution qu'il suggère, il vaut mieux toujours suivre les conseils du prof. C'est lui qui note après tour Maintenant il faut voir le contexte, l'énoncé, et bien sûr connaître la mise en application que le prof cherche à obtenir. Après, ça peut aussi dépendre du prof, s'il apprécie les initiatives, tu peux peut-être sortir du cadre, tant que tu sais justifier ton choix.

    Citation Envoyé par etigau Voir le message
    Quoi qu'il en soit en apportant tes judicieuses corrections, je me retrouve avec une erreur à la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 0<3
    Sans le code correspondant, difficile d'être concret. On obtient ce genre d'erreur lorsqu'on accès un item de List qui hors limite. Ici on accède à l'item d'index 1, alors que la liste est vice. Sans quoi, j'ai juste un soupçon : as-tu bien rendu ton bloc d'initialisation de la liste static ?

    Citation Envoyé par etigau Voir le message
    J'ai essayé plusieurs solution comme rajouter un index à ma liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    specie.add(1, new CharaStats("Tank", 12500,750,600,95,120));
    C'est pris en charge mais ça ne résout pas le problème.
    Ceci ne change rien à un accès à un item de la liste, tu ne fais qu'insérer l'instance de CharaStats à l'index 1. L'erreur c'est au get (ou éventuellement au set), pas au add (sans index).

    Citation Envoyé par etigau Voir le message
    Autre question, pourquoi dans ta suggestion d'utiliser List plutôt qu'ArrayList,
    Il vaut mieux toujours utiliser la classe ou l'interface la plus générique possible (en fonction des manipulations qu'on va avoir besoin de faire) pour le type de la variable. Ainsi, on pourra changer facilement l'implémentation au besoin. Il y a très peu de méthodes spécifiques à ArrayList et il est très rare d'en avoir besoin, donc j'utilise plus habituellement le type List. Et on pourra préférer Collection si on n'a pas besoin d’accéder directement à un élément par son index. Voire même Iterable.
    Citation Envoyé par etigau Voir le message
    tu écris specie en uppercase ?
    Il y a des conventions de nommage en Java. Elles permettent de voir rapidement certaines caractéristiques d'un nom (de variable, de classe, de méthode, etc). Pour les static final, c'est tout en majuscule avec des underscores pour séparer les sous-parties (ce qu'on nomme l'UPPER_CASE).

    Citation Envoyé par etigau Voir le message
    Tu m'explique que c'est la convention, mais c'est à dire ? Quand je l'appel dans Character, je dois aussi déclarer ma variable
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private CharaStats SPECIE;
    donc?
    Pour une variable (de classe ici, ou attribut), la convention c'est le lowerCamelCase, on commence par une minuscule et les séparations se font par des majuscules. Les conventions de nommage n'ont rien à voir avec l'endroit où on déclare, mais juste avec la nature du nom.
    Après dans mon exemple, j'ai déclaré la variable SPECIES dans Character, mais on aurait aussi bien pu la déclarer dans une autre classe, même dans CharaStats, ça aurait été logique en tout cas, vu que c'était une liste statique de CharaStats. Disons que pour mon exemple, ça m'évitait d'avoir à introduire une autre classe, et de la confusion, Ça rendait mon exemple monoclasse, donc monobloc.

    Citation Envoyé par etigau Voir le message
    Ta solution avec l'enum est effectivement plus judicieuse à mon sens, ça fait plaisir de voir de quoi on parle dans le main plutôt qu'un chiffre.
    Et pour le coup elle a l'air de fonctionner haha. Mais j'ai une question un peu bête, comment afficher le resultat ?
    Je dois creer une méthode ?
    Actuellement je ne peux pas utiliser un return newchamp vue que le main est un void, et si je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     public static void main(String[] args) {
           Character newChamp = new Character("David",Gender.MALE,   CharaStats.SWORDSMAN) ;
            System.out.println("Your name is : "+ nickname + ", your genre is :"+ Gender + ", your specie is " + CharaStats.SWORDSMAN);
    nickname et Gender ne sont pas reconnu et CharaStats.SWORDMAN affiche SWORDMAN.
    Haha merci d'avance.
    Pour afficher des informations de newChamp, il faut accèder à ses informations, par des accesseurs par exemple (getters).

    Donc dans Character, tu devrais avoir une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public String getNickName(){
    return nickName;
    }
    Ainsi tu pourras écrire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            System.out.println("Your name is : "+ newChamp .getNickName() + "etc...");
    Tu peux éventuellement aussi exposer les attributs en les rendant public final. C'est peu pratiqué surtout que ça impose à l'attribut d'être final (donc rend immutable la classe), si on ne veut pas que quelqu'un vienne foutre le bazar. Cependant rendre immutable la classe a son intérêt (pouvoir l'utiliser comme clef de map par exemple), et peut se faire même pour un attribut private couplé à un getter. Maintenant, normalement en pure objet, l'exposition des attributs n'est pas fortement recommandé : on devrait avoir une boite noire et des méthodes qui font tous les traitements, sans que l'extérieure ait a décider de comment manipuler l'instance de la classe. Mais je vais peut-être un peu trop loin par rapport à ton avancement de cours. Quoiqu'il en soit, il t a une autre façon de résoudre ton problème d'affichage : implémenter toString() pour que ça fasse l'affichage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Character {
     
      /*
          le code, que je ne répète pas...
       */
     
       public String toString() {
           return "NickName: "+nickName+", Gender: " + gender + ", Specie: " + specie;
       }
     
    }
    Ainsi tu n'as plus qu'à faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Character newChamp = new Character("David",Gender.MALE,   CharaStats.SWORDSMAN) ;
            System.out.println(newChamp);
    En revanche cette méthode fige l'affichage : on ne peut pas choisir sa forme, les informations qu'on veut afficher, etc.

    Si on n'en a besoin, on peut utiliser un Formatter éventuellement. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class Character {
     
    	private String nickName;
    	private Gender gender;
    	private CharaStats specie;
     
    	public Character(String nickName, Gender gender, CharaStats specie) {
    		this.nickName=nickName;
    		this.gender=gender;
    		this.specie=specie;
    	}
     
    	public String toString(String format) {
    		return toString(format, Locale.getDefault());
    	}
        public String toString(String format, Locale locale) {
        	StringBuilder sb = new StringBuilder();
        	Formatter formatter = new Formatter(sb, locale);
        	formatter.format(format, nickName, gender, specie);
        	return sb.toString();
        }
     
        public static void main(String[] args) {
    		Character c1 = new Character("David", Gender.MALE, CharaStats.ARCHER);
    		Character c2 = new Character("Justine", Gender.FEMALE, CharaStats.SWORDSMAN);
    		System.out.println(c1.toString("Le premier personnage s'appelle %s"));
    		System.out.println(c2.toString("Le second personnage est un %3$s et s'appelle %1$s"));
    	}
     
    }
    qui va afficher :
    Le premier personnage s'appelle David
    Le second personnage est un SWORDSMAN et s'appelle Justine
    Evidemment, on peut implémenter le mécanisme dans toutes les classes qui le justifie.

    Par exemple, on peut faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    public enum CharaStats {
    	        TANK("Tank", 12500,750,600,95,120),
    	        SWORDSMAN("Swordsman", 10200,640,800,105,150),
    	        ARCHER("Archer", 9180,540,900,120,130),
    	        MAGUS("Magus", 11000,600,500,110,200),
    	        ;
    	private final String name;
    	private final int pv;
    	private final int defense;
     
    	private CharaStats(String name, int pv, int defense, int chepasquoi1, int chepasquoi2, int chepasquoi3) {
    		this.name=name;
    		this.pv=pv;
    		this.defense=defense;
    	}
     
    	public int getName() {
    		return name;
    	}
     
    	public int getPV() {
    		return pv;
    	}
     
            /*...etc...*.
     
            public String toString() {
                  return name.toLowerCase();
            }
     
    }
    Avec ça, le résultat de l'exécution précédente affichera :
    Le premier personnage s'appelle David
    Le second personnage est un swordsman et s'appelle Justine
    Bon, ça fait beaucoup déjà et il y en a encore beaucoup à dire, en particulier sur la propagation (avec ce que je viens de montrer on ne peut pas choisir les informations de CharStats qu'on veut afficher et comment on veut les afficher à partir d'un code qui a la référence de Character, par exemple).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    septembre 2019
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : septembre 2019
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Merci encore pour toute ses précisions, j'ai pas mal travaillé dessus aujourd'hui, en utilisant tes conseils. J'ai essayé d'aller plus loin ( en essayant d'afficher des infos spécifiques de mes enum, voici comment je m'y suis pris :

    La classe Character
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    package core;
     
     
    import capacity.*;
     
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
     
    public class Character {
     
        // Pseudo
        private String nickname;
        // Genre (Male/Femelle/Non-binaire
        private final Gender gender;
        // Type (Tank/Epeiste/Archer/Mage)
        private final CharaStats specie;
        // Element (Feu/Eau/Vent/Tenebre/Lumière)
        private final Nature nature;
        // Etat (Neutre, Empoisonné, Paralisé, Brulé, Gelé, Endormie)
        private final Status status;
        // Lvl 0 à 100
        private byte level;
     
        private int speed;
        public List<Capacity> capacity;
     
     
        public Character(String nickname, Gender gender, byte level,  CharaStats  specie, Nature nature, Status status) {
            this.nickname = nickname;
            this.gender = gender;
            this.level = level;
            this.specie = specie;
            this.nature = nature;
            this.status = status;
     
            this.speed = specie.getSpeed();
     
        }
        public static void main(String[] args) {
            Character newChamp = new Character("JOJOLE",Gender.MALE,(byte)1, CharaStats.TANK, Nature.DARKNESS, Status.NEUTRAL) ;
            System.out.println(newChamp);
            System.out.println(
                    "\n" + "Your name is : " + newChamp.getNickname()+
                    "\n" + "Your gender is : "+ newChamp.gender +
                    "\n" + "Your abilities are : "+ newChamp.getCapacity() +
                    "\n" + "Your speed is : "+ newChamp.speed +
                    "\n" + "Your specie is : "+ newChamp .specie +
                    "\n" + "Your nature is : "+ newChamp .nature +
                    "\n" + "Your level is : "+ newChamp.getLevel() +
                    "\n");
        }
     
        public List<Capacity> getCapacity() {
            this.capacity = new ArrayList<>(Arrays.asList(specie.getCapacity()));
            capacity.add(nature.getCapacity());
            return capacity;
        }
     
        public String getNickname(){
            return nickname;
        }
       public int getLevel(){
            return level;
        }
     
        public String toString() {
            return "NickName: "+ nickname +", Gender: " + gender + ", level: " + level + ", Specie: " + specie + ", Nature: " + nature + ", status: " + status;
        }
    }

    La classe CharaStats
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    package core;
    import capacity.*;
     
    public enum CharaStats {
        TANK("Tank", 12500,750,600,95,120, new Capacity[]{Capacity.COLOSSUS_S_MIGHT, Capacity.RAPACITY}),
        SWORDSMAN("Swordsman", 10200,640,800,105,150,  new Capacity[]{Capacity.POISON_DAGGER, Capacity.BLADE_DANCE_OF_THE_REAPER}),
        ARCHER("Archer", 9180,540,900,120,130, new Capacity[]{Capacity.WEDGE_ARROW, Capacity.GRAVITY_ARROW}),
        MAGUS("Magus", 11000,600,500,110,200, new Capacity[]{Capacity.HELP_ME_TEDDY, Capacity.MAGIC_SHOT}),
        ;
        private final String name;
        private final int life;
        private final int defense;
        public int attack;
        public int speed;
        public int mana;
        public Capacity[] capacity;
     
        private CharaStats(String name, int life, int defense, int attack, int speed, int mana, Capacity[]capacity) {
            this.name=name;
            this.life=life;
            this.defense=defense;
            this.speed=speed;
            this.mana=mana;
            this.capacity = capacity ;
     
        }
     
        public Capacity[] getCapacity() {
            return capacity;
        }
     
        public void setCapacity(Capacity[] capacity) {
            this.capacity = capacity;
        }
     
        public String getName() {
            return name;
        }
     
        public int getLife() {
            return life;
        }
     
        public int getDefense() {
            return defense;
        }
     
        public int getAttack() {
            return attack;
        }
     
        public void setAttack(int attack) {
            this.attack = attack;
        }
     
        public int getSpeed() {
            return speed;
        }
     
        public void setSpeed(int speed) {
            this.speed = speed;
        }
     
        public int getMana() {
            return mana;
        }
     
        public void setMana(int mana) {
            this.mana = mana;
        }
    }
    Voila Capacity est une enum de capacités pour les personnages, j'ai utilisé le même principe que l'enum CharaStat.
    J'ai pas mal avancé mais pour l'instant je peux juste afficher le personnage créer dans le main haha, il me reste beaucoup à faire, je reviendrais dans le week end si je bloque.
    Si tu as des suggestions sur ce que j'ai déjà fais, n'hésites pas !

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    septembre 2009
    Messages
    11 794
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : septembre 2009
    Messages : 11 794
    Points : 27 819
    Points
    27 819
    Billets dans le blog
    2
    Par défaut
    Pourquoi des attributs non final et des setters dans CharaStats pour la mana, l'attaque, etc ? Ce sont des informations susceptible de varier dans le temps ? Et pourquoi des attributs public ?

    D'ailleurs, dans le constructeur de Character tu fais this.speed = specie.getSpeed();. Donc le speed de Character peut être différent dans le temps que le speed du specie/CharaStats de Character. Cela peut provoquer des dysfonctionnements difficiles à percevoir, à comprendre et/ou à corriger. Il vaut mieux laisser CharaStats gérer la vitesse et Character se fier à son specie pour.
    On peut mettre dans Character une méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public int getSpeed() {
        return specie.getSpeed();
    }


    Pour Capacity, pour simplifier le code, tu peux faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    public enum CharaStats {
        TANK("Tank", 12500,750,600,95,120,  Capacity.COLOSSUS_S_MIGHT, Capacity.RAPACITY),
      /*...*/
    ;
     
      /*...*/
     
        private CharaStats(String name, int life, int defense, int attack, int speed, int mana, Capacity... capacity) {
    Avec les varargs, on élimine la partie "création de tableau" et au final l'argument capacity est quand même un tableau.
    Cependant, avec ta syntaxe, comme avec la tienne, on n'oblige pas à avoir au moins une "capactity". Si on voulait le faire on pourrait faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        private CharaStats(String name, int life, int defense, int attack, int speed, int mana, Capacity capacity, Capacity... additionalcapacities) {
    Et faire dans le constructeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    this.capacity = Stream.concat(Stream.of(capacity), Stream.of(capacities)).toArray(Capacity[]::new);
    .

    Entre parenthèses :

    Tu peux utiliser la même syntaxe à la place de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public List<Capacity> getCapacity() {
            this.capacity = new ArrayList<>(Arrays.asList(specie.getCapacity()));
            capacity.add(nature.getCapacity());
            return capacity;
        }
    Attention aussi dans ce genre de code ci-dessus, il n'est pas normal qu'un getter change un état (capicity).

    Si c'est état est nécessaire (cache par exemple), à priori, les informations de specie et nature n'étant pas variable dans le temps, on peut construire cette liste à l'affectation. Si le temps de construction de la liste est négligeable par rapport à l'exécution globale (pour un rpg, le frame rate n'est pas crucial à priori), reconstruire la liste de capacity à chaque appel est envisageable.

    En plus, si le programme peut fonctionner en multi-process, on risque un état incohérent voire un conflit de concurrence d'accès (plantage donc). Dans tous les cas, il est préférable de ne pas utiliser un état.

    Attention aussi à la faculté de pouvoir modifier la liste, donc un état, à l'extérieure de la classe, ce qui peut provoquer des incohérences. Et également à ce que deux appels par deux entités différentes peuvent dans le cas général provoquer des incohérences dans la vision que ces deux entités ont de la liste de capacités... En résumé, dans le cas général, on ne fait pas ça à cause des risques que ça engendre : problèmes qui ne sont pas toujours aisés à comprendre lorsque le programme dysfonctionne et qu'il faut le déboguer. Mieux vaut prévenir que guérir



    L'appel du constructeur sera exactement le même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    TANK("Tank", 12500,750,600,95,120,  Capacity.COLOSSUS_S_MIGHT, Capacity.RAPACITY),
    On peut aussi vouloir tester si un charastats a une ou plusieurs capacités : stocker les capacités dans un Set facilitera ce genre de test. En plus ça garantira qu'on a pas affecter deux fois la même capacité, ce qui n'est pas très grave, mais ne sert à rien à priori, va consommer de la ressource superflue (mémoire et temps) et peut polluer les affichages.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public enum CharaStats {
        TANK("Tank", 12500,750,600,95,120, new Capacity[]{Capacity.COLOSSUS_S_MIGHT, Capacity.RAPACITY}),
    /*...*/
       ;
    /*...*/
        public Set<Capacity> capacities;
     
    private CharaStats(String name, int life, int defense, int attack, int speed, int mana, Capacity capacity, Capacity... additionalcapacities) {
        /*...*/
        this.capacities = EnumSet.of(capacity, additionalcapacities);
    }
    Pour tester l'appartenance d'une capacity :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public boolean hasCapacity(Capacity capacity) {
           return capacities.contains(capacity);
    }
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    public boolean hasCapacities(Capacity capacity, Capacity...capacities) {
          return this.capacities.containsAll(EnumSet.of(capacity,capacities));
    }
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        public boolean hasOneCapacity(Capacity capacity, Capacity...capacities) {
        	return EnumSet.of(capacity,capacities).stream()
        			      .anyMatch(this.capacities::contains);
        }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

Discussions similaires

  1. Appeler programme rpg depuis java
    Par chezdevelopping dans le forum IO
    Réponses: 1
    Dernier message: 15/02/2018, 10h34
  2. Javascript Array et java ArrayList
    Par bellNew dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 30/05/2011, 22h50
  3. Javascript Array vs java ArrayList
    Par bellNew dans le forum Développement Web en Java
    Réponses: 4
    Dernier message: 30/05/2011, 22h42
  4. debutant java arrayList
    Par mmanas dans le forum java.util
    Réponses: 3
    Dernier message: 21/11/2008, 16h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo