Skip to content

🎯 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

  1. Concepts Fondamentaux
  2. Votre Premier Jeu
  3. Mécaniques de Base
  4. Patterns de Gameplay
  5. Architecture de Jeux
  6. Optimisation et Polish
  7. 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 ! 🚀