🎯 Guide de Création de Jeux - KodLab
Ce guide vous accompagne étape par étape dans la création de jeux avec KodLab, du concept le plus simple aux mécaniques avancées.
📋 Table des Matières
- Concepts Fondamentaux
- Votre Premier Jeu
- Mécaniques de Base
- Patterns de Gameplay
- Architecture de Jeux
- Optimisation et Polish
- Projets Guidés
Concepts Fondamentaux
La Boucle de Jeu
Tous les jeux KodLab suivent le même pattern :
function start()
// INITIALISATION (une seule fois)
// - Charger les ressources
// - Définir les positions initiales
// - Configurer les paramètres
end
function update()
// BOUCLE PRINCIPALE (60 fois/seconde)
// 1. Effacer l'écran
// 2. Traiter les entrées
// 3. Mettre à jour la logique
// 4. Détecter les collisions
// 5. Afficher les éléments
// 6. Afficher l'interface
end
Système de Coordonnées
(0,0) ──────────────── (400,0)
│ │
│ Canvas 400x300 │
│ │
│ │
(0,300) ──────────────── (400,300)
- Origine : (0,0) en haut à gauche
- X : augmente vers la droite
- Y : augmente vers le bas
- Limites : 0-400 en X, 0-300 en Y
Votre Premier Jeu
Étape 1 : Point qui Bouge
let x = 200
let y = 150
function start()
clearScreen("#000033")
end
function update()
clearScreen("#000033")
// Mouvement automatique
x = x + 2
if x > 400
x = 0
end
// Affichage
drawCircle(x, y, 10, "#FF6600")
end
Étape 2 : Contrôle Joueur
let playerX = 200
let playerY = 150
let speed = 3
function start()
clearScreen("#000033")
end
function update()
clearScreen("#000033")
// Contrôles
if isKeyPressed("left")
playerX = playerX - speed
end
if isKeyPressed("right")
playerX = playerX + speed
end
if isKeyPressed("up")
playerY = playerY - speed
end
if isKeyPressed("down")
playerY = playerY + speed
end
// Limites d'écran
if playerX < 10
playerX = 10
end
if playerX > 390
playerX = 390
end
if playerY < 10
playerY = 10
end
if playerY > 290
playerY = 290
end
// Affichage
drawCircle(playerX, playerY, 10, "#00FF00")
end
Étape 3 : Ajouter un Objectif
let playerX = 200
let playerY = 150
let speed = 3
let coinX = 100
let coinY = 100
let score = 0
function start()
clearScreen("#000033")
placeCoin()
end
function update()
clearScreen("#000033")
// Mouvement joueur
movePlayer()
// Vérifier collision avec pièce
let distance = ((playerX - coinX) * (playerX - coinX)) + ((playerY - coinY) * (playerY - coinY))
if distance < 400 // 20 pixels de distance
score = score + 10
placeCoin()
end
// Affichage
drawCircle(playerX, playerY, 10, "#00FF00") // Joueur
drawCircle(coinX, coinY, 8, "#FFFF00") // Pièce
drawText("Score: " + score, 10, 20, "#FFFFFF")
end
function movePlayer()
if isKeyPressed("left")
playerX = playerX - speed
end
if isKeyPressed("right")
playerX = playerX + speed
end
if isKeyPressed("up")
playerY = playerY - speed
end
if isKeyPressed("down")
playerY = playerY + speed
end
// Contraindre aux limites
if playerX < 10
playerX = 10
end
if playerX > 390
playerX = 390
end
if playerY < 10
playerY = 10
end
if playerY > 290
playerY = 290
end
end
function placeCoin()
coinX = 20 + ((score * 7) % 360) // Position pseudo-aléatoire
coinY = 20 + ((score * 11) % 260)
end
Mécaniques de Base
1. Physique Simple
Gravité et Saut
let playerX = 200
let playerY = 250
let velocityY = 0
let onGround = true
let gravity = 0.5
let jumpPower = -12
function update()
clearScreen("#000033")
// Contrôles horizontaux
if isKeyPressed("left")
playerX = playerX - 4
end
if isKeyPressed("right")
playerX = playerX + 4
end
// Saut (seulement si au sol)
if isKeyPressed("up") && onGround
velocityY = jumpPower
onGround = false
end
// Appliquer la gravité
if !onGround
velocityY = velocityY + gravity
playerY = playerY + velocityY
// Collision avec le sol
if playerY >= 250
playerY = 250
velocityY = 0
onGround = true
end
end
// Affichage
drawRect(playerX - 10, playerY - 20, 20, 20, "#00FF00")
drawRect(0, 270, 400, 30, "#654321") // Sol
end
Rebonds et Friction
let ballX = 200
let ballY = 100
let velocityX = 5
let velocityY = 3
let friction = 0.99
let bounce = 0.8
function update()
clearScreen("#001122")
// Mouvement
ballX = ballX + velocityX
ballY = ballY + velocityY
// Rebonds sur les bords
if ballX <= 10 || ballX >= 390
velocityX = velocityX * -bounce
ballX = ballX <= 10 ? 10 : 390
end
if ballY <= 10 || ballY >= 290
velocityY = velocityY * -bounce
ballY = ballY <= 10 ? 10 : 290
end
// Friction
velocityX = velocityX * friction
velocityY = velocityY * friction
// Affichage
drawCircle(ballX, ballY, 10, "#FF6600")
end
2. Détection de Collisions
Collision Rectangle-Rectangle
function checkRectCollision(x1, y1, w1, h1, x2, y2, w2, h2)
if (x1 < x2 + w2) && (x1 + w1 > x2) && (y1 < y2 + h2) && (y1 + h1 > y2)
// Collision détectée
return true
end
return false
end
// Utilisation
let playerCollided = checkRectCollision(playerX, playerY, 20, 20, enemyX, enemyY, 30, 30)
Collision Cercle-Cercle
function checkCircleCollision(x1, y1, r1, x2, y2, r2)
let dx = x1 - x2
let dy = y1 - y2
let distance = (dx * dx) + (dy * dy)
let radiusSum = (r1 + r2) * (r1 + r2)
if distance < radiusSum
return true
end
return false
end
3. Gestion des États
Machine d'États Simple
let gameState = "menu" // "menu", "playing", "paused", "gameover"
function update()
if gameState == "menu"
handleMenu()
else if gameState == "playing"
handleGameplay()
else if gameState == "paused"
handlePause()
else if gameState == "gameover"
handleGameOver()
end
end
function handleMenu()
clearScreen("#000033")
drawText("PRESS SPACE TO START", 120, 150, "#FFFFFF")
if isKeyPressed("space")
gameState = "playing"
initializeGame()
end
end
function handleGameplay()
updatePlayer()
updateEnemies()
checkCollisions()
drawGame()
if isKeyPressed("space")
gameState = "paused"
end
end
function handlePause()
drawText("PAUSED - SPACE TO CONTINUE", 100, 150, "#FFFF00")
if isKeyPressed("space")
gameState = "playing"
end
end
Patterns de Gameplay
1. Système de Vies et Santé
let playerHealth = 100
let maxHealth = 100
let lives = 3
let invulnerable = false
let invulnerabilityTime = 0
function takeDamage(damage)
if !invulnerable
playerHealth = playerHealth - damage
invulnerable = true
invulnerabilityTime = 60 // 1 seconde d'invulnérabilité
if playerHealth <= 0
loseLife()
end
end
end
function loseLife()
lives = lives - 1
playerHealth = maxHealth
if lives <= 0
gameState = "gameover"
else
respawnPlayer()
end
end
function updateInvulnerability()
if invulnerable
invulnerabilityTime = invulnerabilityTime - 1
if invulnerabilityTime <= 0
invulnerable = false
end
end
end
function drawHealthBar()
// Barre de fond
drawRect(10, 10, 100, 10, "#660000")
// Barre de santé
let healthWidth = (playerHealth * 100) / maxHealth
drawRect(10, 10, healthWidth, 10, "#00FF00")
// Contour
drawLine(10, 10, 110, 10, "#FFFFFF")
drawLine(10, 20, 110, 20, "#FFFFFF")
drawLine(10, 10, 10, 20, "#FFFFFF")
drawLine(110, 10, 110, 20, "#FFFFFF")
end
2. Système de Score et Niveaux
let score = 0
let level = 1
let levelScore = 0
let scoreForNextLevel = 1000
function addScore(points)
score = score + points
levelScore = levelScore + points
// Vérifier passage au niveau suivant
if levelScore >= scoreForNextLevel
levelUp()
end
end
function levelUp()
level = level + 1
levelScore = 0
scoreForNextLevel = scoreForNextLevel + (level * 500)
// Augmenter la difficulté
enemySpeed = enemySpeed + 0.5
enemySpawnRate = enemySpawnRate - 2
drawLevelUpMessage()
end
function drawLevelUpMessage()
drawText("LEVEL UP!", 150, 150, "#FFFF00")
drawText("Level " + level, 170, 170, "#FFFFFF")
end
3. Système de Power-ups
let hasShield = false
let shieldTime = 0
let hasRapidFire = false
let rapidFireTime = 0
let hasBigBullets = false
let bigBulletsTime = 0
function collectPowerup(type)
if type == "shield"
hasShield = true
shieldTime = 600 // 10 secondes
else if type == "rapidfire"
hasRapidFire = true
rapidFireTime = 300 // 5 secondes
else if type == "bigbullets"
hasBigBullets = true
bigBulletsTime = 450 // 7.5 secondes
end
end
function updatePowerups()
// Bouclier
if hasShield
shieldTime = shieldTime - 1
if shieldTime <= 0
hasShield = false
end
end
// Tir rapide
if hasRapidFire
rapidFireTime = rapidFireTime - 1
if rapidFireTime <= 0
hasRapidFire = false
end
end
// Grosses balles
if hasBigBullets
bigBulletsTime = bigBulletsTime - 1
if bigBulletsTime <= 0
hasBigBullets = false
end
end
end
function drawPowerupEffects()
// Bouclier visuel
if hasShield
drawCircle(playerX, playerY, 25, "#0066FF")
end
// Indicateurs de temps restant
if hasRapidFire
drawText("Rapid: " + (rapidFireTime / 60), 10, 40, "#FF6600")
end
if hasBigBullets
drawText("Big: " + (bigBulletsTime / 60), 10, 60, "#FF00FF")
end
end
Architecture de Jeux
Structure Modulaire
// === VARIABLES GLOBALES ===
let gameState = "menu"
let score = 0
let level = 1
// Variables joueur
let playerX = 200
let playerY = 250
let playerHealth = 100
// Variables ennemis
let enemyCount = 0
let maxEnemies = 5
// Variables interface
let showFPS = false
let frameCounter = 0
// === FONCTION PRINCIPALE ===
function start()
initializeGame()
end
function update()
frameCounter = frameCounter + 1
if gameState == "menu"
updateMenu()
else if gameState == "playing"
updateGameplay()
else if gameState == "gameover"
updateGameOver()
end
if showFPS
drawFPS()
end
end
// === GESTION DES ÉTATS ===
function updateMenu()
clearScreen("#000033")
drawMenu()
handleMenuInput()
end
function updateGameplay()
clearScreen("#001122")
handleInput()
updatePlayer()
updateEnemies()
updateBullets()
updatePowerups()
checkCollisions()
drawBackground()
drawPlayer()
drawEnemies()
drawBullets()
drawUI()
end
function updateGameOver()
clearScreen("#330000")
drawGameOver()
handleGameOverInput()
end
// === GESTION DU JOUEUR ===
function updatePlayer()
handlePlayerMovement()
handlePlayerShooting()
updatePlayerAnimation()
checkPlayerBounds()
end
function handlePlayerMovement()
if isKeyPressed("left")
playerX = playerX - 4
end
if isKeyPressed("right")
playerX = playerX + 4
end
end
// === GESTION DES ENNEMIS ===
function updateEnemies()
spawnEnemies()
moveEnemies()
removeDeadEnemies()
end
// === RENDU ===
function drawGame()
drawBackground()
drawPlayer()
drawEnemies()
drawBullets()
drawEffects()
drawUI()
end
function drawUI()
drawText("Score: " + score, 10, 20, "#FFFFFF")
drawText("Level: " + level, 10, 40, "#FFFFFF")
drawText("Health: " + playerHealth, 10, 60, "#FFFFFF")
end
Gestion d'Objets Multiples
Comme Kod ne supporte pas les tableaux complexes, voici une approche alternative :
// Gestion de plusieurs ennemis avec variables individuelles
let enemy1X = 0
let enemy1Y = 0
let enemy1Active = false
let enemy2X = 0
let enemy2Y = 0
let enemy2Active = false
let enemy3X = 0
let enemy3Y = 0
let enemy3Active = false
function createEnemy(slot, x, y)
if slot == 1
enemy1X = x
enemy1Y = y
enemy1Active = true
else if slot == 2
enemy2X = x
enemy2Y = y
enemy2Active = true
else if slot == 3
enemy3X = x
enemy3Y = y
enemy3Active = true
end
end
function updateAllEnemies()
if enemy1Active
updateEnemy(1)
end
if enemy2Active
updateEnemy(2)
end
if enemy3Active
updateEnemy(3)
end
end
function updateEnemy(slot)
if slot == 1
enemy1Y = enemy1Y + 2
if enemy1Y > 300
enemy1Active = false
end
else if slot == 2
enemy2Y = enemy2Y + 2
if enemy2Y > 300
enemy2Active = false
end
else if slot == 3
enemy3Y = enemy3Y + 2
if enemy3Y > 300
enemy3Active = false
end
end
end
function drawAllEnemies()
if enemy1Active
drawRect(enemy1X, enemy1Y, 20, 20, "#FF0000")
end
if enemy2Active
drawRect(enemy2X, enemy2Y, 20, 20, "#FF0000")
end
if enemy3Active
drawRect(enemy3X, enemy3Y, 20, 20, "#FF0000")
end
end
Optimisation et Polish
1. Performance
Limiter les Calculs
// ✅ Calculer une fois par frame
let frameCount = 0
let enemySpawnCounter = 0
function update()
frameCount = frameCount + 1
enemySpawnCounter = enemySpawnCounter + 1
// Spawn ennemi toutes les 60 frames (1 seconde)
if enemySpawnCounter >= 60
spawnEnemy()
enemySpawnCounter = 0
end
end
// ❌ Calcul répétitif évité
// if frameCount % 60 == 0 // Calcul modulo chaque frame
Optimiser l'Affichage
function optimizedRender()
// Effacer une seule fois
clearScreen("#001122")
// Dessiner les éléments par couches
drawBackground() // Arrière-plan
drawGameObjects() // Objets de jeu
drawEffects() // Effets visuels
drawUI() // Interface utilisateur
end
2. Effets Visuels
Clignotement
let blinkCounter = 0
function drawBlinkingText()
blinkCounter = blinkCounter + 1
if (blinkCounter / 30) % 2 < 1 // Change toutes les 30 frames
drawText("PRESS SPACE", 150, 150, "#FFFFFF")
end
end
Animation Simple
let animationFrame = 0
function updateAnimation()
animationFrame = animationFrame + 1
if animationFrame > 120
animationFrame = 0
end
end
function drawAnimatedPlayer()
let offset = 0
if (animationFrame / 10) % 4 < 2 // Balancement
offset = 2
else
offset = -2
end
drawRect(playerX + offset, playerY, 20, 20, "#00FF00")
end
3. Feedback Utilisateur
Shake Screen (Tremblement)
let screenShake = 0
function addScreenShake(intensity)
screenShake = intensity
end
function updateScreenShake()
if screenShake > 0
screenShake = screenShake - 1
end
end
function drawWithShake(x, y, color)
let shakeX = 0
let shakeY = 0
if screenShake > 0
shakeX = (screenShake % 4) - 2 // Tremblement aléatoire
shakeY = ((screenShake * 3) % 4) - 2
end
drawCircle(x + shakeX, y + shakeY, 10, color)
end
Particules Simples
let particles = []
let particleCount = 0
function createParticles(x, y)
// Créer 5 particules simples
for i = 1 to 5
if particleCount < 10 // Maximum 10 particules
particleCount = particleCount + 1
// Utiliser variables globales pour chaque particule
// particleX[i], particleY[i], particleLife[i]
end
end
end
function updateParticles()
// Mettre à jour toutes les particules actives
// Décrémenter leur durée de vie
// Les supprimer quand expired
end
function drawParticles()
// Dessiner toutes les particules actives
for i = 1 to particleCount
// Dessiner chaque particule avec fade-out
end
end
Projets Guidés
Projet 1 : Casse-Briques Simplifié
// Variables de jeu
let ballX = 200
let ballY = 250
let ballSpeedX = 3
let ballSpeedY = -3
let paddleX = 160
let paddleWidth = 80
let paddleSpeed = 6
let bricks = []
let brickRows = 5
let brickCols = 8
let bricksRemaining = 40
let score = 0
let lives = 3
function start()
initializeBricks()
end
function update()
clearScreen("#000033")
handleInput()
updateBall()
checkCollisions()
drawPaddle()
drawBall()
drawBricks()
drawUI()
end
function handleInput()
if isKeyPressed("left") && paddleX > 0
paddleX = paddleX - paddleSpeed
end
if isKeyPressed("right") && paddleX < 320
paddleX = paddleX + paddleSpeed
end
end
function updateBall()
ballX = ballX + ballSpeedX
ballY = ballY + ballSpeedY
// Rebonds sur les murs
if ballX <= 5 || ballX >= 395
ballSpeedX = ballSpeedX * -1
end
if ballY <= 5
ballSpeedY = ballSpeedY * -1
end
// Collision avec raquette
if ballY >= 240 && ballY <= 250 && ballX >= paddleX && ballX <= paddleX + paddleWidth
ballSpeedY = ballSpeedY * -1
ballY = 240 // Éviter que la balle reste collée
end
// Balle perdue
if ballY > 300
lives = lives - 1
if lives > 0
resetBall()
else
// Game Over
end
end
end
function resetBall()
ballX = 200
ballY = 250
ballSpeedY = -3
end
function initializeBricks()
// Initialiser l'état des briques (toutes présentes)
bricksRemaining = 40
end
function drawBricks()
for row = 0 to 4
for col = 0 to 7
let brickX = col * 50
let brickY = row * 20 + 50
// Simuler l'état de la brique (simplifié)
let brickIndex = row * 8 + col
if brickIndex < bricksRemaining
drawRect(brickX, brickY, 45, 15, "#FF6600")
end
end
end
end
function drawPaddle()
drawRect(paddleX, 250, paddleWidth, 10, "#FFFFFF")
end
function drawBall()
drawCircle(ballX, ballY, 5, "#FFFF00")
end
function drawUI()
drawText("Score: " + score, 10, 20, "#FFFFFF")
drawText("Lives: " + lives, 300, 20, "#FFFFFF")
end
Projet 2 : Space Shooter
// Variables joueur
let playerX = 200
let playerY = 250
let playerSpeed = 5
// Variables tir
let bulletX = 0
let bulletY = 0
let bulletActive = false
let bulletSpeed = 8
let canShoot = true
let shootCooldown = 0
// Variables ennemis
let enemy1X = 50
let enemy1Y = 50
let enemy1Active = true
let enemy2X = 150
let enemy2Y = 80
let enemy2Active = true
let enemy3X = 250
let enemy3Y = 60
let enemy3Active = true
let enemySpeed = 1
let enemyDirection = 1
// Variables de jeu
let score = 0
let gameOver = false
function start()
clearScreen("#000011")
end
function update()
if !gameOver
clearScreen("#000011")
handleInput()
updatePlayer()
updateBullet()
updateEnemies()
checkCollisions()
drawStars()
drawPlayer()
drawBullet()
drawEnemies()
drawUI()
else
handleGameOver()
end
end
function handleInput()
if isKeyPressed("left") && playerX > 20
playerX = playerX - playerSpeed
end
if isKeyPressed("right") && playerX < 380
playerX = playerX + playerSpeed
end
if isKeyPressed("space") && canShoot && !bulletActive
shoot()
end
end
function shoot()
bulletX = playerX
bulletY = playerY - 10
bulletActive = true
canShoot = false
shootCooldown = 15 // Délai entre les tirs
end
function updatePlayer()
// Gestion du cooldown de tir
if shootCooldown > 0
shootCooldown = shootCooldown - 1
end
if shootCooldown <= 0
canShoot = true
end
end
function updateBullet()
if bulletActive
bulletY = bulletY - bulletSpeed
if bulletY < 0
bulletActive = false
end
end
end
function updateEnemies()
// Mouvement en formation
if enemy1Active
enemy1X = enemy1X + (enemyDirection * enemySpeed)
end
if enemy2Active
enemy2X = enemy2X + (enemyDirection * enemySpeed)
end
if enemy3Active
enemy3X = enemy3X + (enemyDirection * enemySpeed)
end
// Changement de direction
if enemy1X >= 350 || enemy2X >= 350 || enemy3X >= 350 || enemy1X <= 50 || enemy2X <= 50 || enemy3X <= 50
enemyDirection = enemyDirection * -1
if enemy1Active
enemy1Y = enemy1Y + 20
end
if enemy2Active
enemy2Y = enemy2Y + 20
end
if enemy3Active
enemy3Y = enemy3Y + 20
end
end
// Vérifier si les ennemis atteignent le joueur
if (enemy1Active && enemy1Y > 220) || (enemy2Active && enemy2Y > 220) || (enemy3Active && enemy3Y > 220)
gameOver = true
end
end
function checkCollisions()
if bulletActive
// Collision avec ennemi 1
if enemy1Active && bulletX > enemy1X - 15 && bulletX < enemy1X + 15 && bulletY > enemy1Y - 10 && bulletY < enemy1Y + 10
enemy1Active = false
bulletActive = false
score = score + 100
end
// Collision avec ennemi 2
if enemy2Active && bulletX > enemy2X - 15 && bulletX < enemy2X + 15 && bulletY > enemy2Y - 10 && bulletY < enemy2Y + 10
enemy2Active = false
bulletActive = false
score = score + 100
end
// Collision avec ennemi 3
if enemy3Active && bulletX > enemy3X - 15 && bulletX < enemy3X + 15 && bulletY > enemy3Y - 10 && bulletY < enemy3Y + 10
enemy3Active = false
bulletActive = false
score = score + 100
end
end
// Vérifier victoire
if !enemy1Active && !enemy2Active && !enemy3Active
drawText("VICTORY!", 150, 150, "#00FF00")
end
end
function drawStars()
// Étoiles fixes simples
drawPixel(50, 30, "#FFFFFF")
drawPixel(150, 80, "#FFFFFF")
drawPixel(250, 45, "#FFFFFF")
drawPixel(350, 90, "#FFFFFF")
drawPixel(80, 120, "#FFFFFF")
drawPixel(300, 160, "#FFFFFF")
end
function drawPlayer()
// Vaisseau triangulaire
drawRect(playerX - 2, playerY + 5, 4, 15, "#00FF00")
drawRect(playerX - 8, playerY + 10, 16, 8, "#00FF00")
end
function drawBullet()
if bulletActive
drawRect(bulletX - 1, bulletY, 2, 8, "#FFFF00")
end
end
function drawEnemies()
if enemy1Active
drawRect(enemy1X - 10, enemy1Y - 5, 20, 10, "#FF0000")
end
if enemy2Active
drawRect(enemy2X - 10, enemy2Y - 5, 20, 10, "#FF0000")
end
if enemy3Active
drawRect(enemy3X - 10, enemy3Y - 5, 20, 10, "#FF0000")
end
end
function drawUI()
drawText("Score: " + score, 10, 20, "#FFFFFF")
if !canShoot
drawText("Reloading...", 300, 280, "#FFFF00")
end
end
function handleGameOver()
clearScreen("#330000")
drawText("GAME OVER", 140, 120, "#FF0000")
drawText("Score: " + score, 160, 140, "#FFFFFF")
drawText("Press SPACE to restart", 110, 180, "#FFFF00")
if isKeyPressed("space")
restartGame()
end
end
function restartGame()
// Reset toutes les variables
playerX = 200
enemy1X = 50
enemy1Y = 50
enemy1Active = true
enemy2X = 150
enemy2Y = 80
enemy2Active = true
enemy3X = 250
enemy3Y = 60
enemy3Active = true
score = 0
gameOver = false
bulletActive = false
end
🎯 Conseils de Game Design
1. Commencez Simple
- Une mécanique à la fois
- Prototype rapide avant de polir
- Testez fréquemment vos idées
2. Progression du Joueur
- Courbe d'apprentissage douce
- Défis croissants mais justes
- Feedback immédiat sur les actions
3. Rétention d'Attention
- Objectifs clairs : que doit faire le joueur ?
- Récompenses régulières : points, power-ups, niveaux
- Variété : éviter la répétition monotone
4. Polish et Finition
- Sons : même simples, ils ajoutent beaucoup
- Animations : fluidité et vie
- Interface : claire et informative
- Equilibrage : ni trop facile, ni trop dur
Prêt à créer vos propres jeux ? Explorez les Exemples Complets pour plus d'inspiration ! 🚀