Forums Développement Multimédia

Les formations Mediabox
Les formations Mediabox

Les lois de la mécanique du mouvement

Compatible ActionScript 2. Cliquer pour en savoir plus sur les compatibilités.Par didouche





/* Tutorial en cours de rédaction */


Flash nous permettant de positionner et de déplacer des clips, c’est tout naturellement que nous nous posons la question suivante :

« Peut-on simuler des déplacements réalistes dans Flash, c'est-à-dire des déplacements qui respectent les lois de la mécanique ? »

Pour une petite remise à niveau sur les notions mathématiques nécessaires, c’est ici.

Commençons par étudier le mouvement en introduisant les notions de vitesse et d’accélération.

Vitesse :

Un objet en mouvement le long de l’axe des abscisses (x) voit la valeur de cette abscisse varier au cours du temps. La façon dont cette abscisse est modifiée est représentée par sa vitesse.

Dans la réalité, la valeur de l’abscisse est exprimée en mètre (unité du système international SI), la vitesse est donc exprimée en mètre par seconde : m/s ou m.s-1.

Le calcul de la vitesse moyenne d’un objet au cours du mouvement entre deux points s’effectue grâce à la formule : v= d/t. d étant la distance parcourue en mètre et t le temps de parcours en seconde.

La vitesse représente donc la distance parcourue en une seconde. Un objet se déplaçant à la vitesse de 3 m/s verra son abscisse augmenter de 3 mètre à chaque seconde.

Dans Flash, on ne peut mesurer les distances en mètre. Les positions étant exprimées en pixels, les vitesses correspondront donc au nombre de pixels dont l’objet se déplace par seconde.

Le problème est qu’on ne peut se permettre de déplacer un objet toutes les secondes uniquement. Le déplacement paraîtrait quelque peu saccadé.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Si nous voulons un mouvement fluide, il nous faut modifier la position à un rythme un peu plus rapide.

Deux choix s’offrent à nous : onEnterFrame ou setInterval.

Nous allons dépendre ici du rythme de l’animation quelque soit notre choix puisque l’affichage n’est rafraîchi qu’au rythme de la cadence de l’animation. Ici par exemple je demande à la position de changer toutes les 20 millisecondes à l'aide d'un setInterval mais l’animation est à la cadence de 2 images par seconde, le mouvement se fait donc à ce rythme.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Pour rafraichir l'affichage sans attendre l'image suivante, il suffit de placer un :

updateAfterEvent()


dans la fonction appelée.

Utilisons le onEnterFrame. Je voulais une vitesse de 20 pixels par seconde. Ma cadence d’animation étant de 24 images par seconde, il faut que tous les 24ème de seconde, la position augmente de 20/24 pixels. J’ai donc un mouvement qui se fait à la même vitesse que pour le premier mouvement mais qui est fluide.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Il est donc simple de savoir quelle vitesse utiliser pour un déplacement. Il faut connaître la distance que l’on veut faire parcourir à l’objet, le temps qu’il lui faudra pour la parcourir et la cadence de l’animation.

Exemple : Je veux qu’un objet traverse la scène qui fait 300 pixels en 10 secondes. Il faut donc que la vitesse soit égale à 300/10= 30 pixels par seconde. La cadence de mon animation est 36 images par secondes. Il faut qu’elle augmente de 36/30 pixels par image.

Nous avons ici des mouvements à vitesse constante, on dit qu’ils sont uniformes. Celui-ci se faisant selon une ligne droite, il est dit rectiligne uniforme.

Dans l’animation qui suit, la vitesse dépend de la position du curseur et est exprimée en pixels par secondes.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

On peut évidemment faire varier la vitesse selon l’axe des y de la même façon.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

La vitesse d’un objet peut-être décrite à l’aide d’un vecteur appelé vecteur vitesse. C’est tout simplement une flèche reprenant les caractéristiques de la vitesse. Elle est orientée selon la trajectoire de l’objet, dans le sens de son mouvement et sa longueur dépend de la valeur de cette vitesse et de l’échelle choisie pour la représenter.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Exemple : une vitesse de 3m/s représentée à une échelle de 1cm pour 1 m/s le sera par une flèche de longueur 3 cm.

Le vecteur vitesse d’un objet peut-être décomposé selon deux composantes. L’une selon l’axe des abscisses, l’autre selon l’axe des ordonnées. Sur l’animation ci-contre, la composante selon l’axe des abscisses est en rouge, celle selon l’axe des ordonnées est en vert, la somme des deux est en noir.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Pour connaître le vecteur vitesse de l’objet, il faut faire la somme vectorielle des vecteurs vitesses selon les deux axes. Pour connaître la valeur de cette vitesse, utilisons le théorème de Pythagore qui nous dit que le carré de cette valeur est égal à la somme des carrés des valeurs des composantes.

V ² = Vx ² + Vy ².

Nous voyons ici le résultat de la modification de chacune des composantes du vecteur vitesse. Le vecteur vitesse est la somme vectorielle des vecteurs vitesses selon x et selon y.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Accélération :

Lorsque la vitesse d’un objet varie au cours du temps, le mouvement n’est plus uniforme. La façon dont varie la vitesse est appelée l’accélération. Elle est exprimée en m/s2 ou m.s-2. Elle représente la valeur dont augmente (ou diminue) la vitesse en 1 seconde.

Exemple : Un objet soumis à une accélération constante de valeur 2 m/s2 vers le sens positif de l’axe des abscisses (vers la droite) verra sa vitesse augmenter selon cet axe de 2 m/s à chaque seconde. Si sa vitesse à un instant donné a pour valeur 5 m/s, elle sera égale à 7 m/s une seconde plus tard puis 9 m/s après deux secondes.

Dans l’animation ci-contre, on peut faire varier l’accélération selon l’axe des abscisses à l’aide du curseur.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Note: La vitesse n’est pas toujours dirigée dans le même sens que l’accélération comme on peut le voir sur l’animation suivante dans laquelle le vecteur accélération est représenté en jaune et le vecteur vitesse en noir.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.


La question que nous devons nous poser est la suivante: “Par quoi une accélération peut-elle créée ?”

Forces

La réponse à la question précédente est simple: “L'accélération d'un objet est dûe aux forces qui s'exercent sur lui”.

Il suffit donc, pour pouvoir prévoir le mouvement d'un objet, de faire le bilan des forces qu'il subit. On en déduit l'accélération par une simple formule qui nous dit que la somme des forces s'exerçant sur un objet est égal au produit de sa masse et de son accéleration. accélération= (somme des forces)/masse.

Pour une force donnée, l'accélération d'un corps est donc d'autant plus grande que sa force est petite.
Note : L'intensité d'une force est exprimée, en physique, en newton (N).

La relation précédente est une relation vectorielle, ce qui fait que le vecteur accélération est de même direction et sens que le vecteur force appliqué à l'objet.

Exemple : Dans l'exemple suivant, la flèche rouge indique la force s'exerçant sur un objet, la flèche noire représente l' accélération qu'il subit.
L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Gravité

Question récurrente lorsque l'on cherche à simuler la chute d'un corps.

Petit rappel de physique (ce qui suit est un cours de physique, pas indispensable pour la suite mais utile)
La terre exerce une force sur tous les objets qui l'entourent (rigoureusement: tous les objets sont en interaction avec la terre, l'objet attire donc la terre autant qu'il est lui-même attiré).
Cette force est appelée le poids, noté P, de l'objet.
Elle dépend de deux choses:

  • La masse de l'objet.
  • L'intensité de la pesanteur: g = 9,81 N.kg-1.


La formule est la suivante: P= m * g.
Exemple Un objet de masse 10 kg subit de la part de la terre une force dont l'intensité a pour valeur:

P = m * g = 10 * 9,81 = 98,1 N


Revenons à la formule qui donne l'accélération: L'accélération est égale à la valeur de la force divisée par la masse.
Dans le cas du poids, si on divise par la masse, on obtient g.

P=m*g
a=P/m=m*g/m=g

Donc: un objet soumis uniquement à son poids subit une accélération de 9,81 m.s-2. Tous les objets subissent donc la même.
Ceci n'est valable que si on supprime les frottements de l'air: dans le vide, un Airbus et une plume tombent à la même vitesse. (c'est dingue, non ?).
(fin du cours).

Pour simuler une chute sans frottements, il faut donc tout simplement que l'objet subisse une accélération de valeur constante.

Illustration
Nous avons ici des balles qui apparaissent à chaque clic et qui sont soumises uniquement à leur poids. Vous pouvez modifier l'intensité de la pesanteur à l'aide du curseur. Le vecteur qui apparait est, bien entendu, le vecteur vitesse.

L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Le code (allégé pour une meilleure lecture):

onMouseDown=function(){
var mc:MovieClip=boule.duplicateMovieClip("boule"+i,this.getNextHighestDepth(),{_x:_xmouse,_y:_ymouse});
mc.vitx=Math.random()*10-5;
mc.vity=-Math.random()*20;
mc.onEnterFrame=function(){
this.vity+=accel;
this._x+=this.vitx;
this._y+=this.vity;
}
}


Le paramètre accel étant modifié lorsqu'on relache le curseur.

Problème La vitesse augmente de façon régulière mais ce n'est pas conforme à la réalité.

Ceci est dû au fait que nous avons négligé les frottements dûs à l'air ou à n'importe quel fluide.

Question : Y-a-t-il moyen de simplifier un peu le travail dans le cas de plusieurs forces ?

Classe Vector

Lorsque plusieurs forces s'appliquent sur un objet, il faut faire la somme vectorielle de ces forces. L'objet se comportera comme si une force unique lui était appliquée: cette somme de forces.
Somme vectorielle : Dans le schéma ci-dessous, la fleche noire est la somme vectorielle des trois autres forces. Cliquez sur “somme” pour voir comment la somme est réalisée.

Dans le cas de cet objet, il suffit maintenant de s'interesser uniquement à cette force.
L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Concrètement comment fait-on ?
Il faut additionner les coordonnées de nos vecteurs pour obtenir la somme.

Peut-on simplifier ?
Robert Penner nous a fourni une classe bien utile: La classe Vector qui permet de gerer des vecteurs. On peut additionner des vecteurs, les soustraire, faire le produit scalaire (voir cette section pour une explication), changer la taille, l'angle etc…..

var vecteur:Vector=new Vector(2,9);
trace(vecteur.toString());
vecteur.plus(new Vector(4,5));
trace(vecteur.toString());

Comment faire la même chose que précédemment à l'aide de cette classe ?
Mes trois forces sont trois vecteurs qu'il suffit d'additionner:

vect1=new Vector(50,20);
vect2=new Vector(-30,40);
vect3=new Vector(-15,-30);
somme=vect1.plusNew(vect2.plusNew(vect3));
trace(somme.toString());

La méthode plusNew() fait la somme de deux vecteurs et renvoit un nouveau vecteur.
Il n'y a plus qu'a utiliser ce vecteur pour calculer l'accélération comme précédemment. On accede aux coordonnées de ces vecteurs à l'aide des propriétés 'x' et 'y'.

mc.onEnterFrame=function(){
this.vitx+=somme.x
this.vity+=somme.y;
this._x+=this.vitx;
this._y+=this.vity;
}
}

Re-question : Y a pas moyen de faire encore plus simple ?
Si ! toujours grace à Robert Penner.

Classes PhysicParticle et Force

Ces classes permettent de transformer un clip en particule physique et de lui appliquer des forces. L'exemple précédent devient:

var particule:PhysicParticle(mc,_xmouse,_ymouse); /* on crée un objet "particule physique associée au clip "mc". On le place à la position de la souris*/
var grav:Force=new Force(0,0.1);/* On crée une force appelée "grav" verticale donc ayant une valeur nulle selon x et non nulle selon y (0.1) */
particule.addForce("gravite",grav); /* On applique cette force à la particule en lui donnant le nom "gravite" qui permettra de l'effacer le cas échéant. */


Les forces appliquées sont stockées dans un tableau. Au rythme de l'animation, le tableau est parcouru, les forces qu'il contient sont additionnées et la force résultante est appliquée à la particule.
On peut donner une durée de vie aux forces en nombre d'images au bout de laquelle elle disparait.

La suite arrive dans laquelle on détaillera tout ce qui suit:
Mouvement Brownien avec attraction par une particule: L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.
Le code

for (i=1; i<20; i++) {
	var mc:MovieClip = teste.duplicateMovieClip("test"+i, this.getNextHighestDepth(), {_x:Math.random()*400, _y:Math.random()*400});
	this["p"+i] = new PhysicParticle(mc, mc._x, mc._y);
	this["forcepoint"+i] = new ForcePoint(teste2, 0.05);
	this["p"+i].addForce("point", this["forcepoint"+i]);
	this["p"+i].setFriction(0.05);
}
 
bouge.onPress = function() {
	teste2._x = Math.random()*300+50;
	teste2._y = Math.random()*300+50;
	for (i=1; i<20; i++) {
		this._parent["forcepoint"+i].setAnchor(teste2._x, teste2._y);
	}
};

Ma classe RessortForce et sa classe Ressort associée pour dessiner le ressort.
L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

var p:PhysicParticle = new PhysicParticle(teste, teste._x, teste._y);
var ressort:Force = new RessortForce(100, 100, 0.01, 120);
var ressort2:Force = new RessortForce(300, 100, 0.05, 120);
var ressort3:Force = new RessortForce(250, 300, 0.03, 100);
var force:Force = new Force(0, 1);
p.addForce("ressort", ressort);
p.addForce("ressort2",ressort2);
p.addForce("ressort3",ressort3);
p.setFriction(0.02);
 
btn.onPress = function() {
	if (p.getForce("gravite")) {
		p.removeForce("gravite");
	} else {
		p.addForce("gravite", force);
		p.cacheForce("gravite");
	}
};
relance.onPress=function(){
	p.vel=new Vector(Math.random()*20-10,Math.random()*20-10);
}

Chocs elastiques (on détaillera la formule) et particules elastiques
L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

Ma classe PhysicPendule.
L"extension Adobe Flash Plugin est nécessaire pour afficher ce contenu.

var p:PhysicPendule = new PhysicPendule(teste, 250, 0, 250, 50);
var centre:MovieClip = teste.duplicateMovieClip("centre", 1, {_x:250, _y:00, _width:5, _height:5});
var grav:Force = new Force(0, 0.1);
var vent:Force = new Force(0.2, 0);
p.addForce("gravite", grav);
p.cacheForce("gravite");
p.setFriction(0.005);
btn.onPress = function() {
	if (p.getForce("vent")) {
		p.removeForce("vent");
	} else {
		p.addForce("vent", vent);
		p.cacheForce("vent");
	}
};