Bataille navale avec interface graphique

Fermé
mikis69 Messages postés 168 Date d'inscription mardi 26 novembre 2013 Statut Membre Dernière intervention 11 février 2019 - 22 mars 2014 à 16:22
mikis69 Messages postés 168 Date d'inscription mardi 26 novembre 2013 Statut Membre Dernière intervention 11 février 2019 - 24 mars 2014 à 22:55
Bonjour tout le monde,

Je suis étudiant en informatique et j'ai un projet de fin d'année à remettre pour le mois de mai.

J'ai choisis de faire une bataille navale avec une interface graphique.. (SWING obligatoire) (si vous avez d'autres idées de projet vous pouvez aussi me les faire partager)

J'ai juste une question concernant le plateau de jeu donc..

J'ai réfléchi à une manière de faire mon plateau de jeu et je n'arrive pas au résultat que je souhaite sauf en utilisant un tableau de boutons..

Je m'explique : le plateau de jeu sera constitué de cases : 10 X 10 (en abscisse les chiffres 0-9, en ordonnée les lettres A-J) chaque case aura donc une coordonnée de type A1, B0, C5, J9 ,...

Y aurait il un autre moyen 'normal' de faire ce plateau de jeu (sans boutons) ?

Car là, j'ai ma grille avec mes cases, où l'on peut cliquer dessus donc mais vous imaginez, faire 100 classes différentes pour 100 actions différentes en fonction du bouton sur lequel on va cliquer ? Car chaque bouton devra me renvoyer sa propre coordonnée de façon à ce que je puisse contrôler si sous cette case, il y a un bateau ou s'il y a de l'eau..

Donc voilà, je suis bien embêter..

Merci à ceux qui liront et répondront à mon message !

C'est dommage que l'on ne sait pas joindre d'images pour vous montrez le résultat mais je vous met le code de ma classe plateau :

package bataillemoi;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JPanel;

public class Plateau {
    private JPanel total;
    private JButton mesBoutons[] = new JButton[121];
    
    public Plateau() {

        JPanel grille = new JPanel();
        
        total = new JPanel(); // On crée le contenair qui aura le JLabel
        
        total.setLayout(new BorderLayout()); // On le positione ! Ici, mode par défaut
        
        grille = new JPanel();
        grille.setLayout(new GridLayout(11,11));
        
        int taille = 0, lettre = 65, numero = 0;
        for(int i=0;i<11;i++) {
            for(int j=0;j<11;j++) {
                mesBoutons[taille] = new JButton("");
                
                if(i==0&&j==0) mesBoutons[taille].setBackground(Color.BLACK);
                if(i==0&&j!=0) {
                    mesBoutons[taille].setText(""+numero);
                    mesBoutons[taille].setBackground(Color.ORANGE);
                    mesBoutons[taille].setForeground(Color.red);
                    mesBoutons[taille].setBorder(BorderFactory.createEtchedBorder(Color.blue, Color.red));
                    numero++;
                }
                if(j==0&&i!=0) {
                    mesBoutons[taille].setText(""+(char)lettre);
                    mesBoutons[taille].setBackground(Color.ORANGE);
                    mesBoutons[taille].setBorder(BorderFactory.createEtchedBorder(Color.blue, Color.red));
                    lettre++;
                }
                if(i>0&&j>0) {
                    mesBoutons[taille].setText(".");
                }
                
                grille.add(mesBoutons[taille]); 
                taille++;
            }
        }
        
        total.add(grille);
    }
    
    public JPanel getTotal() {
        return total;
    }
    
    public JButton[] getMesBoutons() {
        return mesBoutons;
    }
    
}





2 réponses

KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
22 mars 2014 à 19:33
"C'est dommage que l'on ne sait pas joindre d'images pour vous montrez le résultat"
C'est pour éviter les abus. Mais je te la mets ici. Je répondrais à ta question également, le temps de l'écrire.

public static void main(String[] args)
{
    Plateau plateau = new Plateau();
    
    JFrame frame = new JFrame();
    frame.setContentPane(plateau.getTotal());
    frame.pack();
    frame.setVisible(true);
}

0
KX Messages postés 16733 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 31 janvier 2024 3 015
22 mars 2014 à 20:01
Comme tu l'as fait, tes boutons sont enregistrés dans un tableau à une dimension, il peut déjà être bien de les mettre dans un tableau à deux dimensions pour conserver les coordonnées.

Mais dans ton cas cela ne suffira pas, car vu les interactions que tu attends il te faudra créer une classe (pas 100 hein !) pour définir chacune de tes cases. Dans cette classe, que l'on appellera Case par exemple, tu devras enregistrer le bouton (ou autre) qui te servira à représenter ta case côté swing, les coordonées de cette case au sein de la matrice (que je mettrais static dans Case plutôt que dans Plateau), ainsi que divers champs utiles pour ta case.

public class Case
{
    private static final Case[][] cases = new Case[10][10];
    
    public static Case getCase(int i, int j)
    {
        Case c = cases[i][j];
        
        if (c == null)
        {
            c = new Case(i, j);
            cases[i][j] = c;
        }
        
        return c;
    }
    
    private final JButton button;
    
    private final int x;
    private final int y;
    
    private Case(int x, int y)
    {
        if (cases[x][y] != null)
            throw new IllegalStateException("Case existe déjà");
        
        this.x = x;
        this.y = y;
        
        button = new JButton(toString());
        
        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                System.out.println("Je suis " + toString());
            }
        });
        
        cases[x][y] = this;
    }
    
    public JButton getButton()
    {
        return button;
    }
    
    @Override
    public String toString()
    {
        return String.format("[%c%d]", 'A'+x, y);
    }
}

Pour que ça marche tu n'as qu'à remplacer ce morceau de code :

if(i>0&&j>0) {
    mesBoutons[taille].setText(".");
}

Par celui-ci :

if (i>0 && j>0) {
    mesBoutons[taille] = Case.getCase(i-1, j-1).getButton();
}

Même si du coup, il n'est certainement plus utile de conserver le tableau
mesBoutons
, il faut repenser le programme autour de la grille des cases.
0
mikis69 Messages postés 168 Date d'inscription mardi 26 novembre 2013 Statut Membre Dernière intervention 11 février 2019
24 mars 2014 à 01:13
Bonsoir,

Merci pour ton aide, tes informations et ton temps !

Donc, j'ai regardé ce que tu m'as expliqué et j'ai bien réussi (je crois) à exprimer en code ce que tu m'as conseillé..

J'ai changé quelques trucs, du genre :
- Je change ce qu'il fait écrit sur les boutons..

Mais j'ai donc réussi à faire ma grille computer (car c'est sur cette grille que le joueur cliquera lorsqu'il voudra attaquer)
Quand on clique, il affiche : tu es sur -la où tu as cliqué- (en faisant un button.getText();) Mais c'est mauvais je pense.. Car si sur le bouton j'affiche un "." pour dire que le bouton n'a pas encore été cliqué, lorsque l'on cliquera dessus, il affichera : tu es sur .

Un problème se pose : A cause que la classe Case possède un tableau cases STATIC, je ne peux en créer qu'un seul ? Je ne peux pas créer deux plateaux qui utiliseront cette classe ?
(Je te demande ça car j'ai essayé de faire un plateau computer et un plateau player avec la même classe plateau et ça ne fonctionne pas. J'ai du faire un plateau computer avec la classe Case et un autre plateau player, avec mon ancienne classe Plateau..)

...

Je ne sais pas quoi dire d'autre car je n'arrive pas à visualiser la suite de ma programmation.. J'attend ta réponse, si tu arrives à comprendre ce que j'ai écrit et je te ferais parvenir la suite de mes idées..

Merci en tout cas !

Bonne nuit
0
mikis69 Messages postés 168 Date d'inscription mardi 26 novembre 2013 Statut Membre Dernière intervention 11 février 2019
24 mars 2014 à 22:55
Bonsoir,

Mis à jour : J'ai ajouté un setActionCommand à mes boutons (de la classe Case que tu m'as préparé). Maintenant peu importe le texte qui apparait sur le bouton, il me retourne sa coordonnée et c'est assez utile ^^

Donc, ma question reste la même comment puis je faire pour creer deux écrans de jeu (un pour le player et un pour le computer) qui soit de type plateau (en utilisant ta classe Case) ?
Car à cause du static final, j'ai l'impression de ne pouvoir créer qu'un seul écran, or il m'en faudrait deux..

Merci !
0