Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU01

Mes premiers pas de la programmation Lua avec Roblox

Objectif : Découvrir pas à pas les bases de la programmation Lua avec Roblox :

  • Les variables (texte et nombres)
  • Les propriétés d’objets (écran, texte, Part)
  • Les boucles (for et while)
  • Les tableaux (simples et doubles)
  • Le clonage et la destruction d’objets

Le fil du jeu : tu possèdes un écran géant (TableauPart) qui affiche des messages, et un cube magique (Part) qui va grandir, changer de couleur, devenir invisible… et même se multiplier en pyramide inversée !

Règle du jeu : à chaque étape, essaye d’écrire le code, teste, contrôle ce qui est affiché, puis réponds au QCM avant de passer à la suite !

Étape 0 : Préparer le terrain dans Roblox Studio

Avant de coder, construis la scène :

  1. Dans Workspace, crée un dossier nommé Folder.
  2. Dans ce dossier :
    • Une Part nommée TableauPart : aplatie comme un écran (ex: Size = Vector3.new(12, 8, 0.5)), avec Anchored = true.
    • Une Part nommée Part : un cube visible (Size = Vector3.new(4, 4, 4)), avec Anchored = true.
  3. Sur TableauPart, ajoute (clic droit → Insert Object) :
    • Un SurfaceGui (nomme-le SurfaceGui).
    • Dans le SurfaceGui, un TextBox (nomme-le TextBox) : étire-le sur tout l’écran avec Size = {1,0},{1,0}.
  4. Crée un Script dans ServerScriptService : c’est là que tu colleras le code, étape par étape.

En haut du script, ces lignes (elles ne changent plus jamais) :

-- Récupérer les objets de la scène
local folder = workspace:WaitForChild("Folder")
local tableauPart = folder:WaitForChild("TableauPart")
local surfaceGui = tableauPart:WaitForChild("SurfaceGui")
local screen = surfaceGui:WaitForChild("TextBox")  -- notre écran d'affichage
local part = folder:WaitForChild("Part")           -- notre cube magique

Convention : comme dans tous nos tutoriels, les noms de variables sont en anglais (screen, firstName…) et les commentaires en français.

Étape 1 : Afficher un message (les propriétés d’un objet)

But : écrire « Bonjour » sur l’écran géant.

Explication : un objet Roblox (comme notre TextBox) possède des propriétés : sa couleur, sa taille… et son texte (Text). Pour changer une propriété, on écrit objet.propriete = valeur.

-- ÉTAPE 1 : Affiche un Bonjour à l'écran
screen.Text = "Bonjour"

Teste ! Lance le jeu.
Contrôle : tu dois voir « Bonjour » s’afficher sur l’écran géant. Sinon, vérifie que ton TextBox s’appelle bien TextBox et que le script pointe vers le bon objet.

QCM :

  1. Comment change-t-on le texte affiché dans le TextBox ?
    • a) screen.Bonjour = Text
    • b) print("Bonjour")
    • c) screen.Text = "Bonjour"
  2. Text est… ?
    • a) Une propriété du TextBox.
    • b) Une boucle.
    • c) Un joueur.

Étape 2 : Les variables texte et la concaténation

But : afficher « Bonjour patrick ! » (avec ton prénom !).

Explication : une variable, c’est une boîte avec une étiquette qui contient une valeur. Pour assembler des morceaux de texte, on utilise .. (deux points) : c’est la concaténation.

-- ÉTAPE 2 : Renseigne une variable pour afficher ton prénom
task.wait(2)                       -- petite pause de 2 secondes
local firstName = "patrick"        -- remplace par TON prénom !
screen.Text = "Bonjour " .. firstName .. " !"

Teste ! Contrôle : l’écran affiche d’abord « Bonjour » (2 secondes), puis « Bonjour tonprénom ! ». Attention : il y a un espace dans "Bonjour "; essaie sans espace pour voir la différence !

QCM :

  1. Que fait "Bonjour " .. firstName ?
    • a) Il colle les deux textes bout à bout (concaténation).
    • b) Il les additionne comme des nombres.
    • c) Il supprime le premier texte.
  2. Que fait task.wait(2) ?
    • a) Il supprime 2 objets.
    • b) Il met le script en pause pendant 2 secondes.
    • c) Il écrit 2 fois le texte.

Étape 3 : Modifier les propriétés de l’écran et du texte

But : rendre l’écran coloré et le texte stylé.

Explication : on peut modifier plein de propriétés d’un objet : couleur de fond (BackgroundColor3), couleur du texte (TextColor3), bordure, taille du texte… Color3.fromRGB(rouge, vert, bleu) fabrique une couleur avec 3 nombres de 0 à 255.

-- ÉTAPE 3 : Modifie les propriétés de l'écran et du texte
screen.BackgroundColor3 = Color3.fromRGB(85, 255, 255)   -- fond cyan
sreen.TextColor3 = Color3.fromRGB(50, 50, 100)           -- gris bleu
screen.BorderMode = Enum.BorderMode.Inset               -- style de bordure
screen.BorderColor3 = Color3.fromRGB(255, 0, 0)         -- bordure rouge
screen.BorderSizePixel = 20                              -- épaisseur de la bordure
screen.TextScaled = true                                 -- texte agrandi automatiquement
screen.TextWrapped = true                               -- texte qui passe à la ligne
screen.TextXAlignment = Enum.TextXAlignment.Center      -- texte centré

Teste ! Contrôle : fond cyan, texte jaune, bordure rouge épaisse, texte centré et plus grand. Amuse-toi : change les 3 nombres de fromRGB et observe ! Que donne Color3.fromRGB(255, 0, 0) ? Et Color3.fromRGB(0, 0, 255) ?

QCM :

  1. Que représente les 3 nombres de Color3.fromRGB(...) ?
    • a) Les quantités de rouge, de vert et de bleu (de 0 à 255).
    • b) La taille de l’écran.
    • c) L’heure.
  2. Que fait screen.TextScaled = true ?
    • a) L’écran disparaît.
    • b) Le texte s’agrandit automatiquement pour remplir l’espace.
    • c) Le texte devient bleu.

Étape 4 : Les variables nombre

But : afficher ton âge à l’écran.

Explication : une variable peut contenir du texte ("patrick") ou un nombre (12). Attention au piège : pour coller un nombre à du texte, on utilise quand même .. !

-- ÉTAPE 4 : Renseigne ton âge dans une variable et affiche-le
task.wait(2)
local age = 12                          -- remplace par TON âge !
screen.Text = screen.Text .. "\nJ'ai " .. age .. " ans"

Nouveauté : \n = un saut de ligne dans le texte (le message s’écrit en dessous du précédent).

Teste ! Contrôle : le message « J’ai X ans » apparaît en dessous du message précédent. Si tout s’affiche sur une seule ligne, vérifie ton \n.

QCM :

  1. Que fait "\n" dans un texte ?
    • a) Il affiche un « n ».
    • b) Il efface le texte.
    • c) Il saute à la ligne suivante.
      Réponse : a)
  2. Peut-on coller un nombre à du texte avec .. ?
    • a) Oui, .. " ans" fonctionne avec une variable nombre.
    • b) Non, jamais.
    • c) Seulement le lundi.

Étape 5 : À toi de jouer — une variable de ton choix

But : afficher une information de ton choix (ex: « Fille » ou « Garçon », ou ta classe).

Explication : c’est le même principe qu’avant. À toi d’écrire le code sans copier ! Indice : crée une variable texte, puis concatène-la avec \n à la suite.

-- ÉTAPE 5 : Renseigne une information et affiche-la
task.wait(2)
local gender = "Garçon"                -- ou "Fille"... ou invente ta variable !
screen.Text = screen.Text .. "\n" .. gender

Teste ! Contrôle : ta nouvelle ligne s’affiche sous les précédentes, sans effacer le reste.

QCM :

  1. Que se passe-t-il si tu écris screen.Text = gender (sans concaténation) ?
    • a) Tout le texte précédent est remplacé par ta variable.
    • b) Ta variable s’ajoute à la fin.
    • c) Rien ne s’affiche.

Étape 6 : Les nombres et l’addition (ton inventaire)

But : imagine que tu récupères une épée, un laser et une lampe, et calcule le total des points de ton inventaire.

Explication : avec des variables nombre, on peut calculer : +, -, * (multiplié), / (divisé).

-- ÉTAPE 6 : Calcule le total des points de l'inventaire
task.wait(2)
local sword = 10        -- points de l'épée
local laser = 50        -- points du laser
local lamp = 2          -- points de la lampe
local total = sword + laser + lamp   -- le calcul !
screen.Text = screen.Text .. "\nTotal inventaire : " .. total

Teste ! Contrôle : l’écran affiche « Total inventaire : 62 ». Vérifie le calcul de tête : 10 + 50 + 2 = 62 ?

QCM :

  1. Que vaut total si sword = 10, laser = 50, lamp = 2 ?
    • a) 62
    • b) 10502
    • c) 60
  2. Que fait local total = sword + laser + lamp ?
    • a) Il colle les trois textes.
    • b) Il additionne les trois variables et range le résultat dans total.
    • c) Il supprime les variables.

Étape 7 : Un vrai calcul (le voyage en vaisseau)

But : ton vaisseau part avec un réservoir vide, tu achètes 100 litres, puis tu visites 3 villes qui consomment chacune 30 litres. Combien reste-t-il ?

Explication : on peut combiner plusieurs opérations, et même réutiliser une variable avec =. Les parenthèses ( ) forcent le calcul à se faire en priorité.

-- ÉTAPE 7 : Calcule le carburant restant
task.wait(2)
local fuelTank = 0                          -- réservoir vide au départ
local fuelBought = 100                      -- litres achetés
local trips = 3                             -- nombre de déplacements
local fuelPerTrip = 30                      -- litres consommés par déplacement

fuelTank = fuelTank + fuelBought - (trips * fuelPerTrip)   -- le calcul !

screen.Text = screen.Text .. "\nReste dans mon réservoir : " .. fuelTank

Teste ! Contrôle : l’écran affiche 10 (100 – 90 = 10). Enlève les parenthèses autour de trips * fuelPerTrip : le résultat est-il le même ? Pourquoi ? (Indice : sans parenthèses, le calcul se fait de gauche à droite !)

QCM :

  1. Pourquoi met-on des parenthèses autour de trips * fuelPerTrip ?
    • a) Pour que la multiplication se fasse avant la soustraction.
    • b) Pour décorer le code.
    • c) Pour afficher le texte.

Étape 8 : La boucle for (compteur et décompte)

But : afficher un compteur de 1 à 10, puis un décompte de 10 à 1.

Explication : une boucle for répète un bloc de code. for i = 1, 10 do signifie : « pour i allant de 1 à 10 ». La variable i change à chaque tour ! Et for i = 10, 1, -1 compte à l’envers grâce au pas de -1.

-- ÉTAPE 8a : Compteur de 1 à 10
task.wait(2)
local baseText = screen.Text .. "\n"
for i = 1, 10 do
    screen.Text = baseText .. "Attente : " .. i .. " seconde(s)"
    task.wait(0.3)
end

-- ÉTAPE 8b : Décompte de 10 à 1
for i = 10, 1, -1 do                       -- pas de -1 : on compte à l'envers !
    screen.Text = baseText .. "Attente : " .. i .. " seconde(s)"
    task.wait(0.3)
end

Teste ! Contrôle : le chiffre affiché monte 1, 2, 3… 10 puis redescend 10, 9… 1. Remarque : on a préparé baseText avant la boucle pour ne pas coller 10 fois la phrase !

QCM :

  1. Combien de fois le code dans for i = 1, 10 do s’exécute-t-il ?
    • a) 10 fois.
    • b) 1 fois.
    • c) 11 fois.
  2. Que fait le -1 dans for i = 10, 1, -1 do ?
    • a) Il fait diminuer i de 1 à chaque tour (décompte).
    • b) Il répète la boucle à l’infini.
    • c) Il affiche -1 à l’écran.

Étape 9 : Les tableaux (ton inventaire en liste)

But : ranger les valeurs de l’inventaire dans un tableau et les afficher une par une.

Explication : un tableau ({ }) range plusieurs valeurs dans une seule variable. pairs parcourt le tableau et donne l’index (i, la position) et la valeur (item).

-- ÉTAPE 9 : Affiche l'inventaire avec une boucle
task.wait(2)
screen.Text = baseText .. "\n"
local inventory = {sword, laser, lamp}      -- tableau avec les 3 valeurs

for i, item in pairs(inventory) do
    screen.Text = screen.Text .. "Objet " .. i .. " : " .. item .. "\n"
end

Teste ! Contrôle : l’écran affiche 3 lignes : « Objet 1 : 10 », « Objet 2 : 50 », « Objet 3 : 2 ».

QCM :

  1. Que vaut inventory[1] ?
    • a) Le nombre de cases.
    • b) La première valeur du tableau (10, la valeur de sword).
    • c) Une erreur.
  2. Dans for i, item in pairs(inventory) do, que vaut item ?
    • a) La valeur de la case courante du tableau.
    • b) Le nom du tableau.
    • c) Toujours 1.

Étape 10 : Le tableau double (objet ET valeur)

But : afficher le nom de chaque objet et sa valeur. Un tableau dans un tableau !

Explication : chaque case d’un tableau peut contenir… un autre tableau ! {{"sword", 10}, {"laser", 50}}. Pour lire la case 1 d’un sous-tableau : item[1].

-- ÉTAPE 10 : Affiche les noms et les valeurs de l'inventaire
task.wait(2)
screen.Text = baseText .. "\n"
inventory = {{"sword", sword}, {"laser", laser}, {"lamp", lamp}}   -- tableau double

for i, item in pairs(inventory) do
    screen.Text = screen.Text .. i .. ") " .. item[1] .. " : " .. item[2] .. "\n"
end
baseText = screen.Text     -- on mémorise pour la suite

Teste ! Contrôle : l’écran affiche : « 1) sword : 10 », « 2) laser : 50 », « 3) lamp : 2 ». Le nom ET la valeur !

QCM :

  1. Que vaut item[2] dans la boucle ?
    • a) Le nom de l’objet.
    • b) La position dans le tableau.
    • c) La valeur (le nombre de points) de l’objet courant.
  2. Comment s’appelle un tableau qui contient d’autres tableaux ?
    • a) Un tableau double (imbriqué).
    • b) Une boucle.
    • c) Une propriété.

Étape 11 : La boucle while (la jauge d’énergie)

But : faire monter une jauge d’énergie jusqu’à 100, barre par barre.

Explication : la boucle while (« tant que ») répète un code tant qu’une condition est vraie. Ici : tant que l’énergie est inférieure au maximum, on ajoute 10.

-- ÉTAPE 11 : Charge la jauge d'énergie
task.wait(2)
local energy = 10                 -- énergie de départ
local maxEnergy = 100             -- énergie maximale
screen.Text = screen.Text .. "Energie : "
while energy < maxEnergy do       -- TANT QUE energy < 100
    energy = energy + 10          -- ajouter 10
    screen.Text = screen.Text .. "▄"    -- une barre de plus (Alt+220)
    task.wait(0.3)
end

Teste ! Contrôle : les barres « ▄ » s’ajoutent une par une, puis s’arrêtent d’elles-mêmes quand l’énergie atteint 100. La boucle s’est toute seule arrêtée : c’est la condition qui l’a décidée !

QCM :

  1. Quand la boucle while s’arrête-t-elle ?
    • a) Quand la condition devient fausse (ici, quand energy atteint 100).
    • b) Après 10 secondes.
    • c) Jamais.
  2. Quelle est la différence avec la boucle for ?
    • a) Aucune.
    • b) for répète un nombre de fois connu ; while répète jusqu’à une condition.
    • c) while ne marche que sur les écrans.

Étape 12 : Transformer le cube (taille et couleur)

But : faire grandir, rétrécir, changer la couleur du cube magique… en boucle !

Explication : la Size d’une Part est un Vector3 (largeur, hauteur, profondeur) : on peut l’additionner ou la soustraire avec += et -=. La couleur est faite avec Color3.fromRGB : si les 3 nombres sont égaux, on obtient un gris (0 = noir, 255 = blanc) !

-- ÉTAPE 12a : Fais grandir le cube, puis rétrécir
task.wait(2)
for i = 1, 10 do
    part.Size += Vector3.new(i, i, i)    -- le cube grossit de plus en plus fort !
    task.wait(0.3)
end
for i = 1, 10 do
    part.Size -= Vector3.new(i, i, i)   -- et il rétrécit
    task.wait(0.3)
end

-- ÉTAPE 12b : Du noir au blanc (le gris)
for i = 0, 255 do
    part.Color = Color3.fromRGB(i, i, i)    -- gris qui s'éclaircit
    task.wait(0.01)
end

-- ÉTAPE 12c : Une couleur vivante (du noir au rouge)
for i = 0, 255 do
    part.Color = Color3.fromRGB(i, 160, 160)   -- rouge qui monte, vert/bleu fixes
    task.wait(0.01)
end

Teste ! Contrôle : le cube grossit de plus en plus vite (car i augmente à chaque tour !), rétrécit, passe du noir au gris clair, puis prend une teinte rouge. Modifie le 160 : que se passe-t-il avec Color3.fromRGB(i, 0, 0) ?

QCM :

  1. Pourquoi le cube grandit-il de plus en plus vite dans la première boucle ?
    • a) Parce que task.wait raccourcit.
    • b) Parce que i augmente à chaque tour, et on ajoute Vector3.new(i, i, i).
    • c) Parce qu’il est magique.
  2. Que donne Color3.fromRGB(100, 100, 100) ?
    • a) Un gris moyen.
    • b) Du rouge pur.
    • c) Du blanc pur.

Étape 13 : Invisible puis visible (la transparence)

But : faire disparaître le cube puis le faire réapparaître.

Explication : la propriété Transparency va de 0 (opaque) à 1 (invisible). Deux boucles while parfaites pour ça !

-- ÉTAPE 13a : Rend le cube transparent (disparition)
while part.Transparency < 1 do
    part.Transparency += 0.1    -- un peu plus transparent...
    task.wait(0.1)
end

-- ÉTAPE 13b : Rend-le opaque (réapparition)
task.wait(2)
while part.Transparency > 0 do
    part.Transparency -= 0.1    -- un peu plus opaque...
    task.wait(0.1)
end

Teste ! Contrôle : le cube s’efface progressivement puis réapparaît tout doucement, comme un fantôme !

QCM :

  1. Quand une Part est-elle complètement invisible ?
    • a) Quand Transparency = 0.
    • b) Quand Transparency = 1.
    • c) Quand Transparency = 255.
  2. Que fait part.Transparency += 0.1 ?
    • a) Il ajoute 0.1 à la transparence actuelle (avec +=).
    • b) Il remplace la transparence par 0.1.
    • c) Il change la taille.

Étape 14 : Le clonage : construis une pyramide inversée !

But : cloner le cube 10 fois pour construire une pyramide inversée : chaque nouvel étage est plus large que le précédent, posé au-dessus.

Explication : part:Clone() crée une copie exacte de la Part. On la modifie ensuite (position, taille) puis on l’attache au dossier avec .Parent. Sans .Parent, l’objet reste invisible ! Attention aussi : chaque copie doit avoir un nom différent (« Part1 », « Part2″…) pour pouvoir la retrouver ensuite.

-- ÉTAPE 14 : Construis la pyramide inversée
task.wait(3)
screen.Text = baseText                     -- on nettoie l'écran
for i = 1, 10 do
    local newPart = part:Clone()           -- une copie du cube
    newPart.Position += Vector3.new(0, newPart.Size.Y * i, 0)   -- posée plus haut à chaque fois
    newPart.Size += Vector3.new(i * 3, 0, i * 3)                -- de plus en plus large !
    newPart.Parent = folder               -- ATTACHE la copie au monde
    newPart.Name = "Part" .. i             -- nom unique : "Part1", "Part2"...
    task.wait(1)
end

Teste ! Contrôle : un nouveau bloc apparaît chaque seconde, posé au-dessus du précédent, et de plus en plus large : la pyramide pointe vers le bas ! Regarde dans l’Explorer : les Part1 à Part10 sont bien dans Folder.

QCM :

  1. Que fait part:Clone() ?
    • a) Il crée une copie identique de la Part.
    • b) Il supprime la Part.
    • c) Il change la couleur.
  2. Que se passe-t-il si on oublie newPart.Parent = folder ?
    • a) Le jeu plante.
    • b) La copie existe en mémoire mais n’apparaît pas dans le jeu.
    • c) Rien, c’est la même chose.
  3. Pourquoi newPart.Name = "Part" .. i ?
    • a) Pour donner un nom unique à chaque copie et la retrouver plus tard.
    • b) Pour la détruire.
    • c) Pour changer sa couleur.

Étape 15 : La destruction : démolis la pyramide à l’envers !

But : détruire les blocs du haut vers le bas (ordre inverse).

Explication : :Destroy() supprime définitivement un objet. Pour retrouver chaque bloc par son nom, on utilise FindFirstChild : "Part" .. i fabrique le nom à chercher !

-- ÉTAPE 15 : Détruis les blocs dans l'ordre inverse
task.wait(3)
for i = 10, 1, -1 do                                   -- du dernier au premier !
    local block = folder:FindFirstChild("Part" .. i)   -- retrouve le bloc par son nom
    if block then
        block:Destroy()                                -- ... et détruis-le !
    end
    task.wait(1)
end
task.wait(3)

Teste ! Contrôle : les blocs disparaissent un par un, du haut vers le bas. À la fin, l’Explorer ne contient plus que TableauPart et Part !

  1. Que fait folder:FindFirstChild("Part" .. i) ?
    • a) Il détruit la Part.
    • b) Il cherche dans le dossier l’objet nommé « Part1 », « Part2″… selon la valeur de i.
    • c) Il crée une Part.
  2. Pourquoi la boucle va de 10 à 1 avec un pas de -1 ?
    • a) Pour aller plus vite.
    • b) Par hasard.
    • c) Pour détruire les blocs dans l’ordre inverse de leur création (du haut vers le bas).
  3. Pourquoi vérifie-t-on if block then avant de détruire ?
    • a) Pour éviter une erreur si le bloc n’existe pas (il retourne nil).
    • b) Pour changer sa couleur.
    • c) Ce n’est pas utile.

Résumé des concepts découverts

ConceptDescriptionExemple
PropriétésLes réglages d’un objet.screen.Text, part.Color
Variable texte / nombreUne boîte étiquetée contenant une valeur.local firstName = "patrick"
Concaténation ..Coller des textes (et nombres) ensemble."J'ai " .. age
\nSaut de ligne dans un texte.screen.Text .. "\n"
Color3.fromRGBFabriquer une couleur (rouge, vert, bleu : 0-255).Color3.fromRGB(85, 255, 255)
Calculs‘+, -, *, / et les parenthèses.fuelTank + fuelBought - (trips * fuelPerTrip)
Boucle forRépéter un nombre de fois connu (avec pas négatif pour décompter).for i = 10, 1, -1 do
Boucle whileRépéter tant qu’une condition est vraie.while energy < maxEnergy do
TableauUne liste de valeurs.{sword, laser, lamp}
Tableau doubleUn tableau de tableaux (nom + valeur).{{"sword", 10}}
pairsParcourir un tableau (index + valeur).for i, item in pairs(inventory) do
‘+= et -=Ajouter / retirer à une valeur.part.Size += Vector3.new(i, i, i)
Clone()Copier un objet.part:Clone()
Destroy()Supprimer un objet.block:Destroy()
FindFirstChildRetrouver un objet par son nom.folder:FindFirstChild("Part" .. i)

Défi final :

  1. Personnalise l’écran : affiche ton prénom, ton âge, ton inventaire imaginé (5 objets dans un tableau double !).
  2. Crée un escalier : au lieu d’une pyramide inversée, fais des marches qui montent en décalant aussi sur l’axe X (Vector3.new(i * 5, i * 2, 0)).

Félicitations ! Tu viens de découvrir presque toutes les bases de la programmation Lua : variables, conditions, boucles, tableaux, objets et propriétés. Tous les grands jeux Roblox sont construits avec ces mêmes briques !