IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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

AWT/Swing Java Discussion :

Jeu d'échecs : utilisation de MouseListener


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2014
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2014
    Messages : 70
    Par défaut Jeu d'échecs : utilisation de MouseListener
    Bonsoir à tous,

    Actuellement en L3 info spécialité développement, j'ai voulu me lancer de mon côté dans la réalisation d'un jeu d'échec. J'ai pour l'instant commencé à implémenter les classes suivantes :

    - une classe abstraite Piece dont hériteront toutes les pièces. La classe Piece implémente les méthodes déplacer (que j'ai découpé pour l'instant en déplacement horizontal et vertical seulement, je pense créer ensuite une méthode déplacement en diagonale), une méthode deplacementCorrect redéfinie dans chacune des classes héritant de Piece et une méthode prendre, elle aussi à redéfinir.

    - une classe Square qui représente une case dans l'échiquier. Je lui attribue une couleur, un booléen pour savoir si elle est occupée, une coordonnée X et une coordonnée Y ainsi qu'un JPanel sur lequel je compte afficher la pièce.

    - une classe Pion qui me sert pour l'instant de test, elle n'implémente qu'une fonction deplacementCorrect pour l'instant, prenant en compte les spécificités d'un pion pour se déplacer.

    - enfin une classe Fenetre, elle possède un tableau de Square[8][8] faisant office d'échiquier. Ses méthodes initFrame et initChessboard permettent de créer la fenêtre et de colorier les cases de l'échiquier. Je tiens à préciser que la méthode displayPiece(Piece piece) est vouée à disparaître, elle me sert simplement pour l'instant car je ne souhaite n'afficher qu'une pièce et réussir à la faire se déplacer.

    A terme, je sais qu'une classe comme joueur qui possédera une liste de pièce est nécessaire mais je ne m'y suis pas encore attelé pour le moment.

    Ma principale interrogation se situe au niveau de l'interface graphique. J'en ai déjà fait quelques une auparavant (un 2048 par exemple, c'était donc simpliste, les mouvements ne se géraient qu'au clavier ou encore un launcher pour une société mais la encore, il n'y avait pas de MouseListener) mais je n'ai jamais utilisé réellement l'interface MouseListener. Je ne sais pas où mettre l'implémentation des méthodes de cette interface dans mon code. J'ai essayé d'associer à chaque JPanel un mouseListener en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     chessboard[i][j].getSquare().addMouseListener(new MouseListener() { ... }
    mais je n'y arrive pas. Je peux sélectionner la pièce mais je ne peux pas la déplacer car forcément, lorsque je clique sur un autre JPanel, je ne l'ai plus. Peut être que l'on peut faire de cette manière mais que mon code est mauvais, je ne sais pas.

    J'ai parcouru la discussion suivante http://www.developpez.net/forums/d13...chiquier-java/ et j'ai vu que la personne utilisait une classe privée, est-ce une bonne manière de faire ?

    N'étant qu'au début de mon projet, je suis ouvert à toute remarque car je préfère partir dans la direction la plus "propre" possible. Mes interrogations sont surtout au niveau de la partie graphique car il me semble que la partie fonctionnelle (les pièces, les mouvements) est assez claire, même si je sais que certains préféreraient utiliser une classe Deplacement.
    En bref, n'importe quelle remarque, qu'elle porte sur le fonctionnel ou l'IHM m'intéresse. N'hésitez donc pas à me dire si quelque chose vous fait hurler

    Ci-joint les 4 classes que j'ai pour l'instant implémenté.

    Classe Square (une case)
    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
    72
    73
    74
    75
    76
    77
    package fonctionnel;
     
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
     
    public class Square 
    {
    	private Piece piece;
    	private boolean black, occupied;
    	private int positionX, positionY;
    	private JPanel square; 
     
     
    	public Square(int positionX, int positionY, boolean black, boolean occupied) 
    	{
    		this.black = black;
    		this.occupied = occupied;
    		this.positionX = positionX;
    		this.positionY = positionY;
    		square = new JPanel();
    	}
     
    	public JPanel getSquare() {
    		return square;
    	}
     
    	public void setSquareImage(String nomImage) 
    	{
    		square.removeAll();
    		square.add(new JLabel(new ImageIcon(nomImage)));
    	}
    	public boolean isBlack() {
    		return black;
    	}
     
    	public void setBlack(boolean black) {
    		this.black = black;
    	}
     
    	public boolean isOccupied() {
    		return occupied;
    	}
     
    	public void setOccupied(boolean occupied) {
    		this.occupied = occupied;
    	}
     
    	public int getPositionX() {
    		return positionX;
    	}
     
     
    	public void setPositionX(int positionX) {
    		this.positionX = positionX;
    	}
     
     
    	public int getPositionY() {
    		return positionY;
    	}
     
     
    	public void setPositionY(int positionY) {
    		this.positionY = positionY;
    	}
     
    	public Piece getPiece()
    	{
    		return piece;
    	}
     
    	public void setPiece(Piece piece) {
    		this.piece = piece;
    		this.occupied = true; // C'est pas forcément beau, à voir si on garde comme ça 
    	}
    }
    Classe Piece
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    package fonctionnel;
     
     
    public abstract class Piece
    {
    	protected String nomImage;
    	protected int positionX, positionY;
    	protected final int value;
    	protected boolean black;
     
    	public Piece(int valeur, int positionX, int positionY, boolean estNoir, String nom)
    	{
    		this.value = valeur;
    		this.positionX = positionX;
    		this.positionY = positionY;
    		this.black = estNoir;
    		this.nomImage = nom;
    	}
     
    	public boolean deplacer(Square board[][], int departX, int departY, int arriveeX, int arriveeY)
    	{
     
    		// la méthode renverra un boolean pour savoir si le déplacement a pu être effectué
    		if(deplacementCorrect(board, departX, departY, arriveeX, arriveeY))
    		{
    			board[departX][departY].setOccupied(false);
    			board[arriveeX][arriveeY].setPiece(board[departX][departY].getPiece());// on déplace la pièce sur la case suivante
    			board[arriveeX][arriveeY].setSquareImage(board[arriveeX][arriveeY].getPiece().getNom()); // On affiche la pièce sur la nouvelle case
    			board[departX][departY].getSquare().removeAll(); // Suppression de l'image de la pièce
    			board[departX][departY].setPiece(null); // on indique que la case dont par la pièce est désormais vide
    			board[arriveeX][arriveeY].setOccupied(true); 
    			board[departX][departY].getSquare().repaint();
    			return true;
    		}	
    		return false;
    	}
     
    	protected abstract boolean deplacementCorrect(Square board[][], int departX, int departY, int arriveeX, int arriveeY);
     
     
    	// Méthode générique qui pourrait être réutilisé pour les pions, les tours, les reines et les rois
    	// Un déplacement horizontal effectue un déplacement sur les abscisses
    	protected boolean deplacementHorizontal(Square board[][], int departX, int departY, int arriveeX)
    	{
    		if(departX > arriveeX) // déplacement vers le bas
    		{
    			for(int i = departX-1; i > arriveeX; i--) // On part de la case à gauche de celle que l'on souhaite déplacer
    			{
    				if(board[i][departX].isOccupied()) // Si elle est occupée le déplacement est impossible
    				{
    					return false; // gérer le cas où l'on souhaite prendre la pièce
    				}
    			}
    			return true; 
    		}
    		else // déplacement vers le haut
    		{
    			for(int i = departX + 1; i <= arriveeX; i++)
    			{
    				if(board[i][departX].isOccupied())
    					return false;
    			}
    			return true;
    		}
    	}
     
    	// Un déplacement vertical effectue un déplacement sur les ordonnées
    	protected boolean deplacementVertical(Square board[][], int departX, int departY, int arriveeY)
    	{
    		if(departY > arriveeY) // déplacement vers la gauche
    		{
    			for(int i = departY - 1; i > arriveeY; i--)
    			{
    				if(board[i][departY].isOccupied())
    					return false;
    			}
    			return true;
    		}
    		else // déplacement vers la droite
    			for(int i = departY + 1; i < arriveeY; i++) 
    			{
    				if(board[i][departY].isOccupied())
    					return false;
    			}
    			return true;
    	}
     
    	protected void prendre()
    	{
     
    	}
     
    	public int getPositionX() {
    		return positionX;
    	}
     
    	public void setPositionX(int positionX) {
    		this.positionX = positionX;
    	}
     
    	public int getPositionY() {
    		return positionY;
    	}
     
    	public void setPositionY(int positionY) {
    		this.positionY = positionY;
    	}
     
    	public String getNom() {
    		return nomImage;
    	}
     
    	public void setNom(String nom) {
    		this.nomImage = nom;
    	}
    }
    Classe Pawn
    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
    package fonctionnel;
    public class Pawn extends Piece
    {
    	public Pawn(int positionX, int positionY, boolean estNoir)
    	{
    		super(1, positionX, positionY, estNoir, "pion");
    		//if(estNoir)
    		//	nom = "Images//" + nom + "Noir.jpg";
    		//else
    			nomImage = "Images//" + nomImage + "Blanc.jpg";
    	}
     
    	@Override
    	protected boolean deplacementCorrect(Square board[][], int departX, int departY, int arriveeX, int arriveeY)
    	{
    		if(deplacementVertical(board, departX, departY, arriveeX) && (arriveeY - departY) == 1) // un pion ne peut se d�placer que d'une case
    		{
    			return true;
    		}
     
    		return false;
    	}
     
    	private void evoluer()
    	{
     
    	}
    }
    Classe Fenetre
    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
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
     
    package interfaceGraphique;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
     
    import javax.swing.BorderFactory;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
     
    import fonctionnel.Square;
    import fonctionnel.Piece;
     
     
    public class Fenetre implements MouseListener{
     
    	private final int dimension = 8;
    	private JFrame frame = new JFrame("Echecs");
    	private Square chessboard[][] = new Square[dimension][dimension];
     
     
    	public Fenetre() 
    	{
    		initChessboard();
    		initFrame();
    		frame.addMouseListener(this);
    	}
     
    	private void initFrame()
    	{
    		frame.setSize(800, 800);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setResizable(false);
    		frame.setLocationRelativeTo(null);
    		frame.setLayout(new GridLayout(8,8,1,1));
    		frame.setVisible(true);
    	}
     
    	private void initChessboard()
    	{
    		for(int j = dimension -1; j >= 0; j--)// boucle ordonnées
    		{
    			for(int i = 0; i < dimension ; i++) // boucle abscisses
    			{
    				if((i + j) % 2 == 0) // permet d'obtenir un vrai 1/2 ce que  (j%2) ne permettait pas
    				{
    					chessboard[i][j] = new Square(i, j, true, false);
    					chessboard[i][j].getSquare().setBackground(new Color(128, 64, 0));
    				}
    				else
    				{
    					chessboard[i][j] = new Square(i, j, false, false);
    					chessboard[i][j].getSquare().setBackground(new Color(250,224,124));
    				}
    				chessboard[i][j].getSquare().setPreferredSize(new Dimension(50,50));
    				chessboard[i][j].getSquare().setBorder(BorderFactory.createLineBorder(Color.BLACK));
    				final int x = i, l = j;
     
    				chessboard[i][j].getSquare().addMouseListener(new MouseListener() {
     
    					Piece p;
    					@Override
    					public void mouseReleased(MouseEvent e) {}
     
    					@Override
    					public void mousePressed(MouseEvent e) {}
     
    					@Override
    					public void mouseExited(MouseEvent e) {}
     
    					@Override
    					public void mouseEntered(MouseEvent e) {}
     
    					@Override
    					public void mouseClicked(MouseEvent e) 
    					{
    						if(p == null)
    						{
    							p = chessboard[x][l].getPiece();
    						}
    						else
    						{
    							try
    							{
    								if(chessboard[x][l].getPiece() == null)
    								{	
    									System.out.println("ok");
    									chessboard[x][l].getPiece().deplacer(chessboard, x, l, x, l+1);		
    									frame.revalidate();
    									p = null;
    								}
    								else
    								{
    									System.out.println("case non vide");
    								}
    							}
    							catch(Exception ex){
    								System.out.println("case vide");
    								System.out.println("x : " + x + " y : " + l);
    							}
    						}
    					}
    				});
    				frame.add(chessboard[i][j].getSquare());
    			}
    		}
    	}
     
    	public void displayPiece(Piece piece)
    	{
    		chessboard[piece.getPositionX()][piece.getPositionY()].getSquare().add(new JLabel(new ImageIcon("Images/pionBlanc.jpg")));
    		frame.revalidate();
    	}
     
    	public Square getASquare(int i, int j) // ne retourne qu'une case de notre tableau, utilise pour set une piece
    	{
    		return chessboard[i][j];
    	}
     
    	@Override
    	public void mouseClicked(MouseEvent e) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void mousePressed(MouseEvent e) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void mouseReleased(MouseEvent e) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void mouseEntered(MouseEvent e) {
    		// TODO Auto-generated method stub
     
    	}
     
    	@Override
    	public void mouseExited(MouseEvent e) {
    		// TODO Auto-generated method stub
     
    	}
    }
    Mon petit main de test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    	public static void main(String[] args) 
    	{		
    		Fenetre fenetre = new Fenetre();
    		Pawn pion = new Pawn(4,1,true);
    		fenetre.displayPiece(pion);
    		fenetre.getASquare(pion.getPositionX(), pion.getPositionY()).setPiece(pion);
     
    	}
    Merci d'avance pour votre aide

    PS : J'ai finalement décidé pour ce projet de développer en utilisant la langue anglaise sauf pour les commentaires, si certaines variables ont encore un nom français, c'est un oubli de ma part

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    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 : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,
    Citation Envoyé par snyler Voir le message
    J'ai essayé d'associer à chaque JPanel un mouseListener en faisant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     chessboard[i][j].getSquare().addMouseListener(new MouseListener() { ... }
    mais je n'y arrive pas. Je peux sélectionner la pièce mais je ne peux pas la déplacer car forcément, lorsque je clique sur un autre JPanel, je ne l'ai plus.
    Si tu veux faire un déplacement du type "je clique sur un pion, puis je clique sur case, et le pîon va sur cette case", tu est obligé de gérer un état, qui te permet de savoir que quand tu cliques sur une case, il y a un pion en attente de déplacement, avec un algorithme du type :
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    clic sur pion :
    si pion en attente de déplacement alors annuler déplacement en attente
    sinon déplacement en attente égal le pion cliqué
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    clic sur case :
    si pion en attente de déplacement alors 
       déplacer pion en attente dans case cliquée
       rendre case d'origine vide
    fin si
    Il te faut donc que ton état (une variable) soit accessible depuis le mouselistener du pion et celui de la case. Au lieu de mettre une instance de MouseListener différente sur chaque pion et chaque case, tu peux utiliser une instance unique. Ou alors utiliser des classes internes et mettre l'état dans la classe parente, mais c'est plus compliqué si tu fais des classes séparées : le plus simple étant d'avoir un contrôleur unique. Ce contrôleur (une classe) peut avoir en variable membre l'état en question, va connaitre l'ensemble des pions et cases, et va leur affecter le et les mouselisteners, de manière à ce qu'ils aient tous accès à cet état. Quelque chose comme ça (rapidement écrit, donc abrégé) :
    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
    public class Controller {
        private List<Piece> pieces;
        private List<Square> squares;
        private Map<Piece, Square> locations; // pour mémoriser l'emplacement de chaque pièce (à initialiser au départ) 
        private Piece move;
     
         /*...*/
     
        // a appeler pour chaque piece
        public void addMouseListener(final Piece piece] {
              piece.addMouseListener(new MouseAdapter() { // MouseAdapter t'éviter d'avoir à mettre toutes les méthodes vides que tu n'utilises pas
                     public void mouseClicked(MouseEvent event) {
                             if ( move==null ) {
                                  move=piece;
                             }
                             else {
                                  move=null; // annulation
                             }
                             // updateDisplay(); // ou autre...
                     }
              });
        }
        // a appeler pour chaque case
        public void addMouseListener(final Square square] {
              square.addMouseListener(new MouseAdapter() { // MouseAdapter t'éviter d'avoir à mettre toutes les méthodes vides que tu n'utilises pas
                     public void mouseClicked(MouseEvent event) {
                             if ( move!=null ) {
                                  Sqaure currentSquare=locations.get(piece);
                                  if ( moveIsAllowed(square, move, currentSquare) {
                                     if ( moveIsCapture(square, move, currentSquare ) {
                                               // ...
                                     }
                                     square.setPiece(move); // déplacement
                                     currentSquare.setPïece(null); // supprimer piece depuis la case de départ
                                      locations.put(piece, square); // mémorise l'emplacement de la piece
                                      // updateDisplay(); // ou autre...
                                  }
                                  else {
                                       // afficher message "déplacement interdit"
                                  }
                             }
                     }
              });
        }
     
    }
    Tu peux utilser un MouseAdapter unique, en utilisant event.getSource() pour récupérer la pièce ou case à traiter.

    Autrement, si tu veux faire un déplacement continu, soit opter pour une technique de drag and drop, soit simuler un drag and drop simple, en passant par le GlassPane, ou un JLayer.
    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
    Membre confirmé
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2014
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2014
    Messages : 70
    Par défaut
    Tout d'abord, merci pour ta réponse.

    Citation Envoyé par joel.drigo Voir le message
    Salut,

    Si tu veux faire un déplacement du type "je clique sur un pion, puis je clique sur case, et le pîon va sur cette case", tu est obligé de gérer un état, qui te permet de savoir que quand tu cliques sur une case, il y a un pion en attente de déplacement
    C'est exactement ce que je souhaitais faire, l'algo que tu proposes est celui que je voulais mettre en place mais je ne voyais justement pas comment y arriver sans utiliser une instance unique de listener.

    Dans ce que tu proposes il y a des choses que je comprends et d'autres que je comprends moins. Par exemple, je ne comprends pas pourquoi chaque Piece a besoin d'un MouseListener. Ne peut-on pas avoir qu'un listener sur chaque case et à partir de cette case nous serons à même de récupérer la pièce grâce à la méthode getPiece() ?
    Pourtant, je comprends bien qu'il faut une variable "intermédiaire" nous permettant de savoir quelle pièce nous souhaitons déplacer (chose que je n'arrivais pas à mettre en place avec la solution que j'avais commencé à imaginer) est nécessaire.

    En fait, j'ai du mal à visualiser comment l'écouteur peut faire son travail sur une pièce qui au final n'est pas un élément graphique contrairement à Square qui contient un JPanel. Ma question est peut être simpliste mais j'avoue ne pas savoir, ayant toujours utilisé des listener que sur des boutons, des panels ou des frames.

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    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 : 12 430
    Billets dans le blog
    2
    Par défaut
    Je suis parti du principe que la pièce était un élément graphique (c'est bien quelque chose qu'on voit, n'est-ce-pas ?). Il y a différents moyens de faire bien sûr : on peut faire un JPanel ou un JLabel pour une case, et la pièce est juste une image qu'on affiche dans ce composant. On peut également faire un JPanel pour la case, et un JLabel pour la pièce : dans ce cas, on peut rendre le JLabel cliquable : dans ce cas, le clic est capté par le JLabel et la case qui contient une pièce ne reçoit pas de clic. Personnellement, j'aurais tout fait avec un seul panel et du dessin Java2D, bien plus libre pour faire tout ce qu'on veut, donc j'aurais eu un seul écouteur pour l'ensemble de l'échiquier). C'est dans cet esprit que j'ai écrit l'algorithme. Maintenant, si seule ta classe Square est un JPanel, l'écouteur sera bien techniquement sur la case, et il devra simplement tester :
    Code pseudocode : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    une case est cliquée :
    si il y a une pièce dans cette case alors
        traiter un clic de pièce
    sinon
        traiter un clic de case
    fin si
    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
    Membre confirmé
    Homme Profil pro
    Apprenti
    Inscrit en
    Octobre 2014
    Messages
    70
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Apprenti

    Informations forums :
    Inscription : Octobre 2014
    Messages : 70
    Par défaut
    De mon côté j'étais parti du principe suivant. Une case possède les attributs suivants
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    boolean occupee, black;// connaitre la couleur d'une case et si elle est occupée par une pièce ou non
    int positionX, positionY; // connaitre la place de la case sur l'échiquier
    JPanel square; // le panel qui permettra d'afficher la case en le coloriant et s'il n'est pas vide de superposer un JLabel dessus contenant le dessin de la pièce 
    Piece piece; // la pièce contenue par cette case
    Je peux donc savoir si une case est vide et je comptais donc faire grâce au listener quelque chose ressemblant à ceci
    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
    if(square.getPiece() == null) // la case est vide, il doit s'agir d'un mouvement
    {
    	if(pieceIntermediaire != null) // on vérifie que l'on a bien une pièce à faire bouger
    		{
    			// executer mouvement
    			// vider case dont part la pièce
    			pieceIntermediaire.setPiece(null);
    		}
    }
    else
    {
    	if(pieceIntermediaire == null) // aucune pièce n'a encore été sélectionnée
    	{
    		pieceIntermediaire = square.getPiece(); // manière simpliste, il faudra vérifier que c'est bien la pièce du joueur mais on en est pas encore là
    	}
    	else // on veut se déplacer sur une case occupée par une pièce
    	{
    		// vérifier si capture est possible ou s'il s'agit d'une pièce alliée
    	}
    }
    Je pense donc que cette ébauche est correcte dans les grandes lignes, maintenant c'est sur l'utilisation du listener que je bloque. Est-il possible de conserver l'idée du JPanel en superposant simplement un JLabel quand la pièce est dessus ou est-ce impossible de faire de cette manière la ?
    Comment faire pour conserver la pièce dans une variable pour la déplacer en utilisant simplement un JPanel pour chaque case ?

    Je suis désolé car j'ai l'impression que tu as déjà répondu à ma question dans une de tes réponses mais je n'arrive pas bien à comprendre.

  6. #6
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    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 : 12 430
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par snyler Voir le message
    Je peux donc savoir si une case est vide et je comptais donc faire grâce au listener quelque chose ressemblant à ceci
    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
    if(square.getPiece() == null) // la case est vide, il doit s'agir d'un mouvement
    {
    	if(pieceIntermediaire != null) // on vérifie que l'on a bien une pièce à faire bouger
    		{
    			// executer mouvement
    			// vider case dont part la pièce
    			pieceIntermediaire.setPiece(null);
    		}
    }
    else
    {
    	if(pieceIntermediaire == null) // aucune pièce n'a encore été sélectionnée
    	{
    		pieceIntermediaire = square.getPiece(); // manière simpliste, il faudra vérifier que c'est bien la pièce du joueur mais on en est pas encore là
    	}
    	else // on veut se déplacer sur une case occupée par une pièce
    	{
    		// vérifier si capture est possible ou s'il s'agit d'une pièce alliée
    	}
    }
    => au lieu de pieceIntermediaire.setPiece(null);, à priori pieceIntermediaire=null (puisque pieceIntermediaire = square.getPiece()).

    Citation Envoyé par snyler Voir le message
    Est-il possible de conserver l'idée du JPanel en superposant simplement un JLabel quand la pièce est dessus ou est-ce impossible de faire de cette manière la ?
    Comment faire pour conserver la pièce dans une variable pour la déplacer en utilisant simplement un JPanel pour chaque case ?
    Oui. Pas en superposant, mais en mettant le JLabel dans le JPanel.
    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. Projet Jeu d'échec
    Par Layla dans le forum Langage
    Réponses: 10
    Dernier message: 23/12/2010, 13h06
  2. L'empereur de Chine et le jeu d'échecs
    Par momo1367 dans le forum Pascal
    Réponses: 1
    Dernier message: 04/01/2008, 02h08
  3. Serveur de jeu d'échec en PHP
    Par S_Xavier dans le forum Langage
    Réponses: 3
    Dernier message: 20/10/2007, 15h02
  4. Fonction d'évaluation d'un jeu de dames utilisant l'algorithme du min/max
    Par elron8 dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 31/01/2007, 11h04
  5. Jeu d'échec borland soap
    Par rpoulin dans le forum Web & réseau
    Réponses: 2
    Dernier message: 20/10/2005, 05h02

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