À propos de ce cours
Chapitre 15 — Animations et graphismes avec Canvas · 15.5 TP 15 : Dessin et animation avec Canvas
• dessiner une scène complète avec l'API Canvas ;
• construire une boucle d'animation avec un temps écoulé
dt; • gérer clavier, souris et collisions ;
• organiser un petit jeu en objets et en états.
Présentation
Vous allez programmer un casse-briques: une balle rebondit sur les murs et sur une raquette pilotée par le joueur, et casse des briques. Le jeu mobilise tout le chapitre : dessin (15.2), animation (15.3), interaction et collisions (15.4). Vous pourrez aussi réutiliser les classes du chapitre 16.
Voici le résultat attendu. Les questions de chaque partie vous guident ; aucune solution n'est donnée.

Figure 1 — Le jeu à obtenir (en cours de partie).
Fichiers de départ
⬇ Télécharger les fichiers de départ du TP (tp15-depart.zip)
index.html (à ne pas modifier)
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Casse-briques</title>
<style>
body { margin: 0; min-height: 100vh; display: grid; place-items: center; background: #0f172a; color: #e2e8f0; font-family: system-ui, sans-serif; }
canvas { background: #111827; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,.5); max-width: 95vw; }
p { text-align: center; color: #94a3b8; }
</style>
</head>
<body>
<main>
<canvas id="jeu" width="640" height="420"></canvas>
<p>← → ou souris : déplacer · Espace : lancer · P : pause</p>
</main>
<script src="jeu.js"></script>
</body>
</html>
jeu.js (à compléter)
// =====================================================================
// TP 15 — Casse-briques : fichier de départ
// Complétez ce fichier en suivant les parties du TP.
// =====================================================================
const canvas = document.querySelector("#jeu");
const ctx = canvas.getContext("2d");
// ---- Réglages du jeu (vous pouvez les modifier) ----
const CONFIG = {
raquette: { largeur: 100, hauteur: 14, vitesse: 480, marge: 30 }, // vitesse en px/s
balle: { rayon: 8, vitesse: 320 }, // px/s
briques: { lignes: 5, colonnes: 10, largeur: 56, hauteur: 20, espace: 6, haut: 50 },
couleurs: ["#ef4444", "#f97316", "#eab308", "#22c55e", "#3b82f6"], // une par ligne
points: [50, 40, 30, 20, 10], // une par ligne
vies: 3,
};
// PARTIE 2 — Dessiner la scène
// PARTIE 3 — La boucle d'animation
// PARTIE 4 — Les commandes (clavier et souris)
// PARTIE 5 — Les collisions
// PARTIE 6 — Score, vies et états du jeu

Figure 2 — Deux calculs à préparer sur papier.
🛠 TP · Partie 1 — Préparer et observer
Mission : Ouvrez index.html avec un serveur local, lisez CONFIG et préparez votre plan.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Listez les objets du jeu et, pour chacun, ses données (position, taille, vitesse…) et ce qu'il doit savoir faire. Allez-vous écrire des classes ou de simples objets ? Justifiez.
- Le jeu passe par plusieurs états: en attente du lancer, en jeu, en pause, perdu, gagné. Dessinez le schéma des états avec les événements qui font passer de l'un à l'autre (touche Espace, touche P, dernière brique, dernière vie).
- Avec
CONFIG.briques, calculez la largeur totale de la grille. Quelle valeur de « gauche » la centre dans un canvas de 640 px ? (figure 2)
Je vérifie / je rends :
- ☐ Le plan des objets et le schéma des états.
🛠 TP · Partie 2 — Dessiner la scène
Mission : Dessinez la scène immobile : la grille de briques colorées, la raquette, la balle posée sur la raquette, le score et les vies.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Écrivez une fonction (ou une méthode) qui crée toutes les briques avec deux boucles imbriquées. Où rangez-vous la couleur et les points de chaque brique ?
- La raquette a des coins arrondis : cherchez la méthode
roundRectdu contexte. Que faire si un navigateur ancien ne la connaît pas ? - Comment placer la balle exactement au centre et juste au-dessus de la raquette ?
- Affichez le score à gauche, le record au centre et les vies (♥) à droite. Quelle propriété du contexte permet d'aligner un texte à droite ?
Je vérifie / je rends :
- ☐ Une capture de la scène immobile, conforme à la figure 1.
🛠 TP · Partie 3 — La boucle d'animation
Mission : Mettez la scène en mouvement : la balle part vers le haut quand on appuie sur Espace et rebondit sur les murs.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Écrivez la boucle avec
requestAnimationFrameet undten secondes. Pourquoi limiterdtà une petite valeur ? - Au lancer, la balle part vers le haut avec un angle aléatoire entre −30° et +30° par rapport à la verticale. Comment calculez-vous
vxetvyà partir de l'angle et de la vitesse (indice :Math.cos,Math.sin, radians) ? - Faites rebondir la balle sur les murs gauche, droit et haut. Pourquoi est-il plus sûr d'écrire
vx = Math.abs(vx)quevx = -vxsur le mur gauche ? - Avant le lancer, la balle doit rester collée à la raquette. Où gérez-vous ce cas dans votre boucle ?
Je vérifie / je rends :
- ☐ La balle rebondit sans jamais sortir par le haut ni par les côtés.
🛠 TP · Partie 4 — Les commandes
Mission : Le joueur déplace la raquette avec les flèches et avec la souris.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Utilisez un
Setde touches enfoncées. Pourquoi faut-ilpreventDefault()pour les flèches et la barre d'espace ? - La raquette ne doit jamais sortir du canvas. Écrivez cette contrainte en une seule ligne avec
Math.maxetMath.min. - Avec la souris, la raquette doit être centrée sur le pointeur. Comment convertir la position de la souris si le canvas est réduit sur un petit écran ?
- Ajoutez la pause avec la touche P. Pendant la pause, la souris doit-elle encore déplacer la raquette ?
Je vérifie / je rends :
- ☐ Commandes clavier et souris fonctionnelles, pause comprise.
🛠 TP · Partie 5 — Les collisions
Mission : Faites rebondir la balle sur la raquette et casser les briques.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Quel test de collision utilisez-vous entre la balle et un rectangle ? Écrivez-le une fois et réutilisez-le pour la raquette et les briques.
- Pour pouvoir viser, l'angle de rebond dépend du point d'impact sur la raquette (figure 2). Exprimez l'impact entre −1 et +1, puis transformez-le en angle entre −60° et +60°. Écrivez les formules de
vxetvy. - Pourquoi ne tester la raquette que lorsque la balle descend (
vy > 0) ? Que se passerait-il sinon ? - Quand la balle touche une brique, doit-on inverser
vxouvy? Comment savoir si elle a frappé le dessous ou le côté ? - Faut-il supprimer la brique du tableau ou la marquer comme cassée ? Comparez les deux solutions.
- Pourquoi est-il prudent de ne casser qu'une seule brique par image ?
Je vérifie / je rends :
- ☐ La balle rebondit sur la raquette avec un angle qui dépend de l'impact et casse les briques.
🛠 TP · Partie 6 — Score, vies et fin de partie
Mission : Ajoutez le score, les vies, la victoire, la défaite et le record.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Quand la balle sort par le bas, que doit-il se passer s'il reste des vies ? Et s'il n'en reste plus ?
- Comment détectez-vous la victoire ? (indice :
every) - Affichez un message centré sur un voile sombre semi-transparent pour la pause, la victoire et la défaite. Espace relance une partie après la fin.
- Enregistrez le meilleur score dans le
localStorage. Quand faut-il l'enregistrer : à chaque point, ou à la fin de la partie ? - La balle accélère de 2 % à chaque brique cassée. Comment augmenter la vitesse sans changer la direction ?
Je vérifie / je rends :
- ☐ Une partie complète jouable de bout en bout, avec le record conservé après un rechargement.
🛠 TP · Partie 7 — Bonus
Mission : Améliorez votre jeu.
Questions pour avancer (répondez dans votre compte rendu, puis appliquez dans votre projet) :
- Ajoutez des éclats (particules) quand une brique se casse. Quelle leçon réutilisez-vous ?
- Ajoutez des briques solides qui demandent deux coups, avec un changement de couleur au premier coup. Quelle donnée ajoutez-vous à la classe
Brique? - Ajoutez un niveau 2 avec une autre disposition des briques, décrite par un tableau de chaînes (
"XX..XX..XX"). - Ajoutez des sons avec
new Audio("rebond.mp3").play(). Pourquoi le navigateur refuse-t-il parfois de jouer un son avant la première action du joueur ? - Rendez le jeu jouable au doigt sur téléphone.
Je vérifie / je rends :
- ☐ Les améliorations choisies, décrites dans votre compte rendu.
Grille d'évaluation indicative
| Critère | Points |
|---|---|
| Partie 1 — plan des objets et schéma des états | 2 |
| Partie 2 — scène dessinée, grille centrée par le calcul | 3 |
Partie 3 — boucle avec dt, lancer, rebonds sur les murs | 3 |
| Partie 4 — clavier, souris (avec conversion), pause | 3 |
| Partie 5 — collisions raquette (angle) et briques | 4 |
| Partie 6 — score, vies, victoire, défaite, record | 3 |
| Qualité du code et compte rendu | 2 |
| Total (bonus partie 7 : jusqu'à +3) | 20 |
← 15.4 Interagir avec le canvas : souris, clavier et collisions