Comment créer un rebond automatique avec collision en jQuery ?

Mathieu Chartier 15 septembre 2015 à 09:48 Tutoriels illustrés 0 commentaire

Savoir créer des animations en Javascript ou jQuery est toujours intéressant, notamment depuis la chute indéfinie de Flash qui prenait à cœur cette tâche. Plusieurs techniques sont disponibles pour remplacer la solution d'Adobe, notamment les canvas HTML, ou la fonction animate() de jQuery. Dans ce tutoriel pas-à-pas, nous allons justement prendre ces techniques à contre-courant, et faire sans. L'objectif est de montrer que nous pouvons animer dans n'importe quel contexte. La programmation a cela de magnifique qu'il est possible de presque tout faire, tant que notre imagination et notre talent le permet, profitons-en...

Dans l'exemple que nous allons mettre en place, le but est de comprendre comment gérer un déplacement automatique et surtout comment créer l'effet de rebond sur les bordures d'une zone. En effet, ce sont bien les collisions qu'il faut penser à gérer, sinon l'animation dépassera du cadre et se perdra dans la nature. Nous allons donc maîtriser ces deux points, et dans un prochain tutoriel, nous verrons comment faire le même type d'animation avec une gestion des déplacements au clavier (plutôt que des déplacements automatiques).

Effet de rebonds avec collisions contre bordures (impact) en Javascript

Vous pouvez télécharger les codes deux deux tutoriels dès maintenant si votre patience a des limites. ^^

Télécharger “Effet d'animation en jQuery (avec collisions et rebonds)”rebond1.zip – Téléchargé 3742 fois – 83,49 Ko

Ici, jQuery nous sert essentiellement pour les sélecteurs, la récupération des offsets et des dimensions. En réalité, nous pourrions très écrire un peu plus long de code en Javascript pur. Gardez donc à l'esprit que des variantes sont possibles, même au niveau des valeurs dans certains cas...

Étape n°1

Création du code HTML simple

Dans le <body> d’une page HTML, ajoutez une zone contenant un élément à déplacer.

Ici, il s’agit de deux <div> distinctes.

<div id="zoneAuto">
    <div id="rebondAuto"></div>
</div>

Étape n°2

Création du CSS correspondant

Rien de bien compliqué ici, attribuez un style à la zone de démarcation à l’élément à déplacer.

Dans l’exemple, il s’agit d’un rectangle et d’une balle rebondissante.

* {padding:0; margin:0; font-size:1em; border:0}

#zoneAuto {border:3px solid #007da0; margin:3em; height:150px; width:300px}
#rebondAuto {background:red; width:1em; height:1em; border-radius:20px}

Étape n°3

Gérer jQuery et les scripts Javascript

Ajouter jQuery dans la section <head> de la page ainsi qu’un couple de balises <script>…</script> avec la fonction de lancement de jQuery.

Nous ajoutons une fonction spécifique pour notre usage (non obligatoire).

<script type="application/javascript" src="jquery-1.11.3.min.js"></script>
<script type="application/javascript">
$(document).ready(function() {
   function rebondsAutomatiques() {
      // Code à prévoir...
   }
   rebondsAutomatiques();
});
</script>

Étape n°4

Récupérer les dimensions des éléments

Pour bien gérer les collisions contre les bordures, il faut absolument connaître toutes les dimensions de la « boîte » (zone d’accueil de la première <div>), mais aussi celles de l’élément à déplacer (la <div> de la balle).

Ces éléments sont fondamentaux pour que le système fonctionne.

Selon la méthode utilisée (canvas en HTML, fonction animate(), offset, etc.), cette étape peut être quelque peu différente !

// Variable générale
var z = $('#zoneAuto'); // Zone
var el = $('#rebondAuto'); // Elément à déplacer
        
// Enregistrement des dimensions de l'élément à déplacer
var hauteurElement = el.height();
var largeurElement = el.width();
        
// Enregistrement des dimensions de la zone
var hauteurZone = z.outerHeight();
var largeurZone = z.outerWidth();
        
// Epaisseur de la bordure de zone (voir CSS)
var bordureZone = 3;
        
// "Quadrillage" en pixel (pour savoir où sont les bordures)
var pixelHaut = z.offset().top;
var pixelGauche = z.offset().left;
var pixelBas = (pixelHaut + hauteurZone) - (hauteurElement + bordureZone);
var pixelDroite = (pixelGauche + largeurZone) - (largeurElement + bordureZone);

Étape n°5

Gestion des déplacements et des « timing »

Il convient d’indiquer au programme de combien de pixel sera déplacé l’élément en X (abscisse) et en Y (ordonnée).

La variable timing gère le nombre d’images par seconde à afficher.

Plus la valeur des orientations en X et Y est faible, plus le mouvement est précis et lent, cela signifie qu’il faut augmenter la vitesse parallèlement. Jouez avec ces valeurs.

// Variable utile pour la boucle de mouvement
var orientationX = 0.3; // Valeur de déplacement (0.3 "px" par défaut)
var orientationY = 0.3; // Valeur de déplacement (0.3 "px" par défaut)
var timing = 1000/150; // x images par seconde ("150" par défaut ici)

Étape n°6

Créer la boucle infinie de l’animation

On créé une boucle infinie avec la fonction setInterval() de Javascript. C’est ici que le « timing » est pris en compte pour créer la récurrence du mouvement et l’animation.

Dans d’autres langages, la boucle while() aurait été utilisée (mais occupe beaucoup plus de ressources ici).

// Boucle pour créer le mouvement
var boucle = setInterval(function() {
   // Code de l'étape suivante
}, timing);

Étape n°7

Récupération de l’emplacement de l’élément en mouvement

Il faut absolument récupérer l’emplacement de l’élément à déplacer pendant son mouvement afin de créer les collisions.

Ces données sont récupérées dans la boucle créée par setInterval() car elles changent à chaque « tour ».

// Pixels occupés par l'élément à déplacer
var offsetHaut = el.offset().top;
var offsetGauche = el.offset().left;
var offsetBas = offsetHaut + hauteurElement;
var offsetDroite = offsetGauche + largeurElement;

Étape n°8

Création des collisions avec les bordures

La création des collisions se fait en deux étapes :

  1. les if() { … } permettent d’indiquer les bordures à ne pas dépasser.
  2. la multiplication par -1 permet d’inverser le sens du mouvement et de créer le rebond contre les bordures.
// Sens d'animation gauche-droite (rebonds)
if(parseInt(offsetGauche) >= pixelDroite+1 || parseInt(offsetGauche) <= pixelGauche+1) {
   orientationX *= -1;
}
// Sens d'animation haut-bas (rebonds)
if(parseInt(offsetHaut) >= pixelBas+1 || parseInt(offsetHaut) <= pixelHaut+1) {
   orientationY *= -1;
}

Étape n°9

Déplacement de l’élément (la balle)

Il suffit d’attribuer les nouveaux déplacements à l’élément en mouvement pour que l’animation reste fluide en continu.

// Nouvelles positions pour l'élément
position = el.offset({
   left:offsetGauche + orientationX,
   top:offsetHaut + orientationY
});

Étape n°10

Résultat final de l’animation jQuery avec rebonds et collisions contre les bords.

Effet de rebonds jQuery avec collision (animation Gif)

Étape n°11

Variantes possibles :

  • Il est possible d’attribuer des valeurs au hasard ou différentes aux variables d’orientation en X et en Y pour créer un déplacement plus naturel.
  • Il est possible d’ajouter une variable complémentaire dans les déplacements pour créer un peu de « zizanie » dans l’animation.

Conclusion

Ce premier tutoriel montre comment gérer un effet de rebond automatique avec collision contre des bordures de zone. Il faut imaginer que l’animation de la balle rouge n’est vraiment qu’un exemple, c’est l’idée qu’il faut conserver pour créer toutes sortes d’animations automatisées (avec des valeurs de départ au hasard par exemple, ou variables en X et en Y…), en multipliant les éléments en mouvement et les éléments fixes.

Le même type d’animation peut être utilisé pour créer des mini-jeux. Avec une balle et une zone, il ne nous manque plus que deux traits en mouvement pour recréer Pong, le célèbre jeu vidéo. Et pour tout vous dire, j’avais reprogrammé Pong en GW Basic quand j’étais tout jeune (ça ne me rajeunit pas ^^), ce tutoriel est en fait la réponse à ce bon moment de mon passé, je voulais juste l’adapter avec un langage dans l’ère du temps (Javascript et ici un peu de la bibliothèque jQuery).

J’espère en tout cas que cela vous aura éclairci un peu les idées et vous donnera une méthode supplémentaire pour créer des mouvements avec rebonds et collisions en jQuery/Javascript.