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 :

Synchronisation de multiples animations


Sujet :

JavaFX

  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 13
    Points : 8
    Points
    8
    Par défaut Synchronisation de multiples animations
    Bonjour,

    Dans le cadre d'un projet scolaire, je modélise une machine de Turing à l'aide de JavaFX.
    J'utilise pour ce faire toute une panoplie d'animations dépendantes les unes des autres et pour l'instant, je n'arrive pas à les synchroniser correctement.
    J'ai pour l'instant diviser mon code en deux méthodes.

    La première permet de gérer un événement en créant une boucle qui, à chaque passage lance une animation dépendant de la précédente. Je dis "dépend", parce que l'exécution de l'animation précédente met à jour certaines variables nécessaire à la création de l'animation en cours. Graphiquement, à chaque tour de boucle, je voudrait déplacer mon curseur, changer la couler de deux bulles différentes (une en bleu, une en rouge) et changer un label. J'ai regrouper c'est 4 (+ une pause) animations à l'aide d'une transitions séquentielle.

    La deuxième (appelée par la première) permet d'initialiser ces variables et de créer l'animation. J'ai rajouter quelques commentaires dans mon code pour que vous compreniez plus ou moins ce que fait chaque partie. Je tiens à préciser que les tableaux utilisés sont définis dans d'autres méthodes et que mon code compile (sauf quand il veut lancer une animation avec de valeurs pas à jour).

    Voici en plus deux variables déclarées globalement:
    private int state;
    private int posRuban;

    Méthode 1:
    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
     
    	public void handleRemoteAction(ActionEvent event) throws IOException{ 
     
    		state = 0;
    		posRuban = 0;
    		SequentialTransition animation;
     
            if(event.getSource()==play){ //mon événement déclencheur
     
            	while(state < transitions.length-1){
     
            		//L'appel renvoie une nouvelle annimation à chaque passage 
            		//dans la boucle et incrémente "state"      
            		animation = initAnimation(); 
            		animation.play();       		
            	}
     
            } 
     
    	}

    Méthode 2:
    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
     
    	public SequentialTransition initAnimation() {
     
    		String value;
    		NextMove move;
     		int v = -1;
     		final int j = posRuban;
     		final int exState;
     		final int newState;
     		final String newVal;
     
     		//Déclaration de l'animation principale.
    		final SequentialTransition masterAnimation = new SequentialTransition(); 
     
    		//Déclaration des 5 types d'animations secondaires.
    		final PauseTransition rest = new PauseTransition(Duration.seconds(10));
    		final TranslateTransition shift = new TranslateTransition(Duration.seconds(2), cursor);
    		final Transition changeRubanValue;
    		final Transition changeExStateColor;
    		final Transition changeNewStateColor;
     
     
    		value = ruban[posRuban].getValueLabel(); 
     
    		// Création de l'animation de type 1.        		
    		exState = state;
    		changeExStateColor = new Transition(){ 
    		 	{setCycleDuration(Duration.seconds(5));}
    		 	public void interpolate(double frac) {bulles[exState].setFill(Color.RED);}
    		};
     
    		//Mise à jour des différentes variables
    		for (int incr=0; incr < variables.length; incr++){
    			if (value.equals(variables[incr])){v = incr;}
    		}
    		move = (transitions[state][v]);
     
    		value = move.getVar();
    		state = move.getState();
     
    		// Création de l'animation de type 2. 	
    		newVal = value ;
    		changeRubanValue = new Transition(){ 
    		 	{setCycleDuration(Duration.seconds(2));}
    		 	public void interpolate(double frac) {ruban[j].setValueLabel(newVal);}
    		};
     
    		// Paramétrisation de l'animation de type 3. 	
    		if (move.getDir()){
    			shift.setByX(70); 
    			posRuban = posRuban + 1;}
    		else{
    		 	shift.setByX(-70);; 
    		 	posRuban = posRuban - 1;
    		 	};
     
    		// Création de l'animation de type 4.
    		newState = state;
    		changeNewStateColor = new Transition(){ 
    			{setCycleDuration(Duration.seconds(2));}
    		 	public void interpolate(double frac) {bulles[newState].setFill(Color.AQUA);}
    		};
     
    		// ajout des animations de type 1,2,3,4 et 5 à l'animation principale.
    		changeNewStateColor.setOnFinished(ActionEvent -> changeRubanValue.play());
    		changeRubanValue.setOnFinished(ActionEvent -> changeExStateColor.play());	
    		masterAnimation.getChildren().addAll(changeNewStateColor,shift,rest);
     
    		//Renvoie l'animation principale.
        	return masterAnimation; 
    	}
    D'après mes observations, en ce moment il exécute d'abord toutes les animations de type 1, puis toutes celles de type 2, etc... Au lieu de faire 1,2,3,4,5,1,2,3,4,5...
    Merci d’avance à toute personne qui me fournira un élément de réponse!

  2. #2
    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
    SequentialTransition, comme son nom l'indique c'est une animation séquentielle donc avec le contenu qui s’exécute en séquence, c'est a dire a la queue-leu-leu... C'est ParallelTransition que tu cherches je pense.

    Sinon tu peux aussi construire une unique TimeLine avec toutes tes KeyFrames et KeyValue dedans.
    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

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Merci Bouye!
    Non, c'est bien une transition séquentielle que je veux. Ça permet à l'utilisateur de mieux comprendre ce qu'il se passe. Si j'utilise des animations parrallèle, il n'arrivera pas à suivre tout je pense (mais je vérifierai quand mon autre problème sera régler).

    J'avais déjà tenter d'utiliser une Timeline sans arriver à quelque chose de concluant, mais comme j'ai modifié certaine chose depuis, je vais quand même réessayé.

    Je posterai mes résultats plus tard dans la journée! En attendant, si d'autre personnes ont des suggestions, qu'elles n'hésitent pas à les poster, ça pourra toujours aider!

  4. #4
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Hello,

    Voici la nouvelle version de mon code, qui utilise un Timeline. Le problème reste malheureusement le même, mais je pense avoir gagné en clarté.


    Méthode 1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    public void handleRemoteAction(ActionEvent event) throws IOException{ 
     
    		state = 0;
    		posRuban = 0;
    		Timeline timeline;
     
            if(event.getSource()==play){ //mon événement déclencheur
     
            	while(state < nbState){
            		timeline = AnimWithTimeline();
            		timeline.play();
            	}
    }
    Méthode 2:
    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
     
    public Timeline AnimWithTimeline() {
     
    		String value;
    		NextMove move;
     		int v = -1;
     		final int j = posRuban;
     		final int exState = state;
     		final int newState;
     
     		final Timeline timeline; 
    		final KeyFrame keyFrameAt0s,keyFrameAt2s,keyFrameAt4s,keyFrameAt6s,keyFrameAt8s;
     
    		value = ruban[posRuban].getValueLabel(); 
     
    		keyFrameAt8s = new KeyFrame(
    				Duration.seconds(8), 
    				new KeyValue(bulles[exState].fillProperty(), Color.RED)
    				); 
     
    		for (int incr=0; incr < variables.length; incr++){
    			if (value.equals(variables[incr])){v = incr;}
    		}
    		move = (transitions[state][v]);
     
    		value = move.getVar();
    		state = move.getState();
    		newState = state;
     
    		if (move.getDir()){
    			keyFrameAt6s = new KeyFrame(
    					Duration.seconds(6), 
    					new KeyValue(cursor.translateXProperty(), cursor.getTranslateX() + 70),
    					new KeyValue(bulles[exState].fillProperty(), bulles[newState].getFill())
    					); 
    			posRuban = posRuban + 1;}
    		else{
    		 	keyFrameAt6s = new KeyFrame(
    		 			Duration.seconds(6), 
    		 			new KeyValue(cursor.translateXProperty(), cursor.getTranslateX() - 70), 
    		 			new KeyValue(bulles[exState].fillProperty(), bulles[newState].getFill())
    		 			); 
    		 	posRuban = posRuban - 1;
    		 	};
     
    		keyFrameAt0s = new KeyFrame(
    				Duration.ZERO, 
    				new KeyValue(bulles[newState].fillProperty(), bulles[newState].getFill())
    				);
    		keyFrameAt2s = new KeyFrame(
    				Duration.seconds(2), 
    				new KeyValue(bulles[newState].fillProperty(), Color.AQUA),
    				new KeyValue(ruban[j].ValueProperty(),ruban[j].getValueLabel())
    				);
    		keyFrameAt4s = new KeyFrame(
    				Duration.seconds(4), 
    				new KeyValue(ruban[j].ValueProperty(),value),
    				new KeyValue(cursor.translateXProperty(), cursor.getTranslateX())
    				);
     
    		timeline = new Timeline(keyFrameAt0s,keyFrameAt2s,keyFrameAt4s,keyFrameAt6s,keyFrameAt8s);
    		return timeline;
     
    	}
    En affichant des résultats intermédiaires, je me suis aperçue que le problème venait principalement du tableau "ruban", qui devrait se mettre à jour à chaque Timeline, c'est à dire à chaque passage de la boucle et qui ne le fait pas. De ce que j'ai trouvé comme informations, j'ai l'impression qu'il s'agit d'un problème de multi-threading: les thread qui gère la mise à jour graphique est différent du thread qui calcule les valeurs de mes variables. Or, le processeur ne traite les thread l'un après l'autre, et donc ne met pas à jour mon tableau instantanément puisqu'il dépend de la partie graphique...
    Et-ce possible?

    SI c'est le cas, j'ai l'impression qu'il faudrait que j'instaure un système de verrous ou quelque chose dans le genre, mais j'avoue qu'un peu d'aide serait la bienvenue.
    Sinon, quelqu'un aurait-il une autre explication?

    Encore un grand merci aux personnes qui prendront la peine de passer quelques minutes sur mon problème!

  5. #5
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Et voilà! Avec un peu d'aide, j'ai trouvé une solution toute simple à mon problème (sans devoir passer par des verrous ou autre système du genre), qui m'assure que la première Timeline est exécutée entièrement avant d'entrer une deuxième fois dans la boucle!

    Il suffit de rajouter une nouvelle méthode qui sera appelée dans la première. La deuxième n'a pas été modifiée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    	public void step() {
    		Timeline timeline;
           	if ((state < nbState) ){
        		timeline = initAnim();
        		timeline.setOnFinished(ActionEvent -> step());
        		timeline.play();
        	}
    	}
    Méthode 1:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    	public void handleRemoteAction(ActionEvent event) throws IOException{ 
     
    		state = 0;
    		posRuban = 0;
     
    	    if(event.getSource()==play){
    	    	step();
    	    }  
    }
    Bonne soirée!

  6. #6
    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
    Ça m'apprendra à lire correctement le problème exposé
    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

  7. #7
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Novembre 2016
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2016
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Haha, aucun soucis!
    Je comprends très bien ta réaction, j'avais en plus tester cette solution pour voir comment elle fonctionnait,
    mais j'ai trouvé qu'elle s'adaptait moins à ce que je voulais faire...
    Merci d'avoir essayé de m'aider en tout cas!
    Grâce à toi, j'ai quand même persévéré dans l'utilisation des timeLine que je ne comprenais pas très bien et je trouve que mon code en est d'autant plus propre!

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

Discussions similaires

  1. [XL-2013] Synchroniser une image animée et du son dans un UserForm
    Par luc pic dans le forum Macros et VBA Excel
    Réponses: 20
    Dernier message: 11/10/2016, 20h59
  2. Réponses: 5
    Dernier message: 07/10/2016, 11h27
  3. [java3D] multiples objets, animation alpha
    Par samtheh dans le forum 3D
    Réponses: 1
    Dernier message: 28/03/2007, 15h57
  4. [FLASH MX] Synchroniser une animation sur un long mp3
    Par calogerogigante dans le forum Flash
    Réponses: 9
    Dernier message: 05/07/2006, 11h37
  5. [MX2004]Animations multiples
    Par blueice dans le forum Flash
    Réponses: 15
    Dernier message: 09/03/2004, 16h11

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