Bonjour à tous,
J'ai réalisé un petit jeu en Java/SWING reposant sur le pattern MVC. Le jeu est une grille sur laquelle on peut déplacer des jetons. J'ai alors tenté, lors d'une mise à jour du modèle, de faire une animation sur la vue (interpolation du jeton). Le problème, c'est que cette animation saccade complètement. Mon code état assez volumineux, j'aurais du mal à vous le présenter correctement ici (et ça rebuterait tous ceux qui accepteraient de m'aider), cependant, je pense que le problème se situe plus sur la manière donc j'effectue le rafraîchissement des images.
Mon modèle implante l'interface Obversable de java.util et la vue Observer. Lors d'une mise à jour, le modèle appelle la méthode update de la vue, avec pour argument une structure de données représentant ce qui a été modifié (et qui doit donc être animé). Voici ce qui est effectivement réalisé par la vue :
Appel de update : si l'événement est effectivement un déplacement de jeton, on l'ajoute à une liste L avec un avancement à zéro. On appelle ensuite la méthode generateNewFrame() qui est chargée de mettre à jour l'avancement de tous les jetons de L.
generateNewFrame() : Pour chaque jeton, on incrémente son avancement de 1 et si son avancement est égal au nombre de frame désiré de l'animation (j'ai fixé ce paramètre à 30 pour avoir une animation qui dure environ 1 seconde), on le supprime de la liste (car il est arrivé à destination, il doit donc être affiché normalement). On appelle ensuite repaint() qui fait sa tambouille (calcul des positions de tous les jetons et affichage). Enfin, si la liste de jetons n'est pas vide, on lance un Timer (de javax.swing) sans répétition qui au bout de 33ms (pour correspondre environ à 30FPS) et qui invoque à la fin generateNewFrame(). Ainsi, une nouvelle frame est censée être générée toutes les ~33ms.
Cette manière de procéder produit donc une saccade assez aléatoire (parfois elle va être pratiquement invisible, d'autre fois, le jeton va vraiment saccader plein pot et droper pas mal de frames).
Sauriez-vous, rien qu'avec ces indications, me donner une idée de la source du problème et une idée de solution ? Je miserais sur le timer qui rempilerait un nouveau repaint() avant même que le précédent ne soit terminé, mais je n'en suis pas sûr et je ne vois pas trop comment corriger cela.
Si non, que vous faudrait-il comme information supplémentaires pour pouvoir m'aider ? Un extrait de code me paraîtrait long et compliqué à produire, mais si vous pensez que c'est absolument nécessaire, je m'y essayerai.
En vous remerciant par avance,
Cordialement,
Nakwakwak
Partager