|
|
||||||
| Tutoriaux : Interpolation de mouvement | ||||||
|
Introduction |
||||||
| Ce tutoriel explique ce que les anglophones appellent la technique du "easing" : il s'agit de coder le déplacement d'un clip qui doit suivre le curseur de votre souris avec un léger retard. Ce retard peut être défini par deux paramètres a et b que vous pouvez faire varier entre 0 et 1 comme dans l'animation ci-dessous. Déplacez votre souris dans la zone rectangulaire, observez le déplacement du cercle noir puis faites varier a et b à l'aide des glissières. | ||||||
Nous allons détailler la réalisation de l'animation ci-dessus étape par étape en publiant 4 animations de complexité croissante puis une petite variante vous sera proposée. |
||||||
| Dans la bibliothèque | ||||||
|
- Ouvrez flash et créez un nouveau document de 200 pixels de largeur et de 200 pixels de hauteur. |
||||||
| Sur la scène principale | ||||||
| - Sur la scène principale, placez une occurrence du clip "cercle". Centrez ce clip horizontalement et verticalement puis dans le panneau "propriétés" nommez cette occurrence "cercle_mc". | ||||||
| Le code n°1 et l'animation obtenue | ||||||
|
||||||
| Commentaires du code n°1 | ||||||
| On crée une fonction qui sera exécutée à chaque image. | ||||||
| onEnterFrame = function() { | ||||||
| On calcule la différence entre l'abscisse de la souris et celle du cercle. | ||||||
| var dx = _xmouse - cercle_mc._x; | ||||||
| On ajoute le quart de dx à l'abscisse du cercle. Cette ligne de code est équivalente à : cercle_mc._x = cercle_mc._x + 0.25*dx; En procédant ainsi, la position du cercle "tend" vers celle de la souris. |
||||||
| cercle_mc._x += 0.25*dx; | ||||||
| Fin de la fonction onEnterFrame | ||||||
| } | ||||||
| Pour comprendre comment fonctionne ce petit bout de code, supposons que l'abscisse du cercle noir soit égale à 100 et que l'abscisse de la souris soit égale à 200 (on suppose que la souris reste statique). Au lancement de l'animation on suppose que : cercle_mc._x = 100 et que tout au long de l'animation _xmouse = 200. Dans ce cas dx vaut 100 et à l'image suivante on ajoute 25 à l'abscisse du cercle. A l'image n°1, on a donc cercle_mc._x = 125, dx vaut alors 75 et à l'image suivante on ajoute 18.75. A l'image n°2, on a donc : cercle_mc._x = 143.75. En utilisant la fonction trace, on peut ainsi suivre l'évolution numérique de l'abscisse du cercle et de la distance dx. On obtient le tableau suivant dans lequel les données sont arrondies au millième : | ||||||
|
||||||
| A l'image n°37 (autrement dit en moins de 2 secondes) l'abscisse du cercle est "quasiment" égale à celle de la souris. | ||||||
| Le code n°2 et l'animation obtenue | ||||||
|
||||||
| Commentaires du code n°2 | ||||||
| Le déplacement obtenu se fait verticalement mais le principe est bien entendu le même ! Dans l'animation suivante, nous allons coupler les deux animations précédentes (déplacement horizontal et vertical) : désormais le déplacement du cercle ne sera plus rectiligne. | ||||||
| Le code n°3 et l'animation obtenue | ||||||
|
||||||
| Commentaires du code n°3 | ||||||
| Je ne vois pas l'intérêt de commenter ce code ligne par ligne ! Il suffit de lire ce qui précède... Pourquoi avoir choisi 0.25 comme coefficient multiplicateur de dx ? En bien, vous pouvez prendre des valeurs comprises entre 0 et 1 : pour zéro, le cercle sera immobile tandis que pour 1, le cercle suivra parfaitement et sans retard le déplacement de votre curseur (à la manière d'un startDrag). Les valeurs intermédiaires vous permettront d'obtenir l'effet recherché... Je vous conseille de créer deux paramètres a et b placés en début de programme et d'observer l'incidence de leur variation sur le déplacement du cercle : | ||||||
a = 0.2; b = 0.5; onEnterFrame = function() { var dx = _xmouse - cercle_mc._x; var dy = _ymouse - cercle_mc._y; cercle_mc._x += a*dx; cercle_mc._y += b*dy; } |
||||||
| On peut également placer plusieurs occurrences du même cercle qui se déplacent simultanément vers la position du curseur avec des valeurs de a et de b propres à chaque occurrence. Avoir des clips qui se déplacent vers le curseur c'est bien mais si l'on veut pouvoir utiliser sa souris pour cliquer sur des boutons ou utiliser des glissières comme dans l'animation qui figure dans l'introduction, il faut pouvoir contraindre le déplacement des clips en les obligeant par exemple à rester à l'intérieur d'une zone rectangulaire. C'est ce que je vous propose d'étudier avec l'animation suivante : | ||||||
| Le code n°4 et l'animation obtenue | ||||||
- Modifiez la taille de l'animation : hauteur = 200 pixels, largeur = 400 pixels. Dans le panneau "action" de l'image clé n°1, placez le code ci-dessous |
||||||
xmin = 20; ymin = 20; xmax = 380; ymax = 180; n = 10; amin = 0.05; amax = 0.5; this.createEmptyMovieClip("rectangle_mc", 0); with(rectangle_mc) { lineStyle(0, 0x000000, 100); moveTo(xmin, ymin); lineTo(xmax, ymin); lineTo(xmax, ymax); lineTo(xmin, ymax); lineTo(xmin, ymin); } function deplacement () { var dx = _xmouse - this._x; var dy = _ymouse - this._y; this._x += this.a*dx; this._y += this.a*dy; if(this._x > xmax) {this._x = xmax;} else if(this._x < xmin) {this._x = xmin;} if(this._y > ymax) {this._y = ymax;} else if(this._y < ymin) {this._y = ymin;} } for(var i = 0; i < n; i++) { var cercle = this.attachMovie("cercle", "cercle"+i, i + 1); cercle._height = cercle._width = 5; cercle.a = amin + i*(amax - amin)/(n - 1); cercle.onEnterFrame = deplacement; } |
||||||
| Commentaires du code n°4 | ||||||
| Ces 4 paramètres définissent les abscisses et les ordonnées minimales et maximales entre lesquelles devront évoluer les différents cercles. La zone définie est donc rectangulaire. | ||||||
| xmin = 20; ymin = 20; xmax = 380; ymax = 180; |
||||||
| Ce paramètre représente le nombre de cercles qui devront suivre le déplacement de la souris. | ||||||
| n = 10; | ||||||
| Ces deux paramètres sont les bornes des coefficients multiplicateurs qui permettront de définir la vitesse de déplacement de chaque cercle. | ||||||
| amin = 0.05; amax = 0.5; |
||||||
| On crée un clip vide dans lequel on trace un rectangle qui correspond à la zone dans laquelle les cercles sont "emprisonnés". | ||||||
| this.createEmptyMovieClip("rectangle_mc", 0); with(rectangle_mc) { lineStyle(0, 0x000000, 100); moveTo(xmin, ymin); lineTo(xmax, ymin); lineTo(xmax, ymax); lineTo(xmin, ymax); lineTo(xmin, ymin); } |
||||||
| On crée une fonction qui permettra de gérer le déplacement de chaque cercle. Cette fonction devrait vous être familière ! Les deux dernières lignes de cette fonction permettent de s'assurer que les abscisses restent comprises entre xmin et xmax et que les ordonnées restent comprises entre ymin et ymax. | ||||||
| function deplacement () { var dx = _xmouse - this._x; var dy = _ymouse - this._y; this._x += this.a*dx; this._y += this.a*dy; if(this._x > xmax) {this._x = xmax;} else if(this._x < xmin) {this._x = xmin;} if(this._y > ymax) {this._y = ymax;} else if(this._y < ymin) {this._y = ymin;} } |
||||||
| On utilise une boucle for indexée sur la variable i. | ||||||
| for(var i = 0; i < n; i++) { | ||||||
| On cherche dans la bibliothèque, le clip dont le nom de liaison est "cercle" et on place sur la scène principale des occurrences de ce cercle qui portent les noms cercle0, cercle1, cercle2,... | ||||||
| var cercle = this.attachMovie("cercle", "cercle"+i, i + 1); | ||||||
| On définit les dimensions de chaque cercle. | ||||||
| cercle._height = cercle._width = 5; | ||||||
| On définit le coefficient multiplicateur de chaque cercle : pour le premier cercle ce coefficient sera égal à amin tandis que pour le dernier cercle ce coefficient sera égal à amax... Le premier cercle sera donc le plus lent tandis que le dernier cercle placé dans cette boucle sera le plus rapide. | ||||||
| cercle.a = amin + i*(amax - amin)/(n - 1); | ||||||
| Chaque cercle placé sur la scène fera appel à chaque image à la fonction deplacement définie plus haut. | ||||||
| cercle.onEnterFrame = deplacement; | ||||||
| fin de la boucle for. | ||||||
| } | ||||||
| Une dernière remarque | ||||||
La technique que je viens de vous expliquer est utilisée dans ce tutoriel avec les propriétés _x et _y d'un clip mais elle peut être utilisée pour d'autres propriétés comme _alpha ou _rotation... Le principe est toujours le même : vous voulez faire tendre la valeur d'une propriété vers une valeur cible, il suffit alors de procéder de la manière suivante. coefficient = 0.2; onEnterFrame = function() { |
||||||
|
Plus la valeur du coefficient est proche de 1, plus la convergence vers la valeur cible est rapide. Si la valeur du coefficient est proche de 0 cette convergence est lente. Une petite illustration de cette dernière remarque par une animation qui utilise la technique du easing pour faire tourner des clips. |
||||||
|
|