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 :

Déplacer correctement une représentation graphique d'un objet


Sujet :

JavaFX

  1. #1
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut Déplacer correctement une représentation graphique d'un objet
    Bonjour,

    Je suis actuellement entrain de réaliser un projet pour déplacer des poissons.
    Je dispose d'un model où chaque poisson dispose d'une méthode draw qui les dessine sur un Pane par l'intermédiaire d'une ImageView.
    Je me suis un peu renseigné pour les déplacer, mais il existe plusieurs techniques, et je ne sais pas vraiment laquelle utiliser.
    Mon poisson dispose d'une position courante (currentPos) et d'une liste de destination (ArrayList de (x,y)). J'aimerai pouvoir lui dire de se déplacer au premier couple (x,y). Arrivée à la destination, qu'il reparte vers une autre destination stocké dans ce même ArrayList.

    Comment puis-je procéder ? Serait-il une bonne idée d'utiliser la classe Transition ? Si oui, j'ai cru comprendre qu'on ne pouvait pas lui dire de faire quelque chose une fois l'animation terminée.

    Je vous remercie néanmoins des idées/solutions que vous pourrez me proposer !

  2. #2
    Modérateur
    Avatar de wax78
    Homme Profil pro
    Chef programmeur
    Inscrit en
    Août 2006
    Messages
    4 074
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chef programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2006
    Messages : 4 074
    Points : 7 978
    Points
    7 978
    Par défaut
    Citation Envoyé par LePtitBen Voir le message
    Si oui, j'ai cru comprendre qu'on ne pouvait pas lui dire de faire quelque chose une fois l'animation terminée.
    Bonjour, je pense que si, tu peux mettre un handler a la fin de l'Animation. Voire la méthode setOnFinished de la classe Animation. https://docs.oracle.com/javafx/2/api...Animation.html
    (Les "ça ne marche pas", même écrits sans faute(s), vous porteront discrédit ad vitam æternam et malheur pendant 7 ans)

    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Oh, effectivement, je suis passé à côté, merci beaucoup !

  4. #4
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Plus simple : créer une SequentialTransition composée de toutes les TranslateTransition.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  5. #5
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Merci de vos réponses, je vais essayer ça et je retourne vers vous si j'ai un soucis ! Merci encore !
    La seule question que je me pose. Imaginons que mon poisson je le supprime de mon model pendant la Transition. Comment faire en sorte que je supprime aussi l'imageView associé ? Je n'ai clairement pas trouvé de méthode qui testerait quelque chose à chaque état d'avancement de la transition.

  6. #6
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    J'ai pu tester quelques fonctionnalités. En effet, elle semble assez résoudre certains de mes soucis. Mais je me retrouve néanmoins avec un problème de coordonnée que je n'arrive pas à comprendre. Mon poisson se déplace dans l'espace de coordonnée de lui même, et non dans celui de l'écran. En effet, mon écran est de type Pane de taille 1280x720. Il est au centre et doit se rendre vers le coin supérieur gauche de l'écran (120,72). Néanmoins, quand je lance la transition, mon poisson se retrouve en dehors de l'écran, en bas à gauche, pour arriver vers son ancienne position décallé de 120,72 pixel. Ai-je mal compris quelque chose dans le système de coordonnée ?

    Je n'ai pour l'instant essayé qu'une seule transition et pas un enchainement.

    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
    public void draw(Object o, IFish fish){
            Pane pane = (Pane) o;
            try{
                String[] typeFish = fish.getName().split("_");
                FileInputStream inputstream = new FileInputStream("../fishes/" + typeFish[0] +".png"); 
                Image image = new Image(inputstream); 
                ImageView fishView = new ImageView(image);
                fishView.setLayoutX(((float)fish.getPosition().getX()/100)*pane.getWidth()); // Coordinates stored in the model are in percentage of the screen size
                fishView.setLayoutY(((float)fish.getPosition().getY()/100)*pane.getHeight());
                fishView.setFitHeight(100); 
                fishView.setFitWidth(100); 
     
                //Create the transition to the first destination
                TranslateTransition transition = new TranslateTransition(Duration.millis(5000),fishView);
                transition.setFromX(fishView.getLayoutX());
                transition.setFromY(fishView.getLayoutY());
                transition.setToX(((float)fish.getDestination().get(0).getX()/100)*pane.getWidth()); //Coordinates stored in the model are in percentage of the screen size
                transition.setToY(((float)fish.getDestination().get(0).getY()/100)*pane.getHeight());
                pane.getChildren().add(fishView);
                transition.play();
            }catch(FileNotFoundException error){
                error.printStackTrace();
            }
        }

  7. #7
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Un nœud se déplace dans le système de coordonnées de son parent et non pas dans celui de l'écran.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2020
    Messages
    17
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2020
    Messages : 17
    Points : 38
    Points
    38
    Par défaut
    Mais son parent ici est celui du Pane. Ca devrait fonctionner non ? Car j'ai le même soucis que lui pour un rectangle et un Pane.

  9. #9
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Peut-être que tes calculs sont mauvais.

    Voici un exemple avec 3 types de manière différentes de procéder au positionnement et à l'animation (mais il existe plein d'autre manières de faire).
    L'animation peut se faire :
    • Via une des transition pre-existantes
    • Via une timeline

    Tandis que le positionnement peut se faire :
    • via la propriété translateX et translateY.
    • via un positionnement absolu (ici centerX et centerY mais ca aurait aussi pu être layoutX ou layoutY)
    • via une transformation de type translation.



    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
    package test;
     
    import javafx.animation.*;
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ToolBar;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.shape.Circle;
    import javafx.scene.transform.Translate;
    import javafx.stage.Stage;
    import javafx.util.Duration;
     
    import java.util.Optional;
     
    final public class Main extends Application {
        final double width = 1000;
        final double height = 800;
        private Circle sprite;
        private Transition currentAnimation;
        private Timeline currentTimeline;
     
        public static void main(final String... args) {
            launch(args);
        }
     
        @Override
        public void start(final Stage stage) throws Exception {
            sprite = new Circle(10);
            final var animationPane = new Pane() {
                {
                    setMinWidth(width);
                    setMinHeight(height);
                    setPrefWidth(width);
                    setPrefHeight(height);
                    sprite.setFill(Color.RED);
                    sprite.setCenterX(0.5 * width);
                    sprite.setCenterY(0.1 * height);
                    getChildren().setAll(sprite);
                }
     
            };
            final var transitionPropertiesButton = new Button("Transition - translate properties");
            transitionPropertiesButton.setOnAction(event -> {
                stopAndReset();
                final var seg1 = new TranslateTransition();
                seg1.setNode(sprite);
                seg1.setToX(-0.4 * width);
                seg1.setToY(0.4 * height);
                seg1.setDuration(Duration.seconds(2));
                final var seg2 = new TranslateTransition();
                seg2.setNode(sprite);
                seg2.setToX(0);
                seg2.setToY(0.8 * height);
                seg2.setDuration(Duration.seconds(2));
                final var seg3 = new TranslateTransition();
                seg3.setNode(sprite);
                seg3.setToX(0.4 * width);
                seg3.setToY(0.4 * height);
                seg3.setDuration(Duration.seconds(2));
                final var seg4 = new TranslateTransition();
                seg4.setNode(sprite);
                seg4.setToX(0);
                seg4.setToY(0);
                seg4.setDuration(Duration.seconds(2));
                final var animation = new SequentialTransition();
                animation.getChildren().setAll(seg1, seg2, seg3, seg4);
                animation.setCycleCount(Animation.INDEFINITE);
                currentAnimation = animation;
                Platform.runLater(animation::play);
            });
            final var timelinePropertiesButton = new Button("Timeline - center properties");
            timelinePropertiesButton.setOnAction(event -> {
                stopAndReset();
                final var timeline = new Timeline();
                timeline.getKeyFrames().add(new KeyFrame(Duration.ZERO,
                        new KeyValue(sprite.centerXProperty(), 0.5 * width),
                        new KeyValue(sprite.centerYProperty(), 0.1 * height)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(2),
                        new KeyValue(sprite.centerXProperty(), 0.1 * width),
                        new KeyValue(sprite.centerYProperty(), 0.5 * height)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(4),
                        new KeyValue(sprite.centerXProperty(), 0.5 * width),
                        new KeyValue(sprite.centerYProperty(), 0.9 * height)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(6),
                        new KeyValue(sprite.centerXProperty(), 0.9 * width),
                        new KeyValue(sprite.centerYProperty(), 0.5 * height)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(8),
                        new KeyValue(sprite.centerXProperty(), 0.5 * width),
                        new KeyValue(sprite.centerYProperty(), 0.1 * height)));
                timeline.setCycleCount(Timeline.INDEFINITE);
                currentTimeline = timeline;
                Platform.runLater(currentTimeline::play);
            });
            final var timelineTransformButton = new Button("Timeline - transform");
            timelineTransformButton.setOnAction(event -> {
                stopAndReset();
                final var transform = new Translate();
                sprite.getTransforms().setAll(transform);
                final var timeline = new Timeline();
                timeline.getKeyFrames().add(new KeyFrame(Duration.ZERO,
                        new KeyValue(transform.xProperty(), 0),
                        new KeyValue(transform.yProperty(), 0)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(2),
                        new KeyValue(transform.xProperty(), -0.4 * width),
                        new KeyValue(transform.yProperty(), 0.4 * height)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(4),
                        new KeyValue(transform.xProperty(), 0),
                        new KeyValue(transform.yProperty(), 0.8 * height)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(6),
                        new KeyValue(transform.xProperty(), 0.4 * width),
                        new KeyValue(transform.yProperty(), 0.4 * height)));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(8),
                        new KeyValue(transform.xProperty(), 0),
                        new KeyValue(transform.yProperty(), 0)));
                timeline.setCycleCount(Timeline.INDEFINITE);
                currentTimeline = timeline;
                Platform.runLater(currentTimeline::play);
            });
            final var stopButton = new Button("Stop");
            stopButton.setOnAction(event -> stopAndReset());
            final var toolBar = new ToolBar();
            toolBar.getItems().setAll(transitionPropertiesButton, timelinePropertiesButton, timelineTransformButton, stopButton);
            final var root = new BorderPane();
            root.setTop(toolBar);
            root.setCenter(animationPane);
            final var scene = new Scene(root);
            stage.setTitle("Test");
            stage.setScene(scene);
            stage.setResizable(false);
            stage.show();
        }
     
        private void stopAndReset() {
            Optional.ofNullable(currentAnimation)
                    .ifPresent(Transition::stop);
            currentAnimation = null;
            Optional.ofNullable(currentTimeline)
                    .ifPresent(Timeline::stop);
            currentTimeline = null;
            sprite.setTranslateX(0);
            sprite.setTranslateY(0);
            sprite.setCenterX(0.5 * width);
            sprite.setCenterY(0.1 * height);
            sprite.getTransforms().clear();
        }
    }
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  10. #10
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    J'ai bien pris en compte ce que tu m'as dit. Mais mon poisson ne se trouve pas forcément au bon endroit. Par exemple, voilà ce que ça donne après deux transitions. Il devrait être en coordonnée (25,36) (coordonnée donné en paramètre pour le setToX setToY) mais termine à son ancienne position (environ 150,200). J'ai donc remarqué que les coordonnées du layoutX et layoutY de mon poisson à la fin de la transition ne sont pas celles de la Transition. Comment faire en sorte qu'elle soit aux bonnes valeurs ? J'ai voulu faire un setLayoutX et Y à la fin de la transition, mais crash de l'application. Je suppose donc que ce n'est pas ainsi que je dois procéder.
    Il y a t-il quelque chose que je n'ai pas compris avec les Layout ? Et la position d'une imageView ? Ou plus globalement une transition ^^.

    L'idée de base étant juste de déplacer mon imageView de manière fluide et en un temps donnée d'un point A vers un B, puis un point C etc (Mais en mettant à jour la position de l'imageView)

    Edit :

    J'ai essayé avec des KeyFrames, mais je n'en ai qu'une exécutée.. (Alors que j'en ai bien fait 2). Je suis directement parti à utiliser les setX et setY de mon imageView contre les LayoutX et layoutY.

    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
    Timeline timeline = new Timeline();
                for(int nbDest = 0; nbDest < destList.size() ; nbDest++){
                    KeyFrame move;
                    if(nbDest == 0){
                        double posDestX = ((float)destList.get(nbDest).getX()/100)*pane.getWidth();
                        double posDestY = ((float)destList.get(nbDest).getY()/100)*pane.getHeight();
                        KeyValue keyValueX = new KeyValue(fishView.xProperty(), posDestX);
                        KeyValue keyValueY = new KeyValue(fishView.yProperty(), posDestY);
                        move = new KeyFrame(Duration.millis(fish.getSpeed()*1000),keyValueX,keyValueY);
                    }else{
                        double posOldDestX = ((float)destList.get(nbDest-1).getX()/100)*pane.getWidth();
                        double posOldDestY = ((float)destList.get(nbDest-1).getY()/100)*pane.getHeight(); 
                        double posDestX = ((float)destList.get(nbDest).getX()/100)*pane.getWidth();
                        double posDestY = ((float)destList.get(nbDest).getY()/100)*pane.getHeight();
                        KeyValue keyValueX = new KeyValue(fishView.xProperty(), posDestX);
                        KeyValue keyValueY = new KeyValue(fishView.yProperty(), posDestY);
                        move = new KeyFrame(Duration.millis(fish.getSpeed()*1000),keyValueX,keyValueY);
                    }
                    timeline.getKeyFrames().add(move);
                }

  11. #11
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    les propriétés translateXXX, TranslateTransition (qui influent sur ces propriétés translateXXX) ou la transformation Translate (applique un transformation de translation sans toucher aux propriétés translateXXX) vient s'appliquer après le positionnement via layoutXXX. De plus dans l'ordre d'application, les propriétés layoutXXX s'appliquent avant les propriétés translateXXX qui s'appliquent elles-mêmes avant la liste des transforms.

    Si tu regardes mon code tu pourras voir que les animations 1 et 3 qui sont basées sur une translation (l'objet reste ancre a sa position d'origine et on le translate juste a sa nouvelle position une sorte de position "virtuelle") ont pas du tout les mêmes valeurs que l'animation 2 qui est basée sur une un déplacement absolu du centre (l'objet change réellement de position). Les valeurs des animations 1 et 3 sont donc relatives par rapport a la position initiale de l'objet tandis que l'animation 2 déplace réellement l'objet sur l’écran.

    Est-il possible de voir un peu plus de code de la classe FishView.
    Si cette classe étant bien ImageView ou est une variable de ce type, alors tu as un soucis de compréhension : les propriétés x et y servent d'origine pour le positionnement de l’image dans la vue ( (0,0) par défaut - l'image est affichée a partir du coin supérieur gauche de la vue) et ne servent pas du tout au positionnement de la vue dans son parent. Je reconnais que la doc est peu claire sur cette différence importante :

    The current x coordinate of the ImageView origin.

    The current y coordinate of the ImageView origin.

    Il vaut mettre ces 2 propriétés en relation avec le setter setViewport() ou encore les fitXXX en fait, bref tout ce qui a rapport avec la configuration de l'affichage de l'image dans la vue.

    As-tu essayé de créer une TimeLine qui change les valeurs des propriétés layoutX et layoutY de ton poisson a la place ?

    Et histoire de verifier que tes calculs sont bien corrects, as-tu tenté de faire une sortie textuelle ou encore placer graphiquement des points (ex: petit cercle rouge) aux coordonnées des lieux que tu as calculés lorsque tu calcules les positions de tes KeyFrame pour vérifier que ces positions étaient correctes a l'écran ?
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  12. #12
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Voilà mon code complet pour dessiner

    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
        public void draw(IFish fish){
            try{
                //We get the correct image link to the name.
                String[] typeFish = fish.getName().split("_");
                FileInputStream inputstream = new FileInputStream("../fishes/" + typeFish[0] +".png"); 
                Image image = new Image(inputstream); 
                ImageView fishView = new ImageView(image);
     
                //We give it a correct position in the scene
                double posX = ((float)fish.getPosition().getX()/100)*pane.getWidth();
                double posY = ((float)fish.getPosition().getY()/100)*pane.getHeight();
     
                fishView.setX(posX);
                fishView.setY(posY);
                fishView.setFitHeight(100); 
                fishView.setFitWidth(100); 
     
     
                //Create the transition to the correct destination
                ArrayList<Position> destList = fish.getDestination();
                final Timeline timeline = new Timeline();
                for(int nbDest = 0; nbDest < destList.size() ; nbDest++){
                    KeyFrame move;
                    if(nbDest == 0){
                        double posDestX = ((float)destList.get(nbDest).getX()/100)*pane.getWidth();
                        double posDestY = ((float)destList.get(nbDest).getY()/100)*pane.getHeight();
                        KeyValue keyValueX = new KeyValue(fishView.xProperty(), posDestX);
                        KeyValue keyValueY = new KeyValue(fishView.yProperty(), posDestY);
                        move = new KeyFrame(Duration.millis(fish.getSpeed()*1000), keyValueX,keyValueY);
                    }else{
                        double posOldDestX = ((float)destList.get(nbDest-1).getX()/100)*pane.getWidth();
                        double posOldDestY = ((float)destList.get(nbDest-1).getY()/100)*pane.getHeight(); 
                        double posDestX = ((float)destList.get(nbDest).getX()/100)*pane.getWidth();
                        double posDestY = ((float)destList.get(nbDest).getY()/100)*pane.getHeight();
                        KeyValue keyValueX = new KeyValue(fishView.xProperty(), posDestX);
                        KeyValue keyValueY = new KeyValue(fishView.yProperty(), posDestY);
                        move = new KeyFrame(Duration.millis(fish.getSpeed()*1000),keyValueX,keyValueY);
                    }
                    timeline.getKeyFrames().add(move);
                }
                timeline.setOnFinished(e -> {
                        System.out.println("Location after relocation = " + fishView.getX()
                                + "," + fishView.getY() + ")");
     
                });
                timeline.play();
                pane.getChildren().add(fishView);
            }catch(FileNotFoundException error){
                error.printStackTrace();
            }
        }
    Donc si j'ai bien compris, je ne devrais pas utiliser setX() et setY() même si je veux mettre en place une position réelle et non "virtuelle" avec les Translates ? Mais dans ce cas là, comment faire en sorte pour qu'à la fin de la TranslateTransition, j'ai effectivé bien bougé mon imageView et non pas de manière virtuelle comme j'avais ? (C'est à dire où son layoutX et layoutY ne changeait pas qu'importe la position avec le translate). Ce point là je n'arrive pas réellement à le comprendre ^^.

    Edit : J'ai modifié mon code pour n'utiliser que les LayoutX et LayoutY comme conseillé dans les keyFrames. J'ai donc utilisé les layoutXProperty() et layoutYProperty(). Je remarque bien que cette fois-ci les positions de LayoutX et LayoutY change. Néanmoins, j'ai toujours le problème évoqué plus haut avec la timeline : Je n'ai qu'une keyframe exécuté alors que j'en dispose de 2. Ai-je donc mal ajouté mes KeyFrames ?

  13. #13
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    Au final j'ai fait comme ca mais je ne suis pas totalement sur que ca soit la meilleure methode :

    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
    package test.animation2;
     
    import javafx.animation.KeyFrame;
    import javafx.animation.KeyValue;
    import javafx.animation.Timeline;
    import javafx.application.Application;
    import javafx.beans.property.DoubleProperty;
    import javafx.beans.property.SimpleDoubleProperty;
    import javafx.geometry.Point2D;
    import javafx.scene.Scene;
    import javafx.scene.control.ToggleButton;
    import javafx.scene.control.ToolBar;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.Pane;
    import javafx.scene.paint.Color;
    import javafx.scene.paint.CycleMethod;
    import javafx.scene.paint.LinearGradient;
    import javafx.scene.paint.Stop;
    import javafx.scene.shape.Circle;
    import javafx.stage.Stage;
    import javafx.util.Duration;
     
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Objects;
    import java.util.Optional;
     
    public class Main extends Application {
        public static void main(final String... args) {
            launch(args);
        }
     
        private FishView sprite;
     
        @Override
        public void init() throws Exception {
            final var tunaImage = new Image(getClass().getResource("BigeyeTuna.png").toExternalForm());
            sprite = new FishView(tunaImage);
        }
     
        private static final short WIDTH = 1000;
        private static final short HEIGHT = 800;
     
        @Override
        public void start(final Stage primaryStage) throws Exception {
            final var animationPane = new Pane();
            animationPane.setStyle("-fx-background-color: transparent;");
            animationPane.setMinWidth(WIDTH);
            animationPane.setMinHeight(HEIGHT);
            animationPane.getChildren().setAll(sprite);
            computeAllPositions(WIDTH, HEIGHT)
                    .stream()
                    .map(point -> new Circle(point.getX(), point.getY(), 5, Color.RED))
                    .forEach(animationPane.getChildren()::add);
            final var animateButton = new ToggleButton("Animate");
            animateButton.selectedProperty().addListener((observableValue, oldValue, newValue) -> {
                if (newValue) {
                    playAnimation();
                } else {
                    pauseAnimation();
                }
            });
            final var toolbar = new ToolBar();
            toolbar.getItems().setAll(animateButton);
            final var root = new BorderPane();
            root.setStyle("-fx-background-color: transparent;");
            root.setTop(toolbar);
            root.setCenter(animationPane);
            final var scene = new Scene(root);
            final var gradient = new LinearGradient(0, 0, 0, 1, true, CycleMethod.NO_CYCLE, new Stop(0, Color.AQUAMARINE), new Stop(0.25, Color.ROYALBLUE), new Stop(0.75, Color.NAVY), new Stop(1, Color.NAVY.darker().darker()));
            scene.setFill(gradient);
            primaryStage.setTitle("Test");
            primaryStage.setResizable(true);
            primaryStage.setScene(scene);
            primaryStage.show();
        }
     
        private List<Point2D> computeAllPositions(final double width, final double height) {
            final var result = new ArrayList<Point2D>(4);
            result.add(new Point2D(0.5 * width, 0.2 * height));
            result.add(new Point2D(0.2 * width, 0.5 * height));
            result.add(new Point2D(0.5 * width, 0.8 * height));
            result.add(new Point2D(0.8 * width, 0.5 * height));
            return result;
        }
     
        private Timeline currentAnimation;
     
        private void pauseAnimation() {
            Optional.ofNullable(currentAnimation)
                    .ifPresent(Timeline::pause);
        }
     
        private void stopAnimation() {
            Optional.ofNullable(currentAnimation)
                    .ifPresent(Timeline::stop);
        }
     
        private void playAnimation() {
            if (Objects.isNull(currentAnimation)) {
                final var image = sprite.getImage();
                final var positions = computeAllPositions(WIDTH, HEIGHT);
                final double halfWidth = sprite.getFitWidth() / 2d;
                // Does not appear to be properly computed.
                // final double halfHeight = sprite.getFitHeight()/2d;
                final double halfHeight = (image.getHeight() / image.getWidth()) * sprite.getFitWidth() / 2d;
                final DoubleProperty centerX = new SimpleDoubleProperty(0) {
                    @Override
                    protected void invalidated() {
                        sprite.setLayoutX(getValue() - halfWidth);
                    }
                };
                final DoubleProperty centerY = new SimpleDoubleProperty(0) {
                    @Override
                    protected void invalidated() {
                        sprite.setLayoutY(getValue() - halfHeight);
                    }
                };
                final var timeline = new Timeline();
                timeline.setCycleCount(Timeline.INDEFINITE);
                timeline.getKeyFrames().add(new KeyFrame(Duration.ZERO,
                        new KeyValue(centerX, positions.get(0).getX()),
                        new KeyValue(centerY, positions.get(0).getY())));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(2),
                        new KeyValue(centerX, positions.get(1).getX()),
                        new KeyValue(centerY, positions.get(1).getY())));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(4),
                        new KeyValue(centerX, positions.get(2).getX()),
                        new KeyValue(centerY, positions.get(2).getY())));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(6),
                        new KeyValue(centerX, positions.get(3).getX()),
                        new KeyValue(centerY, positions.get(3).getY())));
                timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(8),
                        new KeyValue(centerX, positions.get(0).getX()),
                        new KeyValue(centerY, positions.get(0).getY())));
                currentAnimation = timeline;
            }
            currentAnimation.play();
        }
     
        private static final class FishView extends ImageView {
            private static final short SPRITE_WIDTH = 100;
     
            public FishView(final Image image) {
                Objects.requireNonNull(image);
                setPreserveRatio(true);
                setFitWidth(100);
                setSmooth(true);
                setImage(image);
            }
        }
    }
    Nom : Untitled.jpg
Affichages : 671
Taille : 50,7 Ko
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  14. #14
    Membre régulier
    Homme Profil pro
    .
    Inscrit en
    Octobre 2018
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 25
    Localisation : France, Seine et Marne (Île de France)

    Informations professionnelles :
    Activité : .

    Informations forums :
    Inscription : Octobre 2018
    Messages : 62
    Points : 79
    Points
    79
    Par défaut
    Oh, j'ai compris mon erreur. J'ai mal interprété la signification de time dans le KeyFrame. Je croyais que c'était la durée d'exec et pas le temps de début sur la timeline.. Comme j'ai des durées potentiellement différente, ça ne correspond pas à mon problème. Il faudrait que je modifie la vitesse de la Timeline.. Ca m'a l'air bien plus complexe pour le problème que j'ai. Au final, je pense retomber sur TranslateTransition.. Faut-il encore que j'arrive à le placer correctement.. Car même en repassant sur des TranslateTransition, j'ai réussi à placer correctement son layoutX et layoutY. Mais, en visuel, l'imageView n'est vraiment pas au bonne endroit.. Je ne vais jamais m'en sortir ^^

  15. #15
    Rédacteur/Modérateur

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

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

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    C'est pour ca que j'ai crée une propriété centerX et centerY pour placer correctement mon ImageView avec le centre sur les points de passage.

    Du coup le soucis de TranslateTransition c'est que ça va placer le coin supérieur gauche de l'image sur les points de passage. Donc il te faut prendre en compte le décalage de longueur/2 et largeur/2 dans le calcul de leurs coordonnes.

    Je croyais que c'était la durée d'exec et pas le temps de début sur la timeline.. Comme j'ai des durées potentiellement différente, ça ne correspond pas à mon problème.
    En même temps si tu connais les durées de chaque segment tu peux calculer les temps de lancemen de chaque KeyFrame, et donc je vois pas trop ou est le soucis.
    Sinon en général si un truc est faisable avec une Transition, il est tout a fait faisable avec une Timeline.
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Question sur une représentation graphique
    Par lpndm dans le forum MATLAB
    Réponses: 13
    Dernier message: 11/12/2012, 20h22
  2. Réponses: 4
    Dernier message: 04/07/2012, 14h46
  3. [XL-2003] Faire une représentation graphique
    Par hortencia dans le forum Conception
    Réponses: 14
    Dernier message: 09/02/2012, 07h58
  4. [WD14] Comment faire une représentation graphique
    Par noviceman1 dans le forum WinDev
    Réponses: 5
    Dernier message: 16/01/2012, 09h46
  5. Aide pour creer une palette graphique sur un objet
    Par irsis60 dans le forum Services
    Réponses: 1
    Dernier message: 05/03/2010, 11h46

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