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

JavaFX Discussion :

[JavaFX] Déplacement d'un jeton avec la souris - Scrabble


Sujet :

JavaFX

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2017
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2017
    Messages : 1
    Points : 1
    Points
    1
    Par défaut [JavaFX] Déplacement d'un jeton avec la souris - Scrabble
    Bonjour à tous,

    Je suis en train, du moins j'essaye, de réaliser un scrabble en Java et JavaFX.

    Débutant en JavaFX, j'essaye de me débrouiller avec les tutos qu'on trouve sur le net.
    Mais j'ai un peu de mal avec les événements de la souris, notamment le fais de déplacer un jeton du chevalet vers une case du plateau de jeu, en cliquant sur le jeton puis en cliquant sur la case du plateau où l'on veut mettre le jeton.

    Voici mon code:
    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
    154
    155
    156
    157
    158
    import javafx.application.Application;
    import javafx.event.EventHandler;
    import javafx.scene.Group;
    import javafx.scene.Scene;
    import javafx.scene.input.MouseEvent;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.stage.Stage;
     
     
    public class ScrabbleMain extends Application{
     
    	private double largeurPlat = 800;
        private double longueurPlat = 800;
     
        private int ligne = 15;
        private int colonne = 15;
     
        double largeurCase = largeurPlat / ligne;
        double longueurrCase = longueurPlat / colonne;
     
        Case[][] playfield = new Case[ligne][colonne];
       Jeton[][] chevaletJeton = new Jeton[7][1];
     
     
    	public static void main(String[] args) {
    		Application.launch(ScrabbleMain.class, args);
    	}
     
    	@Override
    	public void start(Stage primaryStage)
    	{
    		primaryStage.setTitle("Scrabble");
    		StackPane root = new StackPane();
    		Scene scenePrincipale = new Scene(root, 1200, 1000, Color.WHITE);	//Création de la scéne
     
     
    		Group grille = new Group();
    		 // initialize playfield
            for( int i=0; i < ligne; i++) {
                for( int j=0; j < colonne; j++) {
     
                    // create node
                	Case node = new Case(i, j, largeurCase, longueurrCase);
     
                    // add node to group
                    grille.getChildren().add(node);
     
                    // add to playfield for further reference using an array
                    playfield[i][j] = node;
     
                }
            }
            grille.setTranslateX(-20);
            grille.setTranslateY(-80);
            root.getChildren().add(grille);
     
            Group chevalet = new Group();
            for( int i=0; i < 7; i++) {
     
                // create node
                Jeton node = new Jeton(i, 0, largeurCase, longueurrCase);
     
                // add node to group
                chevalet.getChildren().add(node);
     
                // add to playfield for further reference using an array
                chevaletJeton[i][0] = node;
     
            }
            chevalet.setTranslateX(-20);
            chevalet.setTranslateY(400);
            root.getChildren().add(chevalet);
     
     
     
     
    		primaryStage.setScene(scenePrincipale);
    		primaryStage.show();
    	}
     
     
    	public static class Case extends StackPane {
     
        	Rectangle rectangle = new Rectangle();
            public Case(int x, int y, double largeur, double longueur) {
     
                // create rectangle
                Rectangle rectangle = new Rectangle( largeur, longueur);
                rectangle.setStroke(Color.WHITE);
                rectangle.setFill(Color.SEAGREEN);
     
     
     
                // set position
                setTranslateX(x * largeur);
                setTranslateY(y * longueur);
     
                getChildren().addAll(rectangle);
     
            }        
     
    	}
     
    	public static class Jeton extends StackPane {
     
        	Rectangle rectangle = new Rectangle();
            public Jeton(int x, int y, double largeur, double longueur) {
     
                // create rectangle
                Rectangle rectangle = new Rectangle( largeur, longueur);
                rectangle.setStroke(Color.WHITE);
                rectangle.setFill(Color.SEAGREEN);
     
     
     
                // set position
                setTranslateX(x * largeur);
                setTranslateY(y * longueur);
     
                this.setOnMouseEntered(new EventHandler<MouseEvent>(){
                    public void handle(MouseEvent me){
                    	rectangle.setFill(Color.LIGHTGREY);
                    }
                });
                this.setOnMouseExited(new EventHandler<MouseEvent>(){
                    public void handle(MouseEvent me){
                    	rectangle.setFill(Color.SEAGREEN);
                    }
                });
                this.setOnMousePressed(new EventHandler<MouseEvent>(){
                    public void handle(MouseEvent me){
                        appuyer(x, y);
                    }
                });
                this.setOnMouseReleased(new EventHandler<MouseEvent>(){
                    public void handle(MouseEvent me){
                        relacher(y);
                    }
                });
     
                getChildren().addAll(rectangle);
     
            }
     
            public void appuyer(int positionX, int positionY){
                rectangle.setFill(Color.DARKGREY);
                System.out.println(positionX+"/"+positionY);
            }
     
            public void relacher(int positionY){
            	rectangle.setFill(Color.WHITE);
            }
     
     
    	}
    }


    Bien cordialement

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 854
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 854
    Points : 22 878
    Points
    22 878
    Billets dans le blog
    51
    Par défaut
    Hum je sais que tu codes en français mais fait attention en général en anglais on utilise width et height, soit "largeur" et "hauteur" tandis que toi tu utilise "largeur" et "longueur" donc ça peut porter a confusion d'autant plus que tu fais immédiatement une inversion entre la ligne et la colonne lorsque tu mets en place ta grille.

    Ensuite on va commencer par nettoyer un peu le code :
    • Mettre des régions a la place des groupes. Ca permettra :
      • D'eviter que la taille ou le positionnement du groupe change quand son contenu change.
      • D'utiliser CSS plus facilement.
    • Introduire l'usage des CSS (ça évitera de mettre trop de directives de dessin dans le code.
    • Introduire l’usage des pseudo-classes qui vont permettre de colorier différemment les cases spéciales du plateau.
    • J'ai cherché également a supprimer la plupart des translations car ca rendait les calculs de positionnement inutilement complexes.
    • J'ai introduit deux calques (layers) :
      • Le premier contient le plateau de jeu et le chevalet, c'est ce que tu avais dans root avant.
      • Le second est un glass pane, une plaque de verre transparente a la souris et posée par dessus le plateau dans lequel on va pouvoir faire des animations en toute tranquillité.


    Voici ce que ça donne comme nouvelle base :

    Code CSS : 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
    .root {
    }
    .game-pane {
        -fx-padding: 10px 10px 50px 10px;
    }
    .glass-pane {
        -fx-padding: 10px 10px 50px 10px;
    }
    .grille {
        -fx-background-color: seagreen;
    }
    .case {
        -fx-border-color: paleturquoise;
        -fx-border-width: 0.5px;
    }
    .case:LETTRE_COMPTE_DOUBLE {   
        -fx-background-color: skyblue;
    }
    .case:LETTRE_COMPTE_TRIPLE {    
        -fx-background-color: deepskyblue;
    }
    .case:MOT_COMPTE_DOUBLE {
        -fx-background-color: salmon;     
    }
    .case:MOT_COMPTE_TRIPLE {    
        -fx-background-color: red;
    }
    .case:hover {
        -fx-background-color: lightgray;
    }
    .chevalet {
        -fx-border-color: black;
        -fx-background-color: darkgray;
    }
    .jeton {
        -fx-padding: 0.25em;
        -fx-border-color: blanchedalmond;
        -fx-background-color: beige;
    }
    .jeton:hover {
        -fx-border-color: red;
    }
    .jeton:pressed {
        -fx-border-color: darkred;
    }
    .jeton .letter {
        -fx-fill: black;
        -fx-font-size: 2em;
        -fx-font-weight: bold;
    }
    .jeton .weight {
        -fx-fill: black;
    }
    .jeton:pressed .letter {
        -fx-fill: darkred;
    }


    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
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    package scrabble;
     
    import java.util.Optional;
    import java.util.stream.IntStream;
    import javafx.animation.TranslateTransition;
    import javafx.application.Application;
    import javafx.css.PseudoClass;
    import javafx.geometry.Bounds;
    import javafx.geometry.Pos;
    import javafx.scene.Scene;
    import javafx.scene.layout.Pane;
    import javafx.scene.layout.StackPane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Rectangle;
    import javafx.scene.text.Text;
    import javafx.stage.Stage;
    import javafx.util.Duration;
    import org.scenicview.ScenicView;
     
    public class ScrabbleMain extends Application {
     
        private final double largeurPlat = 800;
        private final double longueurPlat = 800;
     
        private final int lignes = 15;
        private final int colonnes = 15;
     
        private final double largeurCase = largeurPlat / lignes;
        private final double longueurCase = longueurPlat / colonnes;
     
        private static final PseudoClass LETTRE_COMPTE_DOUBLE_PSEUDOCLASS = PseudoClass.getPseudoClass("LETTRE_COMPTE_DOUBLE");
        private static final PseudoClass LETTRE_COMPTE_TRIPLE_PSEUDOCLASS = PseudoClass.getPseudoClass("LETTRE_COMPTE_TRIPLE");
        private static final PseudoClass MOT_COMPTE_DOUBLE_PSEUDOCLASS = PseudoClass.getPseudoClass("MOT_COMPTE_DOUBLE");
        private static final PseudoClass MOT_COMPTE_TRIPLE_PSEUDOCLASS = PseudoClass.getPseudoClass("MOT_COMPTE_TRIPLE");
     
        Case[][] playfield = new Case[lignes][colonnes];
        Jeton[][] chevaletJeton = new Jeton[7][1];
     
        public static void main(String[] args) {
            Application.launch(ScrabbleMain.class, args);
        }
     
        private StackPane root;
        private Pane gamePane;
        private Pane glassPane;
        private Pane grille;
        private Pane chevalet;
     
        @Override
        public void start(Stage primaryStage) {
            gamePane = new StackPane();
            gamePane.setId("gamePane");
            gamePane.getStyleClass().add("game-pane");
            grille = new Pane();
            grille.setId("grille");
            grille.getStyleClass().add("grille");
            grille.setMinSize(largeurPlat, longueurPlat);
            grille.setPrefSize(largeurPlat, longueurPlat);
            grille.setMaxSize(largeurPlat, longueurPlat);
            // initialize playfield
            IntStream.range(0, lignes)
                    .forEach(ligne -> IntStream.range(0, colonnes)
                    .forEach(colonne -> {
                        // create node
                        Case aCase = new Case(colonne, ligne, largeurCase, longueurCase);
                        if (((colonne == 0) && (ligne == 0 || ligne == 7 || ligne == 14))
                                || ((colonne == 7) && (ligne == 0 || ligne == 14))
                                || ((colonne == 14) && (ligne == 0 || ligne == 7 || ligne == 14))) {
                            aCase.pseudoClassStateChanged(MOT_COMPTE_TRIPLE_PSEUDOCLASS, true);
                        }
                        if ((colonne == 7) && (ligne == 7)) {
                            aCase.pseudoClassStateChanged(MOT_COMPTE_DOUBLE_PSEUDOCLASS, true);
                        }
                        aCase.setOnMouseClicked(mouseEvent -> appuyerCase(ligne, colonne));
     
                        // add node to group
                        grille.getChildren().add(aCase);
     
                        // add to playfield for further reference using an array
                        playfield[ligne][colonne] = aCase;
                    }));
            gamePane.getChildren().add(grille);
     
            chevalet = new Pane();
            chevalet.setId("chevalet");
            chevalet.getStyleClass().add("chevalet");
            chevalet.setMinSize(7 * largeurCase, longueurCase);
            chevalet.setPrefSize(7 * largeurCase, longueurCase);
            chevalet.setMaxSize(7 * largeurCase, longueurCase);
            Character[] characters = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
            short[] values = {1, 3, 3, 2, 1, 4, 2};
            IntStream.range(0, 7)
                    .forEach(colonne -> {
     
                        // create node
                        Jeton jeton = new Jeton(colonne, 0, largeurCase, longueurCase, characters[colonne], values[colonne]);
                        jeton.setOnMousePressed(event -> appuyerJeton(colonne, 0));
                        jeton.setOnMouseReleased(event -> relacherJeton(colonne, 0));
     
                        // add node to group
                        chevalet.getChildren().add(jeton);
     
                        // add to playfield for further reference using an array
                        chevaletJeton[colonne][0] = jeton;
                    });
            StackPane.setAlignment(chevalet, Pos.BOTTOM_CENTER);
            gamePane.getChildren().add(chevalet);
            glassPane = new Pane();
            glassPane.setId("glassPane");
            glassPane.getStyleClass().add("glass-pane");
            glassPane.setMouseTransparent(true);
     
            root = new StackPane();
            root.getChildren().add(gamePane);
            root.getChildren().add(glassPane);
            final Scene scenePrincipale = new Scene(root, 1200, 1000, Color.WHITE);	//Création de la scéne
     
            primaryStage.setTitle("Scrabble");
            primaryStage.setScene(scenePrincipale);
            primaryStage.show();
            Optional.ofNullable(getClass().getResource("scrabble.css"))
                    .ifPresent(url -> scenePrincipale.getStylesheets().add(url.toExternalForm()));
            ScenicView.show(scenePrincipale);
        }
     
        public void appuyerJeton(int positionX, int positionY) {
            System.out.println(positionX+"/"+positionY);
        }
     
        public void relacherJeton(int positionX, int positionY) {
        }
     
        private void appuyerCase(final int ligne, final int colonne) {
             System.out.printf("clic sur case %d x %d%n", ligne, colonne);
        }
     
        private final static class Case extends StackPane {
     
            public Case(int x, int y, double largeur, double longueur) {
                setId("case");
                getStyleClass().add("case");
                setMinSize(largeur, longueur);
                setPrefSize(largeur, longueur);
                setMaxSize(largeur, longueur);
                // set position
                setTranslateX(x * largeur);
                setTranslateY(y * longueur);
            }
        }
     
        private final static class Jeton extends StackPane {
     
            private final Character character;
            private final short value;
            private Text letter;
            private Text weight;
     
            public Jeton(int x, int y, double largeur, double longueur, Character character, short value) {
                setId("jeton");
                getStyleClass().add("jeton");
                this.character = character;
                this.value = value;
                setMinSize(largeur, longueur);
                setPrefSize(largeur, longueur);
                setMaxSize(largeur, longueur);
                if (character != null) {
                    // create letter
                    letter = new Text();
                    letter.setId("letter");
                    letter.getStyleClass().add("letter");
                    letter.setText(String.valueOf(character));
                    getChildren().add(letter);
                    // create weight
                    weight = new Text();
                    weight.setId("weight");
                    weight.getStyleClass().add("weight");
                    weight.setText(String.valueOf(value));
                    StackPane.setAlignment(weight, Pos.BOTTOM_RIGHT);
                    getChildren().add(weight);
                }
                // set position
                setLayoutX(x * largeur);
                setLayoutY(y * longueur);
            }
        }
    }
    A voir si ce code te semble plus correct pour ce que tu veux faire.

  3. #3
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 854
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 854
    Points : 22 878
    Points
    22 878
    Billets dans le blog
    51
    Par défaut
    Voyons maintenant comment simuler le placement d'un jeton depuis le chevalet jusque sur une case du plateau :

    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
        private Jeton jeton;
     
        public void appuyerJeton(int positionX, int positionY) {
            System.out.println(positionX + "/" + positionY);
            jeton = chevaletJeton[positionX][positionY];
        }
     
        public void relacherJeton(int positionX, int positionY) {
        }
     
        private void appuyerCase(final int ligne, final int colonne) {
            System.out.printf("clic sur case %d x %d%n", ligne, colonne);
            if (jeton != null) {
                // Test.
                final Bounds source = jeton.localToScene(jeton.getBoundsInLocal());
                Rectangle rect1 = new Rectangle(0, 0, largeurCase, longueurCase);
                rect1.setFill(Color.RED);
                rect1.setLayoutX(source.getMinX());
                rect1.setLayoutY(source.getMinY());
                glassPane.getChildren().add(rect1);
                final Case aCase = playfield[ligne][colonne];
                final Bounds destination = aCase.localToScene(aCase.getBoundsInLocal());
                Rectangle rect2 = new Rectangle(0, 0, largeurCase, longueurCase);
                rect2.setFill(Color.BLUE);
                rect2.setLayoutX(destination.getMinX());
                rect2.setLayoutY(destination.getMinY());
                glassPane.getChildren().add(rect2);
                Rectangle rect3 = new Rectangle(0, 0, largeurCase, longueurCase);
                rect3.setFill(Color.YELLOW);
                glassPane.getChildren().add(rect3);
                final TranslateTransition anim = new TranslateTransition(Duration.seconds(2), rect3);
                anim.setFromX(source.getMinX());
                anim.setFromY(source.getMinY());
                anim.setToX(destination.getMinX());
                anim.setToY(destination.getMinY());
                anim.setOnFinished(event -> {
                    glassPane.getChildren().remove(rect1);
                    glassPane.getChildren().remove(rect2);
                    glassPane.getChildren().remove(rect3);
                });
                anim.play();
            }
        }
    il s'agit la d'une simulation. Mais ca devrait t'indiquer comment faire l'animation, il faut :

    • Retirer le jeton du chevalet.
    • Retirer son onMouseClicked()
    • Le placer dans le glass pane.
    • Faire l'animation a destination de la cellule.
    • Retirer le jeton du glass pane.
    • Le placer dans la grille par dessus les cellule et a la coordonne de la cellule cible.


    Évidement pour le jeu il faudra penser a créer une animation inverse en cas d'annulation de l'action du joueur (son mot est incorrect ou ne tient pas dans l'espace imparti) et remettre le onMouseClicked() sur le jeton quand on le replace dans le chevalet.

Discussions similaires

  1. déplacement d'objet 3d avec la souris XNA 4.0
    Par lwifi dans le forum XNA/Monogame
    Réponses: 1
    Dernier message: 27/11/2013, 09h49
  2. Réponses: 0
    Dernier message: 27/07/2011, 11h43
  3. Déplacement d'une DIV avec la souris
    Par PtitGénie dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 24/02/2009, 11h35
  4. Déplacement avec la souris dans un JScrollPane/JPanel
    Par deadstar62 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 27/04/2007, 17h10
  5. [JavaScript-Divs-Fenêtres] Déplacement avec la souris
    Par dontDeleteMe dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 09/02/2007, 16h58

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