﻿{"id":595,"date":"2026-02-14T18:58:43","date_gmt":"2026-02-14T17:58:43","guid":{"rendered":"https:\/\/lmspro.fr\/sinitier-au-developpement-de-jeux-darcade\/"},"modified":"2026-02-15T13:35:32","modified_gmt":"2026-02-15T12:35:32","slug":"sinitier-au-developpement-de-jeux-darcade","status":"publish","type":"post","link":"https:\/\/lmspro.fr\/en\/sinitier-au-developpement-de-jeux-darcade\/","title":{"rendered":"Introduction to Arcade Game Development"},"content":{"rendered":"<article class=\"lms-video-card\"><div class=\"lms-content\"><div class=\"lms-meta\"><span class=\"lms-pill lms-pill--provider\">YouTube<\/span><span class=\"lms-pill lms-pill--muted\">longplay<\/span><span class=\"lms-pill lms-pill--muted\">arcade game (video game platform)<\/span><span class=\"lms-pill lms-pill--muted\">racing video game (video game genre)<\/span><span class=\"lms-pill lms-pill--muted\">hd<\/span><\/div><div class=\"lms-media\"><iframe class=\"lms-iframe\" src=\"https:\/\/www.youtube-nocookie.com\/embed\/rOfCbDMX4LQ?rel=0\" allowfullscreen><\/iframe><\/div><\/div><\/article>\n<h2>S&rsquo;initier au d\u00e9veloppement de Jeux d&rsquo;Arcade<\/h2>\n<p class=\"wpa-text\">Plongez dans l&rsquo;univers passionnant du d\u00e9veloppement de jeux d&rsquo;arcade ! Apprenez \u00e0 cr\u00e9er un jeu de course captivant en ma\u00eetrisant les fondamentaux de la programmation interactive. De la cr\u00e9ation du terrain de jeu jusqu&rsquo;aux m\u00e9caniques de collision, d\u00e9couvrez comment donner vie \u00e0 vos id\u00e9es ludiques.<\/p>\n<div class=\"article-meta\">\n<p><strong>Module :<\/strong> Module 6 : Module Bonus<\/p>\n<p><strong>Niveau :<\/strong> D\u00e9butant<\/p>\n<p><strong>Dur\u00e9e :<\/strong> 25 minutes<\/p>\n<p><strong>Pr\u00e9requis :<\/strong> Notions de base en HTML et CSS<\/p>\n<\/div>\n<h2>Objectifs p\u00e9dagogiques<\/h2>\n<ul>\n<li>Comprendre la structure de base d&rsquo;un jeu d&rsquo;arcade en JavaScript<\/li>\n<li>Ma\u00eetriser la cr\u00e9ation d&rsquo;\u00e9l\u00e9ments visuels interactifs avec Canvas<\/li>\n<li>Impl\u00e9menter la logique de mouvement et de contr\u00f4le du joueur<\/li>\n<li>D\u00e9velopper un syst\u00e8me de collision et de scoring<\/li>\n<li>Int\u00e9grer des m\u00e9caniques de jeu engageantes (obstacles, checkpoints)<\/li>\n<\/ul>\n<div class=\"wpa-accordion wpa-accordion-flush\" id=\"accordion-sinitier-au-developpement-de-jeux-darcade\">\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-sinitier-au-developpement-de-jeux-darcade-item-1\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">01<\/span> Cr\u00e9ation du terrain de jeu<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-sinitier-au-developpement-de-jeux-darcade-item-1\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Structure HTML du jeu<\/h4>\n<p>Pour cr\u00e9er un jeu d&rsquo;arcade, nous avons besoin d&rsquo;un \u00e9l\u00e9ment Canvas HTML5 qui servira de terrain de jeu. Le Canvas est comme une toile blanche sur laquelle nous pouvons dessiner en temps r\u00e9el avec JavaScript. C&rsquo;est l&rsquo;\u00e9l\u00e9ment parfait pour les jeux car il permet de mettre \u00e0 jour l&rsquo;affichage tr\u00e8s rapidement, cr\u00e9ant l&rsquo;illusion du mouvement.<\/p>\n<h4>Initialisation du contexte graphique<\/h4>\n<p>Une fois notre Canvas cr\u00e9\u00e9, nous devons obtenir son contexte 2D. Le contexte est l&rsquo;outil qui nous permet de dessiner sur le Canvas &#8211; imaginez-le comme un pinceau magique. Nous l&rsquo;utiliserons pour dessiner notre voiture, la route, les obstacles et tous les \u00e9l\u00e9ments visuels de notre jeu. La configuration initiale inclut aussi la d\u00e9finition des dimensions du jeu et des couleurs de base.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Le Canvas HTML5 est l&rsquo;\u00e9l\u00e9ment central de tout jeu web moderne car il offre des performances optimales pour le rendu graphique en temps r\u00e9el.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">Le Canvas HTML5 et son contexte 2D constituent la fondation technique de tout jeu d&rsquo;arcade web, permettant le rendu graphique haute performance.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Cr\u00e9er le terrain de jeu<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Cr\u00e9ez un Canvas avec une route et des lignes de d\u00e9limitation. Observez comment le contexte 2D permet de dessiner des formes g\u00e9om\u00e9triques.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-1\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (Game)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Jeu de Course - Terrain&lt;\/title&gt;\n    &lt;style&gt;\n        body {\n            margin: 0;\n            padding: 20px;\n            background: #222;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            font-family: Arial, sans-serif;\n        }\n        canvas {\n            border: 3px solid #fff;\n            background: #333;\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;canvas id=\"gameCanvas\" width=\"400\" height=\"600\"&gt;&lt;\/canvas&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Terrain de jeu - Course d'arcade\nconst canvas = document.getElementById('gameCanvas');\nconst ctx = canvas.getContext('2d');\n\n\/\/ Configuration du terrain\nconst gameWidth = canvas.width;\nconst gameHeight = canvas.height;\nconst roadWidth = 300;\nconst roadX = (gameWidth - roadWidth) \/ 2;\n\nfunction drawRoad() {\n    \/\/ Fond vert (herbe)\n    ctx.fillStyle = '#4CAF50';\n    ctx.fillRect(0, 0, gameWidth, gameHeight);\n    \n    \/\/ Route grise\n    ctx.fillStyle = '#555';\n    ctx.fillRect(roadX, 0, roadWidth, gameHeight);\n    \n    \/\/ Bordures de route\n    ctx.fillStyle = '#fff';\n    ctx.fillRect(roadX - 5, 0, 5, gameHeight); \/\/ Bordure gauche\n    ctx.fillRect(roadX + roadWidth, 0, 5, gameHeight); \/\/ Bordure droite\n    \n    \/\/ Ligne centrale pointill\u00e9e\n    ctx.fillStyle = '#ff0';\n    for (let y = 0; y < gameHeight; y += 40) {\n        ctx.fillRect(roadX + roadWidth\/2 - 2, y, 4, 20);\n    }\n}\n\nfunction animate() {\n    \/\/ Effacer le canvas\n    ctx.clearRect(0, 0, gameWidth, gameHeight);\n    \n    \/\/ Dessiner la route\n    drawRoad();\n    \n    \/\/ Titre du jeu\n    ctx.fillStyle = '#fff';\n    ctx.font = '24px Arial';\n    ctx.textAlign = 'center';\n    ctx.fillText('TERRAIN DE JEU', gameWidth\/2, 50);\n    \n    ctx.font = '16px Arial';\n    ctx.fillText('Route pr\u00eate pour la course !', gameWidth\/2, 80);\n    \n    requestAnimationFrame(animate);\n}\n\n\/\/ D\u00e9marrer l'animation\nanimate();<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-1\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (Game)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-sinitier-au-developpement-de-jeux-darcade-item-2\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">02<\/span> Cr\u00e9ation et contr\u00f4le de la voiture<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-sinitier-au-developpement-de-jeux-darcade-item-2\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Conception de la voiture du joueur<\/h4>\n<p>La voiture est l'\u00e9l\u00e9ment principal avec lequel le joueur interagit. Nous la repr\u00e9sentons comme un objet JavaScript contenant sa position (x, y), sa taille, sa couleur et sa vitesse. Pensez \u00e0 la voiture comme \u00e0 un personnage de jeu vid\u00e9o : elle a des propri\u00e9t\u00e9s (o\u00f9 elle se trouve, \u00e0 quelle vitesse elle va) et des comportements (bouger \u00e0 gauche, \u00e0 droite). Pour la dessiner, nous utilisons des rectangles color\u00e9s qui forment la carrosserie et les roues.<\/p>\n<h4>Syst\u00e8me de contr\u00f4les clavier<\/h4>\n<p>Pour que le joueur puisse contr\u00f4ler sa voiture, nous devons \u00e9couter les \u00e9v\u00e9nements clavier. Les fl\u00e8ches directionnelles gauche et droite permettront de d\u00e9placer la voiture horizontalement. Nous utilisons des \"event listeners\" qui r\u00e9agissent quand une touche est press\u00e9e ou rel\u00e2ch\u00e9e. C'est comme avoir des capteurs qui d\u00e9tectent les actions du joueur et les traduisent en mouvements dans le jeu.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : La gestion des \u00e9v\u00e9nements clavier est essentielle pour cr\u00e9er une interaction fluide entre le joueur et le jeu.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">La voiture du joueur est un objet avec des propri\u00e9t\u00e9s (position, vitesse) et des m\u00e9thodes (mouvement, affichage) contr\u00f4l\u00e9es par les \u00e9v\u00e9nements clavier.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Voiture contr\u00f4lable<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Ajoutez une voiture que vous pouvez d\u00e9placer avec les fl\u00e8ches du clavier. Testez les contr\u00f4les gauche et droite.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-2\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (Game)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Jeu de Course - Contr\u00f4les&lt;\/title&gt;\n    &lt;style&gt;\n        body {\n            margin: 0;\n            padding: 20px;\n            background: #222;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            font-family: Arial, sans-serif;\n        }\n        .game-container {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            gap: 10px;\n        }\n        canvas {\n            border: 3px solid #fff;\n            background: #333;\n        }\n        .controls {\n            color: #fff;\n            text-align: center;\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=\"game-container\"&gt;\n        &lt;canvas id=\"gameCanvas\" width=\"400\" height=\"600\"&gt;&lt;\/canvas&gt;\n        &lt;div class=\"controls\"&gt;\n            &lt;p&gt;Utilisez \u2190 \u2192 pour d\u00e9placer la voiture&lt;\/p&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Voiture contr\u00f4lable - Course d'arcade\nconst canvas = document.getElementById('gameCanvas');\nconst ctx = canvas.getContext('2d');\n\n\/\/ Configuration du jeu\nconst gameWidth = canvas.width;\nconst gameHeight = canvas.height;\nconst roadWidth = 300;\nconst roadX = (gameWidth - roadWidth) \/ 2;\n\n\/\/ Objet voiture du joueur\nconst player = {\n    x: gameWidth \/ 2 - 15,\n    y: gameHeight - 100,\n    width: 30,\n    height: 50,\n    speed: 5,\n    color: '#ff4444'\n};\n\n\/\/ \u00c9tat des touches\nconst keys = {\n    left: false,\n    right: false\n};\n\n\/\/ Gestion des \u00e9v\u00e9nements clavier\ndocument.addEventListener('keydown', (e) => {\n    switch(e.key) {\n        case 'ArrowLeft':\n            keys.left = true;\n            e.preventDefault();\n            break;\n        case 'ArrowRight':\n            keys.right = true;\n            e.preventDefault();\n            break;\n    }\n});\n\ndocument.addEventListener('keyup', (e) => {\n    switch(e.key) {\n        case 'ArrowLeft':\n            keys.left = false;\n            break;\n        case 'ArrowRight':\n            keys.right = false;\n            break;\n    }\n});\n\nfunction updatePlayer() {\n    \/\/ D\u00e9placement horizontal\n    if (keys.left && player.x > roadX) {\n        player.x -= player.speed;\n    }\n    if (keys.right && player.x < roadX + roadWidth - player.width) {\n        player.x += player.speed;\n    }\n}\n\nfunction drawRoad() {\n    \/\/ Fond vert (herbe)\n    ctx.fillStyle = '#4CAF50';\n    ctx.fillRect(0, 0, gameWidth, gameHeight);\n    \n    \/\/ Route grise\n    ctx.fillStyle = '#555';\n    ctx.fillRect(roadX, 0, roadWidth, gameHeight);\n    \n    \/\/ Bordures de route\n    ctx.fillStyle = '#fff';\n    ctx.fillRect(roadX - 5, 0, 5, gameHeight);\n    ctx.fillRect(roadX + roadWidth, 0, 5, gameHeight);\n    \n    \/\/ Ligne centrale\n    ctx.fillStyle = '#ff0';\n    for (let y = 0; y < gameHeight; y += 40) {\n        ctx.fillRect(roadX + roadWidth\/2 - 2, y, 4, 20);\n    }\n}\n\nfunction drawPlayer() {\n    \/\/ Corps de la voiture\n    ctx.fillStyle = player.color;\n    ctx.fillRect(player.x, player.y, player.width, player.height);\n    \n    \/\/ Pare-brise\n    ctx.fillStyle = '#87CEEB';\n    ctx.fillRect(player.x + 3, player.y + 5, player.width - 6, 15);\n    \n    \/\/ Roues\n    ctx.fillStyle = '#000';\n    ctx.fillRect(player.x - 2, player.y + 10, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + 10, 6, 12);\n    ctx.fillRect(player.x - 2, player.y + player.height - 22, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + player.height - 22, 6, 12);\n}\n\nfunction animate() {\n    \/\/ Mettre \u00e0 jour la logique\n    updatePlayer();\n    \n    \/\/ Effacer et redessiner\n    ctx.clearRect(0, 0, gameWidth, gameHeight);\n    drawRoad();\n    drawPlayer();\n    \n    \/\/ Interface\n    ctx.fillStyle = '#fff';\n    ctx.font = '16px Arial';\n    ctx.textAlign = 'center';\n    ctx.fillText('D\u00e9placez votre voiture !', gameWidth\/2, 30);\n    \n    requestAnimationFrame(animate);\n}\n\n\/\/ Focus pour capturer les \u00e9v\u00e9nements clavier\ncanvas.focus();\ncanvas.tabIndex = 0;\n\n\/\/ D\u00e9marrer le jeu\nanimate();<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-2\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (Game)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-sinitier-au-developpement-de-jeux-darcade-item-3\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">03<\/span> Ajout des obstacles mobiles<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-sinitier-au-developpement-de-jeux-darcade-item-3\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Cr\u00e9ation du syst\u00e8me d'obstacles<\/h4>\n<p>Les obstacles sont les \u00e9l\u00e9ments qui rendent le jeu challenging et amusant. Nous les cr\u00e9ons comme un tableau d'objets, chacun ayant sa propre position, taille et vitesse. Les obstacles apparaissent en haut de l'\u00e9cran et descendent vers le joueur, cr\u00e9ant l'illusion que la voiture avance \u00e0 grande vitesse. C'est le m\u00eame principe que dans les anciens jeux d'arcade o\u00f9 le d\u00e9cor d\u00e9file pour simuler le mouvement.<\/p>\n<h4>G\u00e9n\u00e9ration automatique et mouvement<\/h4>\n<p>Pour maintenir l'int\u00e9r\u00eat du jeu, nous devons g\u00e9n\u00e9rer de nouveaux obstacles de fa\u00e7on r\u00e9guli\u00e8re et al\u00e9atoire. Un syst\u00e8me de timer d\u00e9clenche la cr\u00e9ation d'un nouvel obstacle toutes les quelques secondes, \u00e0 une position horizontale al\u00e9atoire sur la route. Les obstacles se d\u00e9placent vers le bas \u00e0 chaque frame d'animation, et sont supprim\u00e9s quand ils sortent de l'\u00e9cran pour optimiser les performances.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : La gestion automatique des obstacles (cr\u00e9ation, mouvement, suppression) est cruciale pour maintenir des performances optimales et un gameplay fluide.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">Les obstacles mobiles cr\u00e9ent le d\u00e9fi du jeu gr\u00e2ce \u00e0 un syst\u00e8me de g\u00e9n\u00e9ration al\u00e9atoire, de mouvement automatique et de nettoyage m\u00e9moire.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Obstacles en mouvement<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Impl\u00e9mentez des obstacles qui apparaissent al\u00e9atoirement en haut de l'\u00e9cran et descendent vers votre voiture. Observez la g\u00e9n\u00e9ration automatique.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-3\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (Game)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Jeu de Course - Obstacles&lt;\/title&gt;\n    &lt;style&gt;\n        body {\n            margin: 0;\n            padding: 20px;\n            background: #222;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            font-family: Arial, sans-serif;\n        }\n        .game-container {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            gap: 10px;\n        }\n        canvas {\n            border: 3px solid #fff;\n            background: #333;\n        }\n        .ui {\n            color: #fff;\n            text-align: center;\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=\"game-container\"&gt;\n        &lt;canvas id=\"gameCanvas\" width=\"400\" height=\"600\"&gt;&lt;\/canvas&gt;\n        &lt;div class=\"ui\"&gt;\n            &lt;p&gt;\u2190 \u2192 pour \u00e9viter les obstacles&lt;\/p&gt;\n            &lt;p&gt;Obstacles \u00e9vit\u00e9s: &lt;span id=\"score\"&gt;0&lt;\/span&gt;&lt;\/p&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Obstacles mobiles - Course d'arcade\nconst canvas = document.getElementById('gameCanvas');\nconst ctx = canvas.getContext('2d');\n\n\/\/ Configuration\nconst gameWidth = canvas.width;\nconst gameHeight = canvas.height;\nconst roadWidth = 300;\nconst roadX = (gameWidth - roadWidth) \/ 2;\n\n\/\/ Voiture du joueur\nconst player = {\n    x: gameWidth \/ 2 - 15,\n    y: gameHeight - 100,\n    width: 30,\n    height: 50,\n    speed: 5\n};\n\n\/\/ Syst\u00e8me d'obstacles\nconst obstacles = [];\nlet obstacleTimer = 0;\nlet score = 0;\n\n\/\/ Contr\u00f4les\nconst keys = { left: false, right: false };\n\ndocument.addEventListener('keydown', (e) => {\n    if (e.key === 'ArrowLeft') keys.left = true;\n    if (e.key === 'ArrowRight') keys.right = true;\n    e.preventDefault();\n});\n\ndocument.addEventListener('keyup', (e) => {\n    if (e.key === 'ArrowLeft') keys.left = false;\n    if (e.key === 'ArrowRight') keys.right = false;\n});\n\nfunction createObstacle() {\n    const obstacle = {\n        x: roadX + Math.random() * (roadWidth - 30),\n        y: -50,\n        width: 30,\n        height: 50,\n        speed: 3 + Math.random() * 2,\n        color: `hsl(${Math.random() * 360}, 70%, 50%)`\n    };\n    obstacles.push(obstacle);\n}\n\nfunction updatePlayer() {\n    if (keys.left && player.x > roadX) {\n        player.x -= player.speed;\n    }\n    if (keys.right && player.x < roadX + roadWidth - player.width) {\n        player.x += player.speed;\n    }\n}\n\nfunction updateObstacles() {\n    \/\/ Cr\u00e9er de nouveaux obstacles\n    obstacleTimer++;\n    if (obstacleTimer > 60) { \/\/ Environ 1 par seconde\n        createObstacle();\n        obstacleTimer = 0;\n    }\n    \n    \/\/ D\u00e9placer et nettoyer les obstacles\n    for (let i = obstacles.length - 1; i >= 0; i--) {\n        obstacles[i].y += obstacles[i].speed;\n        \n        \/\/ Supprimer si hors \u00e9cran\n        if (obstacles[i].y > gameHeight) {\n            obstacles.splice(i, 1);\n            score++; \/\/ Point pour avoir \u00e9vit\u00e9 l'obstacle\n            document.getElementById('score').textContent = score;\n        }\n    }\n}\n\nfunction drawRoad() {\n    \/\/ Herbe\n    ctx.fillStyle = '#4CAF50';\n    ctx.fillRect(0, 0, gameWidth, gameHeight);\n    \n    \/\/ Route\n    ctx.fillStyle = '#555';\n    ctx.fillRect(roadX, 0, roadWidth, gameHeight);\n    \n    \/\/ Bordures\n    ctx.fillStyle = '#fff';\n    ctx.fillRect(roadX - 5, 0, 5, gameHeight);\n    ctx.fillRect(roadX + roadWidth, 0, 5, gameHeight);\n    \n    \/\/ Ligne centrale anim\u00e9e\n    ctx.fillStyle = '#ff0';\n    const lineOffset = (Date.now() * 0.1) % 40;\n    for (let y = -lineOffset; y < gameHeight; y += 40) {\n        ctx.fillRect(roadX + roadWidth\/2 - 2, y, 4, 20);\n    }\n}\n\nfunction drawPlayer() {\n    \/\/ Voiture\n    ctx.fillStyle = '#ff4444';\n    ctx.fillRect(player.x, player.y, player.width, player.height);\n    \n    \/\/ D\u00e9tails\n    ctx.fillStyle = '#87CEEB';\n    ctx.fillRect(player.x + 3, player.y + 5, player.width - 6, 15);\n    \n    \/\/ Roues\n    ctx.fillStyle = '#000';\n    ctx.fillRect(player.x - 2, player.y + 10, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + 10, 6, 12);\n    ctx.fillRect(player.x - 2, player.y + player.height - 22, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + player.height - 22, 6, 12);\n}\n\nfunction drawObstacles() {\n    obstacles.forEach(obstacle => {\n        \/\/ Corps de l'obstacle\n        ctx.fillStyle = obstacle.color;\n        ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);\n        \n        \/\/ Pare-brise\n        ctx.fillStyle = 'rgba(255,255,255,0.3)';\n        ctx.fillRect(obstacle.x + 3, obstacle.y + obstacle.height - 20, obstacle.width - 6, 15);\n        \n        \/\/ Roues\n        ctx.fillStyle = '#000';\n        ctx.fillRect(obstacle.x - 2, obstacle.y + 10, 6, 12);\n        ctx.fillRect(obstacle.x + obstacle.width - 4, obstacle.y + 10, 6, 12);\n    });\n}\n\nfunction animate() {\n    updatePlayer();\n    updateObstacles();\n    \n    ctx.clearRect(0, 0, gameWidth, gameHeight);\n    drawRoad();\n    drawObstacles();\n    drawPlayer();\n    \n    \/\/ Interface\n    ctx.fillStyle = '#fff';\n    ctx.font = '16px Arial';\n    ctx.textAlign = 'center';\n    ctx.fillText('\u00c9VITEZ LES OBSTACLES !', gameWidth\/2, 30);\n    \n    requestAnimationFrame(animate);\n}\n\n\/\/ D\u00e9marrer\nanimate();<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-3\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (Game)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-sinitier-au-developpement-de-jeux-darcade-item-4\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">04<\/span> Syst\u00e8me de collision et game over<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-sinitier-au-developpement-de-jeux-darcade-item-4\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>D\u00e9tection de collision rectangulaire<\/h4>\n<p>La d\u00e9tection de collision est le syst\u00e8me qui d\u00e9termine quand la voiture du joueur touche un obstacle. Pour des formes rectangulaires comme nos voitures, nous utilisons l'algorithme AABB (Axis-Aligned Bounding Box). Cet algorithme v\u00e9rifie si deux rectangles se chevauchent en comparant leurs coordonn\u00e9es. Si le bord droit de la voiture est \u00e0 droite du bord gauche de l'obstacle ET le bord gauche de la voiture est \u00e0 gauche du bord droit de l'obstacle (et la m\u00eame logique pour le haut et le bas), alors il y a collision.<\/p>\n<h4>Gestion du game over<\/h4>\n<p>Quand une collision est d\u00e9tect\u00e9e, le jeu passe en \u00e9tat \"game over\". Nous arr\u00eatons la g\u00e9n\u00e9ration de nouveaux obstacles, affichons un message de fin de partie avec le score final, et proposons au joueur de recommencer. Cette transition d'\u00e9tat est fondamentale dans tout jeu - elle donne un sens aux actions du joueur et cr\u00e9e l'envie de recommencer pour faire mieux.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : La d\u00e9tection de collision AABB est simple \u00e0 impl\u00e9menter et suffisamment pr\u00e9cise pour la plupart des jeux d'arcade 2D.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">Le syst\u00e8me de collision transforme le jeu en v\u00e9ritable challenge avec des cons\u00e9quences r\u00e9elles aux actions du joueur et un cycle de jeu complet.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Collision et Game Over<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Ajoutez la d\u00e9tection de collision et un \u00e9cran de game over avec possibilit\u00e9 de restart. Testez en touchant volontairement un obstacle.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-4\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (Game)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Jeu de Course - Collision&lt;\/title&gt;\n    &lt;style&gt;\n        body {\n            margin: 0;\n            padding: 20px;\n            background: #222;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            font-family: Arial, sans-serif;\n        }\n        .game-container {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            gap: 15px;\n        }\n        canvas {\n            border: 3px solid #fff;\n            background: #333;\n        }\n        .ui {\n            color: #fff;\n            text-align: center;\n        }\n        .stats {\n            display: flex;\n            gap: 20px;\n            color: #fff;\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=\"game-container\"&gt;\n        &lt;canvas id=\"gameCanvas\" width=\"400\" height=\"600\"&gt;&lt;\/canvas&gt;\n        &lt;div class=\"stats\"&gt;\n            &lt;div&gt;Score: &lt;span id=\"score\"&gt;0&lt;\/span&gt;&lt;\/div&gt;\n            &lt;div&gt;Meilleur: &lt;span id=\"bestScore\"&gt;0&lt;\/span&gt;&lt;\/div&gt;\n        &lt;\/div&gt;\n        &lt;div class=\"ui\"&gt;\n            &lt;p&gt;\u2190 \u2192 pour \u00e9viter \u2022 ESPACE pour restart&lt;\/p&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Syst\u00e8me de collision - Course d'arcade\nconst canvas = document.getElementById('gameCanvas');\nconst ctx = canvas.getContext('2d');\n\n\/\/ Configuration\nconst gameWidth = canvas.width;\nconst gameHeight = canvas.height;\nconst roadWidth = 300;\nconst roadX = (gameWidth - roadWidth) \/ 2;\n\n\/\/ \u00c9tats du jeu\nlet gameState = 'playing'; \/\/ 'playing' ou 'gameOver'\nlet score = 0;\nlet bestScore = localStorage.getItem('bestScore') || 0;\ndocument.getElementById('bestScore').textContent = bestScore;\n\n\/\/ Voiture du joueur\nconst player = {\n    x: gameWidth \/ 2 - 15,\n    y: gameHeight - 100,\n    width: 30,\n    height: 50,\n    speed: 5\n};\n\n\/\/ Obstacles\nconst obstacles = [];\nlet obstacleTimer = 0;\n\n\/\/ Contr\u00f4les\nconst keys = { left: false, right: false };\n\ndocument.addEventListener('keydown', (e) => {\n    if (e.key === 'ArrowLeft') keys.left = true;\n    if (e.key === 'ArrowRight') keys.right = true;\n    if (e.key === ' ' && gameState === 'gameOver') {\n        restart();\n    }\n    e.preventDefault();\n});\n\ndocument.addEventListener('keyup', (e) => {\n    if (e.key === 'ArrowLeft') keys.left = false;\n    if (e.key === 'ArrowRight') keys.right = false;\n});\n\nfunction checkCollision(rect1, rect2) {\n    return rect1.x < rect2.x + rect2.width &#038;&#038;\n           rect1.x + rect1.width > rect2.x &&\n           rect1.y < rect2.y + rect2.height &#038;&#038;\n           rect1.y + rect1.height > rect2.y;\n}\n\nfunction restart() {\n    gameState = 'playing';\n    score = 0;\n    document.getElementById('score').textContent = score;\n    obstacles.length = 0;\n    obstacleTimer = 0;\n    player.x = gameWidth \/ 2 - 15;\n    player.y = gameHeight - 100;\n}\n\nfunction createObstacle() {\n    const obstacle = {\n        x: roadX + Math.random() * (roadWidth - 30),\n        y: -50,\n        width: 30,\n        height: 50,\n        speed: 3 + Math.random() * 2,\n        color: `hsl(${Math.random() * 360}, 70%, 50%)`\n    };\n    obstacles.push(obstacle);\n}\n\nfunction updateGame() {\n    if (gameState !== 'playing') return;\n    \n    \/\/ D\u00e9placer le joueur\n    if (keys.left && player.x > roadX) {\n        player.x -= player.speed;\n    }\n    if (keys.right && player.x < roadX + roadWidth - player.width) {\n        player.x += player.speed;\n    }\n    \n    \/\/ G\u00e9rer les obstacles\n    obstacleTimer++;\n    if (obstacleTimer > 60) {\n        createObstacle();\n        obstacleTimer = 0;\n    }\n    \n    \/\/ D\u00e9placer obstacles et v\u00e9rifier collisions\n    for (let i = obstacles.length - 1; i >= 0; i--) {\n        obstacles[i].y += obstacles[i].speed;\n        \n        \/\/ Collision avec le joueur\n        if (checkCollision(player, obstacles[i])) {\n            gameState = 'gameOver';\n            if (score > bestScore) {\n                bestScore = score;\n                localStorage.setItem('bestScore', bestScore);\n                document.getElementById('bestScore').textContent = bestScore;\n            }\n        }\n        \n        \/\/ Supprimer si hors \u00e9cran\n        if (obstacles[i].y > gameHeight) {\n            obstacles.splice(i, 1);\n            score++;\n            document.getElementById('score').textContent = score;\n        }\n    }\n}\n\nfunction drawRoad() {\n    \/\/ Herbe\n    ctx.fillStyle = '#4CAF50';\n    ctx.fillRect(0, 0, gameWidth, gameHeight);\n    \n    \/\/ Route\n    ctx.fillStyle = '#555';\n    ctx.fillRect(roadX, 0, roadWidth, gameHeight);\n    \n    \/\/ Bordures\n    ctx.fillStyle = '#fff';\n    ctx.fillRect(roadX - 5, 0, 5, gameHeight);\n    ctx.fillRect(roadX + roadWidth, 0, 5, gameHeight);\n    \n    \/\/ Ligne centrale anim\u00e9e\n    ctx.fillStyle = '#ff0';\n    const lineOffset = gameState === 'playing' ? (Date.now() * 0.1) % 40 : 0;\n    for (let y = -lineOffset; y < gameHeight; y += 40) {\n        ctx.fillRect(roadX + roadWidth\/2 - 2, y, 4, 20);\n    }\n}\n\nfunction drawPlayer() {\n    \/\/ Voiture (rouge ou grise si game over)\n    ctx.fillStyle = gameState === 'playing' ? '#ff4444' : '#888';\n    ctx.fillRect(player.x, player.y, player.width, player.height);\n    \n    \/\/ D\u00e9tails\n    ctx.fillStyle = gameState === 'playing' ? '#87CEEB' : '#666';\n    ctx.fillRect(player.x + 3, player.y + 5, player.width - 6, 15);\n    \n    \/\/ Roues\n    ctx.fillStyle = '#000';\n    ctx.fillRect(player.x - 2, player.y + 10, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + 10, 6, 12);\n    ctx.fillRect(player.x - 2, player.y + player.height - 22, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + player.height - 22, 6, 12);\n}\n\nfunction drawObstacles() {\n    obstacles.forEach(obstacle => {\n        ctx.fillStyle = obstacle.color;\n        ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);\n        \n        ctx.fillStyle = 'rgba(255,255,255,0.3)';\n        ctx.fillRect(obstacle.x + 3, obstacle.y + obstacle.height - 20, obstacle.width - 6, 15);\n        \n        ctx.fillStyle = '#000';\n        ctx.fillRect(obstacle.x - 2, obstacle.y + 10, 6, 12);\n        ctx.fillRect(obstacle.x + obstacle.width - 4, obstacle.y + 10, 6, 12);\n    });\n}\n\nfunction drawUI() {\n    ctx.fillStyle = '#fff';\n    ctx.font = '16px Arial';\n    ctx.textAlign = 'center';\n    \n    if (gameState === 'playing') {\n        ctx.fillText('\u00c9VITEZ LES OBSTACLES !', gameWidth\/2, 30);\n    } else {\n        \/\/ Game Over screen\n        ctx.fillStyle = 'rgba(0,0,0,0.8)';\n        ctx.fillRect(0, 0, gameWidth, gameHeight);\n        \n        ctx.fillStyle = '#ff4444';\n        ctx.font = '32px Arial';\n        ctx.fillText('GAME OVER', gameWidth\/2, gameHeight\/2 - 60);\n        \n        ctx.fillStyle = '#fff';\n        ctx.font = '18px Arial';\n        ctx.fillText(`Score final: ${score}`, gameWidth\/2, gameHeight\/2 - 20);\n        \n        if (score === bestScore && score > 0) {\n            ctx.fillStyle = '#ff0';\n            ctx.fillText('\ud83c\udfc6 NOUVEAU RECORD ! \ud83c\udfc6', gameWidth\/2, gameHeight\/2 + 10);\n        }\n        \n        ctx.fillStyle = '#ccc';\n        ctx.font = '14px Arial';\n        ctx.fillText('Appuyez sur ESPACE pour recommencer', gameWidth\/2, gameHeight\/2 + 50);\n    }\n}\n\nfunction animate() {\n    updateGame();\n    \n    ctx.clearRect(0, 0, gameWidth, gameHeight);\n    drawRoad();\n    drawObstacles();\n    drawPlayer();\n    drawUI();\n    \n    requestAnimationFrame(animate);\n}\n\n\/\/ D\u00e9marrer\nanimate();<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-4\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (Game)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-sinitier-au-developpement-de-jeux-darcade-item-5\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">05<\/span> Am\u00e9liorations et finalisation<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-sinitier-au-developpement-de-jeux-darcade-item-5\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Syst\u00e8me de niveaux progressifs<\/h4>\n<p>Pour maintenir l'int\u00e9r\u00eat du joueur, nous ajoutons un syst\u00e8me de difficult\u00e9 progressive. Plus le score augmente, plus les obstacles deviennent rapides et nombreux. Cette escalade de difficult\u00e9 cr\u00e9e une courbe d'apprentissage naturelle : le joueur s'am\u00e9liore en m\u00eame temps que le jeu devient plus difficile. Nous pouvons aussi ajouter diff\u00e9rents types d'obstacles avec des comportements vari\u00e9s (d\u00e9placement lat\u00e9ral, changement de vitesse).<\/p>\n<h4>Effets visuels et audio<\/h4>\n<p>Les effets sp\u00e9ciaux transforment un jeu fonctionnel en exp\u00e9rience immersive. Les particules d'explosion lors des collisions, les tra\u00een\u00e9es de fum\u00e9e, les effets de vitesse rendent le jeu plus spectaculaire. L'ajout d'effets sonores (moteur, collision, score) et d'une musique de fond compl\u00e8te l'exp\u00e9rience sensorielle. Ces \u00e9l\u00e9ments semblent optionnels mais sont en r\u00e9alit\u00e9 cruciaux pour l'engagement du joueur.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Les am\u00e9liorations audiovisuelles et la progression de difficult\u00e9 sont essentielles pour transformer un prototype en v\u00e9ritable jeu addictif.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">La finalisation d'un jeu implique d'ajouter de la progression, des effets visuels et une exp\u00e9rience utilisateur polie pour cr\u00e9er un produit fini et engageant.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Jeu complet avec effets<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Cr\u00e9ez la version finale avec difficult\u00e9 progressive, effets de particules, diff\u00e9rents types d'obstacles et une interface utilisateur compl\u00e8te.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-5\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (Game)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Course d'Arcade - Version Compl\u00e8te&lt;\/title&gt;\n    &lt;style&gt;\n        body {\n            margin: 0;\n            padding: 20px;\n            background: linear-gradient(45deg, #1a1a2e, #16213e);\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            min-height: 100vh;\n            font-family: 'Arial', sans-serif;\n        }\n        .game-container {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            gap: 15px;\n        }\n        canvas {\n            border: 3px solid #00ff88;\n            background: #0f3460;\n            box-shadow: 0 0 20px rgba(0,255,136,0.3);\n            border-radius: 10px;\n        }\n        .ui {\n            color: #00ff88;\n            text-align: center;\n            font-weight: bold;\n        }\n        .stats {\n            display: grid;\n            grid-template-columns: repeat(3, 1fr);\n            gap: 20px;\n            color: #fff;\n            font-weight: bold;\n        }\n        .stat-box {\n            background: rgba(0,255,136,0.1);\n            padding: 10px;\n            border-radius: 8px;\n            text-align: center;\n            border: 1px solid rgba(0,255,136,0.3);\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=\"game-container\"&gt;\n        &lt;canvas id=\"gameCanvas\" width=\"400\" height=\"600\"&gt;&lt;\/canvas&gt;\n        &lt;div class=\"stats\"&gt;\n            &lt;div class=\"stat-box\"&gt;\n                &lt;div&gt;Score&lt;\/div&gt;\n                &lt;div id=\"score\"&gt;0&lt;\/div&gt;\n            &lt;\/div&gt;\n            &lt;div class=\"stat-box\"&gt;\n                &lt;div&gt;Niveau&lt;\/div&gt;\n                &lt;div id=\"level\"&gt;1&lt;\/div&gt;\n            &lt;\/div&gt;\n            &lt;div class=\"stat-box\"&gt;\n                &lt;div&gt;Record&lt;\/div&gt;\n                &lt;div id=\"bestScore\"&gt;0&lt;\/div&gt;\n            &lt;\/div&gt;\n        &lt;\/div&gt;\n        &lt;div class=\"ui\"&gt;\n            &lt;p&gt;\u2190 \u2192 Diriger \u2022 ESPACE Restart&lt;\/p&gt;\n        &lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">\/\/ Jeu de course complet - Inspir\u00e9 de javascript-racer\nconst canvas = document.getElementById('gameCanvas');\nconst ctx = canvas.getContext('2d');\n\n\/\/ Configuration\nconst gameWidth = canvas.width;\nconst gameHeight = canvas.height;\nconst roadWidth = 300;\nconst roadX = (gameWidth - roadWidth) \/ 2;\n\n\/\/ \u00c9tat du jeu\nlet gameState = 'playing';\nlet score = 0;\nlet level = 1;\nlet bestScore = localStorage.getItem('racebestScore') || 0;\ndocument.getElementById('bestScore').textContent = bestScore;\n\n\/\/ Joueur\nconst player = {\n    x: gameWidth \/ 2 - 15,\n    y: gameHeight - 100,\n    width: 30,\n    height: 50,\n    speed: 6,\n    trail: []\n};\n\n\/\/ Obstacles avec types diff\u00e9rents\nconst obstacles = [];\nconst obstacleTypes = [\n    { color: '#ff4444', speed: 3, width: 30, height: 50 }, \/\/ Voiture normale\n    { color: '#44ff44', speed: 2, width: 40, height: 60 }, \/\/ Camion lent\n    { color: '#4444ff', speed: 5, width: 25, height: 45 }, \/\/ Voiture rapide\n    { color: '#ff44ff', speed: 4, width: 35, height: 55 }  \/\/ Voiture sp\u00e9ciale\n];\n\n\/\/ Syst\u00e8me de particules\nconst particles = [];\n\n\/\/ Contr\u00f4les et timing\nconst keys = { left: false, right: false };\nlet obstacleTimer = 0;\nlet levelTimer = 0;\n\n\/\/ \u00c9v\u00e9nements clavier\ndocument.addEventListener('keydown', (e) => {\n    if (e.key === 'ArrowLeft') keys.left = true;\n    if (e.key === 'ArrowRight') keys.right = true;\n    if (e.key === ' ' && gameState === 'gameOver') restart();\n    e.preventDefault();\n});\n\ndocument.addEventListener('keyup', (e) => {\n    if (e.key === 'ArrowLeft') keys.left = false;\n    if (e.key === 'ArrowRight') keys.right = false;\n});\n\nfunction createParticle(x, y, color = '#ff0') {\n    particles.push({\n        x: x,\n        y: y,\n        vx: (Math.random() - 0.5) * 4,\n        vy: (Math.random() - 0.5) * 4,\n        life: 30,\n        maxLife: 30,\n        color: color\n    });\n}\n\nfunction updateParticles() {\n    for (let i = particles.length - 1; i >= 0; i--) {\n        const p = particles[i];\n        p.x += p.vx;\n        p.y += p.vy;\n        p.life--;\n        p.vy += 0.1; \/\/ Gravit\u00e9\n        \n        if (p.life <= 0) {\n            particles.splice(i, 1);\n        }\n    }\n}\n\nfunction drawParticles() {\n    particles.forEach(p => {\n        const alpha = p.life \/ p.maxLife;\n        ctx.save();\n        ctx.globalAlpha = alpha;\n        ctx.fillStyle = p.color;\n        ctx.fillRect(p.x, p.y, 3, 3);\n        ctx.restore();\n    });\n}\n\nfunction checkCollision(rect1, rect2) {\n    return rect1.x < rect2.x + rect2.width &#038;&#038;\n           rect1.x + rect1.width > rect2.x &&\n           rect1.y < rect2.y + rect2.height &#038;&#038;\n           rect1.y + rect1.height > rect2.y;\n}\n\nfunction restart() {\n    gameState = 'playing';\n    score = 0;\n    level = 1;\n    obstacles.length = 0;\n    particles.length = 0;\n    obstacleTimer = 0;\n    levelTimer = 0;\n    player.x = gameWidth \/ 2 - 15;\n    player.trail.length = 0;\n    updateUI();\n}\n\nfunction updateUI() {\n    document.getElementById('score').textContent = score;\n    document.getElementById('level').textContent = level;\n    if (score > bestScore) {\n        bestScore = score;\n        localStorage.setItem('racebestScore', bestScore);\n        document.getElementById('bestScore').textContent = bestScore;\n    }\n}\n\nfunction createObstacle() {\n    const type = obstacleTypes[Math.floor(Math.random() * obstacleTypes.length)];\n    const obstacle = {\n        x: roadX + Math.random() * (roadWidth - type.width),\n        y: -type.height,\n        width: type.width,\n        height: type.height,\n        speed: type.speed + level * 0.5,\n        color: type.color\n    };\n    obstacles.push(obstacle);\n}\n\nfunction updateGame() {\n    if (gameState !== 'playing') return;\n    \n    \/\/ Progression de niveau\n    levelTimer++;\n    if (levelTimer > 1800) { \/\/ 30 secondes\n        level++;\n        levelTimer = 0;\n        \/\/ Effets de niveau\n        for (let i = 0; i < 10; i++) {\n            createParticle(gameWidth\/2 + Math.random() * 100 - 50, 100, '#00ff88');\n        }\n    }\n    \n    \/\/ Trail du joueur\n    player.trail.unshift({ x: player.x + player.width\/2, y: player.y + player.height });\n    if (player.trail.length > 8) player.trail.pop();\n    \n    \/\/ Mouvement joueur\n    if (keys.left && player.x > roadX) {\n        player.x -= player.speed;\n        createParticle(player.x + player.width, player.y + player.height, '#88aaff');\n    }\n    if (keys.right && player.x < roadX + roadWidth - player.width) {\n        player.x += player.speed;\n        createParticle(player.x, player.y + player.height, '#88aaff');\n    }\n    \n    \/\/ G\u00e9n\u00e9ration d'obstacles (plus fr\u00e9quente aux niveaux \u00e9lev\u00e9s)\n    obstacleTimer++;\n    const spawnRate = Math.max(40 - level * 3, 20);\n    if (obstacleTimer > spawnRate) {\n        createObstacle();\n        obstacleTimer = 0;\n    }\n    \n    \/\/ Mise \u00e0 jour obstacles\n    for (let i = obstacles.length - 1; i >= 0; i--) {\n        obstacles[i].y += obstacles[i].speed;\n        \n        \/\/ Collision\n        if (checkCollision(player, obstacles[i])) {\n            gameState = 'gameOver';\n            \/\/ Explosion\n            for (let j = 0; j < 20; j++) {\n                createParticle(\n                    player.x + Math.random() * player.width,\n                    player.y + Math.random() * player.height,\n                    '#ff4444'\n                );\n            }\n            updateUI();\n        }\n        \n        \/\/ Nettoyage\n        if (obstacles[i].y > gameHeight) {\n            obstacles.splice(i, 1);\n            score += 10;\n            updateUI();\n        }\n    }\n    \n    updateParticles();\n}\n\nfunction drawRoad() {\n    \/\/ D\u00e9grad\u00e9 de fond\n    const gradient = ctx.createLinearGradient(0, 0, gameWidth, 0);\n    gradient.addColorStop(0, '#2a4d3a');\n    gradient.addColorStop(0.5, '#1e3a1e');\n    gradient.addColorStop(1, '#2a4d3a');\n    ctx.fillStyle = gradient;\n    ctx.fillRect(0, 0, gameWidth, gameHeight);\n    \n    \/\/ Route avec d\u00e9grad\u00e9\n    const roadGradient = ctx.createLinearGradient(roadX, 0, roadX + roadWidth, 0);\n    roadGradient.addColorStop(0, '#333');\n    roadGradient.addColorStop(0.5, '#666');\n    roadGradient.addColorStop(1, '#333');\n    ctx.fillStyle = roadGradient;\n    ctx.fillRect(roadX, 0, roadWidth, gameHeight);\n    \n    \/\/ Bordures brillantes\n    ctx.fillStyle = '#00ff88';\n    ctx.fillRect(roadX - 3, 0, 3, gameHeight);\n    ctx.fillRect(roadX + roadWidth, 0, 3, gameHeight);\n    \n    \/\/ Ligne centrale anim\u00e9e\n    ctx.fillStyle = '#ffff00';\n    const speed = gameState === 'playing' ? 0.2 * (1 + level * 0.1) : 0;\n    const lineOffset = (Date.now() * speed) % 40;\n    for (let y = -lineOffset; y < gameHeight; y += 40) {\n        ctx.fillRect(roadX + roadWidth\/2 - 2, y, 4, 20);\n    }\n}\n\nfunction drawPlayer() {\n    \/\/ Trail\n    ctx.strokeStyle = '#88aaff';\n    ctx.lineWidth = 3;\n    ctx.beginPath();\n    player.trail.forEach((point, i) => {\n        ctx.globalAlpha = (player.trail.length - i) \/ player.trail.length * 0.5;\n        if (i === 0) ctx.moveTo(point.x, point.y);\n        else ctx.lineTo(point.x, point.y);\n    });\n    ctx.stroke();\n    ctx.globalAlpha = 1;\n    \n    \/\/ Voiture\n    ctx.fillStyle = gameState === 'playing' ? '#ff4444' : '#666';\n    ctx.fillRect(player.x, player.y, player.width, player.height);\n    \n    \/\/ D\u00e9tails avec brillance\n    ctx.fillStyle = gameState === 'playing' ? '#87CEEB' : '#444';\n    ctx.fillRect(player.x + 3, player.y + 5, player.width - 6, 15);\n    \n    \/\/ Roues avec reflets\n    ctx.fillStyle = '#000';\n    ctx.fillRect(player.x - 2, player.y + 10, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + 10, 6, 12);\n    ctx.fillRect(player.x - 2, player.y + player.height - 22, 6, 12);\n    ctx.fillRect(player.x + player.width - 4, player.y + player.height - 22, 6, 12);\n    \n    ctx.fillStyle = '#333';\n    ctx.fillRect(player.x, player.y + 12, 4, 8);\n    ctx.fillRect(player.x + player.width - 4, player.y + 12, 4, 8);\n}\n\nfunction drawObstacles() {\n    obstacles.forEach(obstacle => {\n        ctx.fillStyle = obstacle.color;\n        ctx.fillRect(obstacle.x, obstacle.y, obstacle.width, obstacle.height);\n        \n        \/\/ Reflet\n        ctx.fillStyle = 'rgba(255,255,255,0.3)';\n        ctx.fillRect(obstacle.x + 3, obstacle.y + 5, obstacle.width - 6, 10);\n        \n        \/\/ Roues\n        ctx.fillStyle = '#000';\n        ctx.fillRect(obstacle.x - 2, obstacle.y + 10, 6, 12);\n        ctx.fillRect(obstacle.x + obstacle.width - 4, obstacle.y + 10, 6, 12);\n    });\n}\n\nfunction drawUI() {\n    if (gameState === 'playing') {\n        \/\/ Vitesse visuelle\n        ctx.fillStyle = '#00ff88';\n        ctx.font = 'bold 20px Arial';\n        ctx.textAlign = 'center';\n        ctx.fillText('NIVEAU ' + level, gameWidth\/2, 35);\n        \n        \/\/ Barre de progression niveau\n        const progress = (levelTimer \/ 1800) * 200;\n        ctx.fillStyle = 'rgba(0,255,136,0.3)';\n        ctx.fillRect(gameWidth\/2 - 100, 45, 200, 8);\n        ctx.fillStyle = '#00ff88';\n        ctx.fillRect(gameWidth\/2 - 100, 45, progress, 8);\n        \n    } else {\n        \/\/ Game Over \u00e9labor\u00e9\n        ctx.fillStyle = 'rgba(0,0,0,0.8)';\n        ctx.fillRect(0, 0, gameWidth, gameHeight);\n        \n        ctx.fillStyle = '#ff4444';\n        ctx.font = 'bold 32px Arial';\n        ctx.textAlign = 'center';\n        ctx.fillText('CRASH!', gameWidth\/2, gameHeight\/2 - 80);\n        \n        ctx.fillStyle = '#fff';\n        ctx.font = '18px Arial';\n        ctx.fillText(`Score: ${score}`, gameWidth\/2, gameHeight\/2 - 40);\n        ctx.fillText(`Niveau atteint: ${level}`, gameWidth\/2, gameHeight\/2 - 10);\n        \n        if (score === parseInt(bestScore) && score > 0) {\n            ctx.fillStyle = '#00ff88';\n            ctx.font = 'bold 16px Arial';\n            ctx.fillText('\ud83c\udfc6 NOUVEAU RECORD! \ud83c\udfc6', gameWidth\/2, gameHeight\/2 + 20);\n        }\n        \n        ctx.fillStyle = '#ccc';\n        ctx.font = '14px Arial';\n        ctx.fillText('ESPACE pour recommencer', gameWidth\/2, gameHeight\/2 + 60);\n    }\n}\n\nfunction animate() {\n    updateGame();\n    \n    ctx.clearRect(0, 0, gameWidth, gameHeight);\n    drawRoad();\n    drawObstacles();\n    drawPlayer();\n    drawParticles();\n    drawUI();\n    \n    requestAnimationFrame(animate);\n}\n\n\/\/ D\u00e9marrer le jeu\nanimate();<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-5\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (Game)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h2>R\u00e9capitulatif<\/h2>\n<div class=\"tuto-recap\" style=\"background: #f5f5f5; border-left: 4px solid #9c27b0; padding: 16px 20px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #9c27b0; margin: 0 0 12px 0; font-size: 16px;\">Points essentiels \u00e0 retenir<\/h3>\n<ul style=\"margin: 0; padding-left: 20px; color: #333;\">\n<li><strong>Canvas HTML5<\/strong> : \u00c9l\u00e9ment fondamental pour cr\u00e9er des jeux web avec rendu graphique haute performance<\/li>\n<li><strong>Game Loop<\/strong> : Cycle de mise \u00e0 jour-affichage qui permet l'animation fluide et la logique de jeu<\/li>\n<li><strong>Gestion des \u00e9v\u00e9nements<\/strong> : Syst\u00e8me de contr\u00f4les clavier essential pour l'interactivit\u00e9 joueur<\/li>\n<li><strong>D\u00e9tection de collision<\/strong> : Algorithme AABB pour g\u00e9rer les interactions entre objets du jeu<\/li>\n<li><strong>Progression et effets<\/strong> : Syst\u00e8me de niveaux et particules qui transforment un prototype en jeu engageant<\/li>\n<\/ul>\n<\/div>\n<h2>Sources<\/h2>\n<div class=\"sources-box\" style=\"background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); border: 1px solid #cbd5e1; border-radius: 12px; padding: 16px; margin-bottom: 24px;\">\n<p style=\"color: #64748b; margin: 0 0 12px 0; font-size: 13px;\">Pour approfondir vos connaissances :<\/p>\n<ul style=\"margin: 0; padding-left: 0; list-style: none;\">\n<li style=\"margin-bottom: 8px;\">\n<a href=\"#\" style=\"display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: white; border-radius: 8px; text-decoration: none; color: #1e293b; border: 1px solid #e2e8f0;\"><br \/>\n<span style=\"color: #94a3b8;\">\ud83d\udd17<\/span><br \/>\n<span style=\"flex: 1; font-weight: 500; color: #0f172a;\">MDN Canvas API - Guide complet du d\u00e9veloppement de jeux<\/span><br \/>\n<span style=\"color: #94a3b8;\">\u2192<\/span><br \/>\n<\/a>\n<\/li>\n<li style=\"margin-bottom: 0;\">\n<a href=\"#\" style=\"display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: white; border-radius: 8px; text-decoration: none; color: #1e293b; border: 1px solid #e2e8f0;\"><br \/>\n<span style=\"color: #94a3b8;\">\ud83d\udd17<\/span><br \/>\n<span style=\"flex: 1; font-weight: 500; color: #0f172a;\">JavaScript Game Development Tutorials - Techniques avanc\u00e9es<\/span><br \/>\n<span style=\"color: #94a3b8;\">\u2192<\/span><br \/>\n<\/a>\n<\/li>\n<\/ul>\n<\/div>\n<h2>Validez vos connaissances<\/h2>\n<p>Testez votre compr\u00e9hension avec ce quiz de 10 questions :<\/p>\n<div id=\"quiz-block-1\" class=\"quiz-container\" data-quiz-json=\"https:\/\/lmspro.fr\/wp-content\/plugins\/generate-article-endpoint\/quiz-data\/en\/quiz-sinitier-au-developpement-de-jeux-darcade.json\" aria-label=\"Interactive Quiz\"><div class=\"quiz-loading\" role=\"status\" aria-live=\"polite\"><span class=\"quiz-sr-only\">Loading quiz...<\/span><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introduction to Arcade Game Development: Dive into the exciting world of arcade game development! Learn to create a captivating racing game by mastering the fundamentals of interactive programming. From creating the playing field to collision mechanics, discover how to bring your game ideas to life. Module: Module 6\u2026 <a href=\"https:\/\/lmspro.fr\/en\/sinitier-au-developpement-de-jeux-darcade\/\" class=\"more-link\">Read More<span class=\"screen-reader-text\"> \u00ab\u00a0S&rsquo;initier au d\u00e9veloppement de Jeux d&rsquo;Arcade\u00a0\u00bb<\/span> &raquo;<\/a><\/p>","protected":false},"author":1,"featured_media":342,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[183],"tags":[185,5,2],"class_list":["post-595","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-module-bonus","tag-bonus","tag-design","tag-ux"],"_links":{"self":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/595","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/comments?post=595"}],"version-history":[{"count":1,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/595\/revisions"}],"predecessor-version":[{"id":609,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/595\/revisions\/609"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/media\/342"}],"wp:attachment":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/media?parent=595"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/categories?post=595"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/tags?post=595"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}