Partage
  • Partager sur Facebook
  • Partager sur Twitter

Accèder à une méthode d'un objet instancié

TP Jeu de combat - Apprenez l’objet avec Java

Sujet résolu
    15 janvier 2019 à 11:04:29

    Bonjour,

    J'ai un problème pour accéder à une méthode se situant dans la classe de l'objet créé.

    Après avoir créé mes personnages, j'ai créé une classe Combat pour gérer les interactions lors du duel. Voici donc mon code qui montre la création de mes personnages et celui qui va les faire combattre en eux.

    CreationPersonnage.java

    public class CreationPersonnage{
        private int nbJoueur = 2;
        private int nbClasse;
        private int niveau;
        private int vitalite;
        private int force;
        private int agilite;
        private int intelligence;
        private String nameClasse;
        private Personnage joueur1;
        private Personnage joueur2;
    
    
        public Personnage getJoueurs(int id) {
            if(id == 1) {
                return joueur1;
            }else{
                return joueur2;
            }
        }
        
    
        
        // Getters, Setters et méthodes inutiles à mon problème
        
    
        
        /**
         * Création d'un personnage : ses caracteristiques et sa classe
         * @param id : 1 pour joueur1 et 2 pour joueur 2
         * @param nbClasse: 1 pour Guerrier, 2 pour Rodeur, 3 pour Mage
         */
        public void creerPersonnage(int id, int nbClasse){
            switch(id){
                case 1:
                    switch(nbClasse){
                        case 1:
                            this.joueur1 = new Guerrier(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                            break;
                        case 2:
                            this.joueur1 = new Rodeur(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                            break;
                        case 3:
                            this.joueur1 = new Mage(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                            break;
                    }
                    break;
                case 2:
                    switch(nbClasse){
                        case 1:
                            this.joueur2 = new Guerrier(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                            break;
                        case 2:
                            this.joueur2 = new Rodeur(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                            break;
                        case 3:
                            this.joueur2 = new Mage(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                            break;
                    }
                    break;
            }
        }
        /**
         * Creation des personnages
         * - Texte de description complète des personnages
         * - Création de chaque personnage
         */
        public void creerPersonnages() {
            for (int i = 1; i <= nbJoueur; i++) {
                System.out.println("Création du personnage du Joueur " + i);
                askClasse();
                askCaracteristiques();
                System.out.println("Woarg je suis le "+this.nameClasse+" Joueur "+i+" niveau "+this.niveau+", je possède "+this.vitalite+" de vitalité, "+this.force+" de force, "+this.agilite +" d'agilité et " +this.intelligence + " d'intelligence !\n");
    
                int id = i;
                switch(id){
                    case 1:
                        creerPersonnage(id, this.nbClasse);
                        break;
                    case 2:
                        creerPersonnage(id, this.nbClasse);
                        break;
                }
            }
        }
    }
    

    ActionsCombat.java

    public interface ActionsCombat {
        public int attaque(int id);
        public int attaqueSpeciale(int id);
        public int getDegats();
    }
    

    Guerrier.java

    public class Guerrier extends Personnage implements ActionsCombat {
        private int degats;
        private int attaque;
        private int attaqueSpeciale;
    
        public Guerrier(int id, int niveau, int vitalite, int force, int agilite, int intelligence) {
            super(id, niveau, vitalite, force, agilite, intelligence);
            super.setClasse("Guerrier");
            super.setAttaqueBasique("Coup d’Épée");
            super.setAttaqueSpeciale("Coup de Rage");
        }
    
        @Override
        public int getDegats() {
            return degats;
        }
    
        @Override
        public int attaque(int idJoueur){
            int forceCombattant = super.getJoueurs(idJoueur).getForce();
            System.out.println("Degats infligés "+ forceCombattant);
            return this.degats = forceCombattant;
        };
    
        @Override
        public int attaqueSpeciale(int idJoueur) {
            int forceCombattant = super.getJoueurs(idJoueur).getForce();
            return this.degats = forceCombattant*2;
        }
    
    }
    


    Combat.java

    public class Combat {
        private Personnage joueur1;
        private Personnage joueur2;
    
        public Combat(Personnage joueur1, Personnage joueur2) {
            this.joueur1 = joueur1;
            this.joueur2 = joueur2;
        }
    
        public Personnage getJoueurs(int id) {
            if(id == 1) {
                return joueur1;
            }else{
                return joueur2;
            }
        }
    
        public void start(Personnage joueur1, Personnage joueur2){
            Scanner sc = new Scanner(System.in);
            while(joueur1.getVitalite() != 0 || joueur2.getVitalite() != 0){
                for(int i = 1; i <= 2; i++){
                    System.out.println("Joueur "+ getJoueurs(i).getId()+" ("+ getJoueurs(i).getVitalite()+") veuillez choisir votre action (1 : Attaque Basique, 2 : Attaque Spéciale)");
                    int attaque = sc.nextInt();
                    faireDegats(i, attaque);
                }
            }
        };
    
        public void faireDegats(int id, int attaque){
            switch(attaque){
                case 1:
                    System.out.println("Joueur "+id+" utilise "+getJoueurs(id).getAttaqueBasique()+" et inflige "+getJoueurs(id).attaque(o));
                    break;
                case 2:
                    System.out.println("Joueur "+id+" utilise "+getJoueurs(id).getAttaqueSpeciale());
                    break;
            }
        }
    
    }
    

    Mon blocage se situe dans cette classe Combat et plus précisément dans la méthode:

    faireDegats(int id, int attaque);

    Admettons que l'un des personnages créé est un guerrier.

    Donc comme le montre la classe CreationPersonnage et la méthode creerPersonnage(int id, int nbClasse), j'instancie mon objet :

     this.joueur1 = new Guerrier(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);

    J'accède bien à tous les paramètres de mon objet Guerrier mais pas au méthode de la classe. J'aurai voulu idéalement faire ( comme je l'ai laissé volontairement dans le code de ma classe Combat et dans la métgode faireDegats(int id, int attaque) ):

    getJoueurs(id).attaque();


    Mais getJoueur(id) qui se trouve être un objet Guerrier n'accède pas à cette méthode.


    Dois je ré-instancier un objet de la classe Guerrier pour accéder à attaque() alors que le joueur créé est deja de type Guerrier ?

    Dois je plutôt coder mes méthodes attaque() et attaqueSpeciale() directement dans ma classe Combat et donc recréer des conditions selon la classe du joueur?

    Toutes les idées qui me viennent en tête me plaisent pas trop, j'ai l'impression que je vais alourdir le code...

    Merci pour l'aide et désolé du pavé, j'ai essayé d'etre le plus clair possible.

    -
    Edité par Weyn_ 15 janvier 2019 à 11:07:22

    • Partager sur Facebook
    • Partager sur Twitter
      15 janvier 2019 à 12:26:17

      Bonjour,

      - Si tous tes personnages peuvent se battre, mets les méthodes attaque() et attaqueSpeciale() dans la classe Personnage en abstract et le tour est joué.

      - Si ce n'est pas le cas, il faut que les joueur qui se battent possèdent l'interface ActionCombat. Ce ne peut être de simples personnages. Il faut donc veiller à les instancier comme tel. Voici un petit example de ce que tu peux faire. J'ai changer "ActionCombat" par "Combattant" pour que ce soit plus transparent et "Arene" à la place de "Combat":

      public interface Combattant {
      	public void attaque();
      }
      public class Arene {
      	public Combattant creerPersonnage(int type) {
      		switch(type) {
      			case 1: return new Guerrier();
      			case 2: return new Mage();
      			default: return null;
      		}
      	}
      }
      public class Guerrier extends Personnage implements Combattant{
      
      	public void attaque() {
      		System.out.println("Coup d'épée");
      	}
      }
      public class Debut {
      	public static void main(String[] str) {
      		Arene arene = new Arene();
      		Combattant joueur1= arene.creerPersonnage(1);
      		Combattant joueur2 = arene.creerPersonnage(2);
      		
      		joueur1.attaque();
      		joueur2.attaque();
      	}






      • Partager sur Facebook
      • Partager sur Twitter
        16 janvier 2019 à 10:38:33

        Merci pour ta réponse @rtur

        Je suis dans le premier cas.

        Donc effectivement, j'arrive bien à accéder à mes méthodes mais celle ci me retourne null si je fais appelle à elles depuis Combat (dans faireDegats()):

        getJoueur(id).attaque(id)

        Revoici mes classes modifiées :

        Personnage.java

        public abstract class Personnage{
            
        ...
        ...
        ...

          public abstract int attaque(int id); public abstract int attaqueSpeciale(int id); public abstract int getDegats(); }

        Combat.java

        public class Combat {
            private Personnage joueur1;
            private Personnage joueur2;
        
            public Combat(Personnage joueur1, Personnage joueur2) {
                this.joueur1 = joueur1;
                this.joueur2 = joueur2;
            }
        
            public Personnage getJoueurs(int id) {
                if(id == 1) {
                    return joueur1;
                }else{
                    return joueur2;
                }
            }
        
            ...
            ...
            ...
        
            public void faireDegats(int id, int attaque){
                switch(attaque){
                    case 1:
                        System.out.println("Joueur "+id+" utilise "+getJoueurs(id).getAttaqueBasique()+" et inflige "+getJoueurs(id).attaque(id));
                        break;
                   
                    ...
                    ...
                    ...
                }
            }
        }

        Guerrier.java

        package com.maxim.personnages;
        
        public class Guerrier extends Personnage {
            private int degats;
            private int attaque;
            private int attaqueSpeciale;
        
            public Guerrier(int id, int niveau, int vitalite, int force, int agilite, int intelligence) {
                super(id, niveau, vitalite, force, agilite, intelligence);
                super.setClasse("Guerrier");
                super.setAttaqueBasique("Coup d’Épée");
                super.setAttaqueSpeciale("Coup de Rage");
            }
        
            public int getDegats() {
                return degats;
            }
        
            public int attaque(int idJoueur){
                int forceCombattant = super.getJoueurs(idJoueur).getForce();
                return this.degats = forceCombattant;
            };
        
            public int attaqueSpeciale(int idJoueur) {
                int forceCombattant = super.getJoueurs(idJoueur).getForce();
                return this.degats = forceCombattant*2;
            }
        
        }
        



        Après j'ai une autre solution en codant mes méthodes attaque() et attaqueSpeciale() de chaque classe dans Combat mais bon j'aimerai éviter car avoir des noms de méthode comme attaqueMage() ou attaqueSpecialeRodeur(), je ne trouve pas cela très propre.

        -
        Edité par Weyn_ 16 janvier 2019 à 11:17:44

        • Partager sur Facebook
        • Partager sur Twitter
          16 janvier 2019 à 13:09:45

          Bonjour,

          Tout d'abord, dans le code que je vois, tu n'instancie pas les personnages. Tu peux le faire:

          - directement (joueur1 = new Guerrier)

          - ou via une méthode getPersonnage(int type).

          Ensuite, tu gagnerais en lisibilité à passer un Personnage en paramètre de tes méthodes attaque() et attaqueSpeciale() plutôt que de passer l'identifiant du personnage.

          Je mets ci-dessous le code simplifié de ce que tu veux faire:

          public class Combat {
          
          	private static Personnage creerPersonnage(int type) {
          		switch(type) {
          		case 1: return new Guerrier();
          		case 2: return new Mage();
          		default: return null;
          		}
          	}
          	
          	public static void main(String[] str) {
          		Personnage joueur1 = creerPersonnage(1);
          		joueur1.setNom("IronMan");
          		Personnage joueur2 = creerPersonnage(2);
          		joueur2.setNom("Mistika");
          		
          		joueur1.attaque(joueur2);
          		joueur2.attaque(joueur1);
          	}
          }
          public abstract class Personnage {
          	private String nom;
          	
          	public abstract void attaque(Personnage joueurAttaque);
          	
          	public String getNom() {
          		return nom;
          	}
          	
          	public void setNom(String nom) {
          		this.nom = nom;
          	}
          }
          public class Guerrier extends Personnage{
          
          	public void attaque(Personnage joueurAttaque) {
          		System.out.println(this.getNom() + " donne un coup d'épée à " + joueurAttaque.getNom());
          	}
          }





          • Partager sur Facebook
          • Partager sur Twitter
            16 janvier 2019 à 13:57:21

            @rtur a écrit:

            Tout d'abord, dans le code que je vois, tu n'instancie pas les personnages. Tu peux le faire:

            - directement (joueur1 = new Guerrier)

            - ou via une méthode getPersonnage(int type).

            En fait, je l'instancie dans la classe CreationPersonnage (voir le tout premier post)

            Avec un Scanner, je récupère le type de classe, le niveau et les caractéristiques saisis par l'utilisateur. Et ensuite, selon le numero de la classe choisie, j'instancie en conséquence.

                /**
                 * Création d'un personnage : ses caracteristiques et sa classe
                 * @param id : 1 pour joueur1 et 2 pour joueur 2
                 * @param nbClasse: 1 pour Guerrier, 2 pour Rodeur, 3 pour Mage
                 */
                public void creerPersonnage(int id, int nbClasse){
                    switch(id){
                        case 1:
                            switch(nbClasse){
                                case 1:
                                    this.joueur1 = new Guerrier(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                                    break;
                                case 2:
                                    this.joueur1 = new Rodeur(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                                    break;
                                case 3:
                                    this.joueur1 = new Mage(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                                    break;
                            }
                            break;
                        case 2:
                            switch(nbClasse){
                                case 1:
                                    this.joueur2 = new Guerrier(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                                    break;
                                case 2:
                                    this.joueur2 = new Rodeur(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                                    break;
                                case 3:
                                    this.joueur2 = new Mage(id, this.niveau, this.vitalite, this.force, this.agilite, this.intelligence);
                                    break;
                            }
                            break;
                    }
                }
                /**
                 * Creation des personnages
                 * - Texte de description complète des personnages
                 * - Création de chaque personnage
                 */
                public void creerPersonnages() {
                    for (int i = 1; i <= nbJoueur; i++) {
                        System.out.println("Création du personnage du Joueur " + i);
                        askClasse();
                        askCaracteristiques();
                        System.out.println("Woarg je suis le "+this.nameClasse+" Joueur "+i+" niveau "+this.niveau+", je possède "+this.vitalite+" de vitalité, "+this.force+" de force, "+this.agilite +" d'agilité et " +this.intelligence + " d'intelligence !\n");
             
                        int id = i;
                        switch(id){
                            case 1:
                                creerPersonnage(id, this.nbClasse);
                                break;
                            case 2:
                                creerPersonnage(id, this.nbClasse);
                                break;
                        }
                    }



            En tout cas, merci.

            Je regarde ce que tu m'as donné et je vois si je peux intégrer l'idée à mon code.

            Edit:

            J'ai suivi ce que tu m'as dit en mettant plutôt Personnage en paramètre de mes méthodes attaque() et attaqueSpeciale(). Et j'ai fait de même pour mes méthodes dans la Classe Combat.

            Effectivement maintenant tout est plus clair et tout fonctionne comme cela devrait.

            Merci encore @rtur! ;)

            -
            Edité par Weyn_ 16 janvier 2019 à 15:24:17

            • Partager sur Facebook
            • Partager sur Twitter

            Accèder à une méthode d'un objet instancié

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown