Catégories
Jeu vidéo ROBLOX

Tuto 01 : Trouve la bonne couleur !

Tu vas construire, étape par étape, un mini-jeu appelé « Trouve la bonne couleur ».

Voici la règle du jeu : au démarrage, le jeu tire une couleur au hasard parmi rouge, vert et bleu, et l’affiche sur un bloc de référence. Sur un plateau composé de plusieurs blocs, un seul de ces blocs a exactement cette couleur, les autres ont des couleurs différentes. Le joueur doit se déplacer et toucher le bloc qui possède la bonne couleur.

Si le joueur touche le bon bloc, il regagne toute sa vie. Si le joueur touche un mauvais bloc, il perd 10 points de vie. Une fois le bon bloc trouvé, une nouvelle manche démarre automatiquement après quelques secondes, avec une nouvelle couleur à retrouver.

Ce tutoriel est découpé en huit étapes. Chaque étape t’apprend un ou plusieurs concepts de programmation que tu retrouveras dans énormément d’autres jeux et logiciels : les variables, les conditions, les boucles, les fonctions et les événements. À la fin, tu auras écrit et compris l’intégralité du script du jeu, et tu pourras l’améliorer toi-même.

Une variable, en programmation, c’est comme une boîte dans laquelle on range une information (un nombre, un texte, une couleur…) et à laquelle on donne un nom pour la retrouver facilement. C’est une idée que tu vas beaucoup utiliser dans ce tutoriel.

N’aie pas peur de te tromper. Une erreur dans un script n’est pas grave : elle t’indique simplement qu’il faut chercher et corriger, exactement comme un jeu de piste. C’est comme ça que tous les programmeurs apprennent.

Étape 1 : Comprendre le jeu avant de coder

But : Avant d’écrire la moindre ligne de code, tu vas apprendre à analyser un jeu et à le découper en petites règles simples. C’est une étape indispensable pour tout programmeur, avant même d’ouvrir un éditeur de code.

Concepts clés : analyse d’un problème, découpage en étapes logiques.

Explications :

Un programmeur ne commence jamais à écrire du code au hasard. Il commence par se poser des questions simples : que doit faire le jeu, dans quel ordre, et que doit-il se passer dans chaque situation.

Pour notre jeu, on peut résumer les règles ainsi :

  • Le jeu choisit une couleur au hasard.
  • Cette couleur est affichée sur un bloc de référence.
  • Un bloc du plateau reçoit exactement cette couleur, les autres blocs reçoivent d’autres couleurs.
  • Quand le joueur touche un bloc, le script compare sa couleur à la couleur de référence.
  • Si les couleurs sont identiques, le joueur regagne toute sa vie.
  • Si les couleurs sont différentes, le joueur perd 10 points de vie.
  • Une nouvelle manche démarre après un court délai.

Chacune de ces phrases va correspondre, un peu plus tard, à un morceau de code.

À toi de jouer !

Ensuite, essaie d’imaginer un autre mini-jeu avec la même idée (retrouver un élément parmi plusieurs) et écris ses règles de la même façon. Par exemple, un jeu où il faudrait retrouver la bonne forme plutôt que la bonne couleur.

Étape 2 : Modifier les propriétés d’un objet Roblox

But : Apprendre à accéder à un objet du jeu (une Part) et à modifier une de ses propriétés, ici sa couleur.

Concepts clés : variables, propriétés d’un objet, Color3.

Explications :

Dans Roblox, tout ce que tu vois dans le monde du jeu (un bloc, un personnage, une porte) est un objet, appelé instance. Chaque objet possède des propriétés que l’on peut lire ou modifier depuis un script, par exemple sa position, sa taille ou sa couleur.

Pour récupérer un objet du jeu dans le script, on utilise WaitForChild, qui va chercher un objet par son nom et attend qu’il existe avant de continuer. On range le résultat dans une variable, notre « boîte » qui va contenir l’objet.

Crée dans le workspace par Explorer la structure suivante un folder « ColorsGame », un script « ColorsGameScript, une part ReferenceColor :

Pour changer la couleur d’un objet, on utilise sa propriété Color, à laquelle on donne une valeur créée avec Color3.fromRGB(rouge, vert, bleu). Chacun des trois nombres va de 0 à 255 et représente la quantité de rouge, de vert ou de bleu dans la couleur finale.

Code Lua :

-- On récupère le dossier principal du jeu dans le Workspace
local colorsGameFolder = workspace:WaitForChild("ColorsGame")

-- On récupère la partie qui affiche la couleur de référence (celle à retrouver)
local referenceColorPart = colorsGameFolder:WaitForChild("ReferenceColor")

-- On modifie la propriété Color de cet objet pour lui donner une couleur rouge vif
referenceColorPart.Color = Color3.fromRGB(255, 0, 0)

À toi de jouer !

Recopie ce code dans le ColorsGameScript placé dans le Workspace de Roblox Studio, en remplaçant « Part » par le nom exact ReferenceColor d’un bloc que tu as toi-même placé dans ton lieu. Lance le jeu en mode test et observe la couleur du bloc.

Ensuite, modifie les trois nombres de Color3.fromRGB pour obtenir une couleur verte, puis une couleur bleue, puis une couleur de ton choix.

QCM :

  1. Que représente Color3.fromRGB(0, 255, 0) ?
    • a) Une couleur rouge.
    • b) Une couleur verte.
    • c) Une couleur bleue.
  2. Que fait workspace:WaitForChild("MyPart") ?
    • a) Il crée un nouveau bloc nommé « MyPart ».
    • b) Il récupère l’objet nommé « MyPart » et attend qu’il existe avant de continuer.
    • c) Il supprime l’objet « MyPart ».

Étape 3 : Débugger et tester chaque étape

But : Apprendre à utiliser l’instruction print pour afficher des informations dans la console de sortie, afin de vérifier que le script fait bien ce que l’on attend de lui.

Concepts clés : print, console de sortie, débogage.

Explications :

Quand un script ne fonctionne pas comme prévu, il est très utile de pouvoir « regarder à l’intérieur » pour comprendre ce qui se passe réellement. C’est le rôle de l’instruction print : elle affiche du texte ou la valeur d’une variable dans la fenêtre « Output » (sortie) de Roblox Studio.

Cette technique s’appelle le débogage, ou debug en anglais. C’est une des compétences les plus importantes en programmation : un programmeur passe une grande partie de son temps à vérifier pourquoi son code ne fait pas exactement ce qu’il souhaite.

Code Lua :

-- On récupère le dossier principal du jeu dans le Workspace
local colorsGameFolder = workspace:WaitForChild("ColorsGame")

-- On récupère la partie qui affiche la couleur de référence (celle à retrouver)
local referenceColorPart = colorsGameFolder:WaitForChild("ReferenceColor")

-- On modifie la propriété Color de cet objet pour lui donner une couleur rouge vif
referenceColorPart.Color = Color3.fromRGB(0, 255, 0)

-- On affiche à nouveau la couleur pour vérifier qu'elle a bien changé
print("Nouvelle couleur de MyPart :", referenceColorPart.Color)

À toi de jouer !

Ajoute ces lignes print à ton script de l’étape 2, lance le jeu en mode test, puis ouvre la fenêtre « Output » dans Roblox Studio (menu View, puis Output) pour lire les messages affichés.

Essaie d’ajouter un print supplémentaire de ton choix, par exemple pour afficher le nom de l’objet avec myPart.Name.

QCM :

  1. À quoi sert l’instruction print ?
    • a) À afficher un message ou la valeur d’une variable dans la console, pour vérifier le fonctionnement du script.
    • b) À supprimer un objet du jeu.
    • c) À faire gagner le joueur.
  2. Pourquoi le débogage est-il important en programmation ?
    • a) Il ne sert à rien, on peut s’en passer.
    • b) Il permet de comprendre ce qui se passe réellement dans le script et de corriger les erreurs.
    • c) Il remplace le besoin d’écrire du code.

Étape 4 : Donner de l’imprévisibilité au jeu

But : Apprendre à générer un nombre au hasard avec math.random, puis à utiliser une condition if / elseif pour choisir une couleur différente selon ce nombre.

Concepts clés : math.random, conditions if / elseif.

Explications :

Un jeu comme « Trouve la bonne couleur » doit surprendre le joueur à chaque manche : la couleur à retrouver ne doit jamais être toujours la même. Pour cela, on utilise le hasard, avec la fonction math.random(min, max), qui renvoie un nombre entier choisi au hasard entre min et max.

Une fois ce nombre obtenu, on utilise une condition if / elseif pour décider quoi faire selon sa valeur. Une condition permet à un script de prendre des décisions différentes selon la situation, un peu comme lorsque tu choisis un chemin différent selon le panneau indicateur que tu croises.

Code Lua :

-- On récupère le dossier principal du jeu dans le Workspace
local colorsGameFolder = workspace:WaitForChild("ColorsGame")

-- On récupère la partie qui affiche la couleur de référence (celle à retrouver)
local referenceColorPart = colorsGameFolder:WaitForChild("ReferenceColor")

-- On modifie la propriété Color de cet objet pour lui donner une couleur rouge vif
referenceColorPart.Color = Color3.fromRGB(0, 255, 0)

-- On tire un nombre entier au hasard entre 1 et 3
local randomChoice = math.random(1, 3)
print("Nombre tiré :", randomChoice)

local referenceColor = nil

-- Selon le nombre tiré, on choisit une couleur dominante différente
if randomChoice == 1 then
	referenceColor = Color3.fromRGB(math.random(150, 255), 0, 0) -- couleur rouge
elseif randomChoice == 2 then
	referenceColor = Color3.fromRGB(0, math.random(150, 255), 0) -- couleur verte
elseif randomChoice == 3 then
	referenceColor = Color3.fromRGB(0, 0, math.random(150, 255)) -- couleur bleue
end

referenceColorPart.Color = referenceColor

-- On affiche à nouveau la couleur pour vérifier qu'elle a bien changé
print("Nouvelle couleur de MyPart :", referenceColorPart.Color)

Le fait d’utiliser math.random(150, 255) plutôt que math.random(0, 255) garantit une couleur assez claire et vive, jamais trop sombre.

À toi de jouer !

Ajoute ce code à ton script et lance le jeu plusieurs fois de suite en mode test. Observe que la couleur change à chaque lancement.

Modifie ensuite l’intervalle math.random(150, 255) en math.random(0, 100) et observe la différence sur les couleurs obtenues.

QCM :

  1. Que fait math.random(1, 3) ?
    • a) Il renvoie toujours le nombre 3.
    • b) Il renvoie un nombre entier choisi au hasard entre 1 et 3.
    • c) Il renvoie un nombre décimal entre 1 et 3.
  2. À quoi sert une condition if / elseif dans un script ?
    • a) À répéter plusieurs fois la même action.
    • b) À faire prendre au script une décision différente selon une situation.
    • c) À afficher un message dans la console.

Étape 5 : Organiser son code

But : Apprendre à créer une fonction pour regrouper un ensemble d’instructions que l’on pourra réutiliser plusieurs fois.

Concepts clés : fonctions, paramètres, valeur de retour.

Explications :

Une fonction est un bloc de code auquel on donne un nom, et que l’on peut exécuter (« appeler ») autant de fois que nécessaire, sans avoir à recopier le code à chaque fois. Une fonction peut recevoir des informations en entrée, appelées paramètres, et peut renvoyer un résultat avec return.

Dans notre jeu, on va regrouper tout le code qui choisit une nouvelle couleur dans une fonction nommée chooseColor. Elle prendra en paramètre le bloc de référence et le plateau de blocs, et renverra la couleur choisie.

Code Lua :

-- On récupère le dossier principal du jeu dans le Workspace
local colorsGameFolder = workspace:WaitForChild("ColorsGame")

-- On récupère la partie qui affiche la couleur de référence (celle à retrouver)
local referenceColorPart = colorsGameFolder:WaitForChild("ReferenceColor")

-- On modifie la propriété Color de cet objet pour lui donner une couleur rouge vif
referenceColorPart.Color = Color3.fromRGB(0, 255, 0)

local function chooseColor(referenceColorPart)
	-- On tire un nombre entier au hasard entre 1 et 3
	local randomChoice = math.random(1, 3)
	print("Nombre tiré :", randomChoice)

	local referenceColor = nil

	-- Selon le nombre tiré, on choisit une couleur dominante différente
	if randomChoice == 1 then
		referenceColor = Color3.fromRGB(math.random(150, 255), 0, 0) -- couleur rouge
	elseif randomChoice == 2 then
		referenceColor = Color3.fromRGB(0, math.random(150, 255), 0) -- couleur verte
	elseif randomChoice == 3 then
		referenceColor = Color3.fromRGB(0, 0, math.random(150, 255)) -- couleur bleue
	end

	referenceColorPart.Color = referenceColor
	
	return referenceColor
end

local referenceColor = chooseColor(referenceColorPart)

-- On affiche à nouveau la couleur pour vérifier qu'elle a bien changé
print("Nouvelle couleur de MyPart :", referenceColorPart.Color)

À toi de jouer !

Ajoute ce code à ton script. Appelle la fonction chooseColor deux fois de suite dans deux variables différentes, et affiche les deux résultats avec print pour vérifier qu’ils sont bien différents.

QCM :

  1. Pourquoi utilise-t-on une fonction plutôt que de recopier plusieurs fois le même code ?
    • a) Parce que Lua interdit de recopier du code.
    • b) Pour éviter les répétitions et pouvoir réutiliser facilement le même bloc de code.
    • c) Parce que cela rend le jeu plus rapide.
  2. Que fait l’instruction return dans une fonction ?
    • a) Elle arrête complètement le jeu.
    • b) Elle renvoie un résultat à l’endroit où la fonction a été appelée.
    • c) Elle affiche un message dans la console.

Étape 6 : Optimiser son code

But : Apprendre à parcourir automatiquement tous les objets contenus dans un dossier grâce à une boucle, plutôt que de traiter chaque bloc un par un.

Concepts clés : boucles for, GetChildren, IsA.

Explications :

Notre plateau de jeu, ColorBoard, ne contient pas un seul bloc mais plusieurs. Écrire manuellement le code pour chacun des blocs serait très long, et il faudrait tout réécrire si on ajoute un bloc supplémentaire. À la place, on utilise une boucle for, qui répète automatiquement une même action pour chaque objet d’une liste.

La méthode GetChildren() renvoie la liste de tous les objets contenus dans un dossier. On la combine avec ipairs(...) pour parcourir cette liste un par un, en récupérant à chaque tour de boucle un index (1, 2, 3…) et l’objet correspondant.

Comme un dossier peut contenir des objets qui ne sont pas des blocs (un script, par exemple), on vérifie le type de chaque objet avec part:IsA("BasePart") avant de le modifier.

Enfin, pour tirer au sort l’index du bloc gagnant parmi tous les blocs du plateau, on utilise #colorBoard:GetChildren(), qui compte le nombre maxi d’objets présents dans la liste.

Code Lua :

-- On récupère le dossier principal du jeu dans le Workspace
local colorsGameFolder = workspace:WaitForChild("ColorsGame")

-- On récupère la partie qui affiche la couleur de référence (celle à retrouver)
local referenceColorPart = colorsGameFolder:WaitForChild("ReferenceColor")

-- On modifie la propriété Color de cet objet pour lui donner une couleur rouge vif
referenceColorPart.Color = Color3.fromRGB(0, 255, 0)

local function chooseColor(referenceColorPart)
	-- On tire un nombre entier au hasard entre 1 et 3
	local randomChoice = math.random(1, 3)
	print("Nombre tiré :", randomChoice)

	local referenceColor = nil

	-- Selon le nombre tiré, on choisit une couleur dominante différente
	if randomChoice == 1 then
		referenceColor = Color3.fromRGB(math.random(150, 255), 0, 0) -- couleur rouge
	elseif randomChoice == 2 then
		referenceColor = Color3.fromRGB(0, math.random(150, 255), 0) -- couleur verte
	elseif randomChoice == 3 then
		referenceColor = Color3.fromRGB(0, 0, math.random(150, 255)) -- couleur bleue
	end

	referenceColorPart.Color = referenceColor
	
	return referenceColor
end

local referenceColor = chooseColor(referenceColorPart)

-- On affiche à nouveau la couleur pour vérifier qu'elle a bien changé
print("Nouvelle couleur de MyPart :", referenceColorPart.Color)

local colorBoard = colorsGameFolder:WaitForChild("ColorBoard")

-- On compte le nombre de blocs, puis on tire au sort l'index du bloc gagnant
local correctPartIndex = math.random(1, #colorBoard:GetChildren())

-- On parcourt tous les objets contenus dans ColorBoard
for index, part in ipairs(colorBoard:GetChildren()) do

	-- On ne traite que les objets qui sont bien des blocs
	if part:IsA("BasePart") then
		print(index, correctPartIndex)

		if index == correctPartIndex then
			-- C'est le bloc tiré au sort : il reçoit la couleur de référence
			part.Color = referenceColor
		else
			-- Les autres blocs reçoivent une couleur aléatoire différente
			part.Color = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
		end
	end
end

À toi de jouer !

Place plusieurs blocs dans un dossier nommé « ColorBoard » dans le Workspace, puis ajoute ce code à ton script. Lance le jeu en mode test et observe qu’un seul bloc a exactement la couleur de référence.

Ajoute ou supprime un bloc dans le dossier « ColorBoard », relance le jeu, et vérifie que le code fonctionne toujours sans rien modifier.

QCM :

  1. Que renvoie colorBoard:GetChildren() ?
    • a) Le nom du dossier ColorBoard.
    • b) La liste de tous les objets contenus dans le dossier ColorBoard.
    • c) La couleur du dossier ColorBoard.
  2. Pourquoi utilise-t-on part:IsA("BasePart") dans la boucle ?
    • a) Pour vérifier que l’objet est bien un bloc avant de modifier sa couleur.
    • b) Pour compter le nombre d’objets.
    • c) Pour supprimer les objets qui ne sont pas des blocs.

Étape 7 : Construire l’architecture du jeu

But : Apprendre à créer une constante pour les valeurs qui ne changent jamais et assembler l’ensemble des concepts vus précédemment (variables, fonctions, boucles, conditions) avec un nouvel élément essentiel : les événements, pour obtenir le script complet et jouable du jeu.

Concepts clés : constantes, événements, Touched, Humanoid, Health, task.spawn, task.wait.

Explications :

Une constante est une variable dont la valeur ne change jamais pendant toute la partie, par exemple le nombre de points de vie perdus en cas d’erreur. On lui donne généralement un nom entièrement en majuscules, pour bien la distinguer des autres variables, par exemple LOSS_HEALTH.

Un événement est une notification envoyée par Roblox lorsqu’une action précise se produit dans le jeu, par exemple un contact entre deux objets. Chaque Part possède un événement Touched, auquel on peut « s’abonner » avec :Connect(function(hit) ... end) pour exécuter du code à chaque fois qu’un contact a lieu.

Dans la fonction connectée à Touched, hit désigne la partie qui a touché le bloc, généralement une main ou un pied. Son Parent est alors le personnage entier du joueur. Ce personnage possède un objet Humanoid, que l’on récupère avec FindFirstChildOfClass("Humanoid"), et qui gère notamment sa vie via la propriété Health.

En assemblant tout, on obtient l’architecture complète du script : on récupère les objets du jeu, on définit la fonction chooseColor, on l’appelle une première fois pour démarrer la partie, puis on parcourt tous les blocs du plateau pour préparer leurs propriétés et connecter l’événement Touched sur chacun d’eux.

Enfin, task.spawn permet d’exécuter du code « en parallèle » du reste du script, et task.wait(secondes) permet de faire patienter ce code sans bloquer le reste du jeu, ce qui est utilisé pour relancer une nouvelle manche quelques secondes après une bonne réponse.

Code Lua :

-- =========================================================
-- JEU : Trouve la bonne couleur !
-- Le jeu choisit une couleur au hasard (rouge, vert ou bleu).
-- Un des blocs de la ColorBoard aura exactement cette couleur.
-- Si le joueur touche le bon bloc, il regagne toute sa vie.
-- Si le joueur touche un mauvais bloc, il perd 10 points de vie.
-- =========================================================

local LOSS_HEALTH = 10 -- perte de santé pour un mauvais choix
local GAME_TIMEOUT = 5 -- en secondes, pour un time out avent de rejouer la partie = 5

-- On récupère le dossier principal du jeu dans le Workspace
local colorsGameFolder = workspace:WaitForChild("ColorsGame")

-- On récupère la partie qui affiche la couleur de référence (celle à retrouver)
local referenceColorPart = colorsGameFolder:WaitForChild("ReferenceColor")

-- On récupère le plateau qui contient tous les blocs de couleur
local colorBoard = colorsGameFolder:WaitForChild("ColorBoard")


local function chooseColor(referenceColorPart, colorBoard)
	-- Cette variable va contenir la couleur de référence à retrouver
	local referenceColor = nil
	-- On tire un nombre au hasard entre 1 et 3 pour choisir quelle couleur dominante on va utiliser
	local randomChoice = math.random(1, 3)
	-- Selon le nombre tiré, on crée une couleur avec un fort rouge, vert ou bleu
	-- math.random(150, 255) donne une couleur assez claire/vive, pas trop sombre
	if randomChoice == 1 then
		referenceColor = Color3.fromRGB(math.random(150, 255), 0, 0) -- couleur rouge
	elseif randomChoice == 2 then
		referenceColor = Color3.fromRGB(0, math.random(150, 255), 0) -- couleur verte
	elseif randomChoice == 3 then
		referenceColor = Color3.fromRGB(0, 0, math.random(150, 255)) -- couleur bleue
	end

	-- On applique cette couleur à la partie "ReferenceColor" pour que le joueur puisse la voir
	referenceColorPart.Color = referenceColor

	-- On choisit au hasard l'INDEX du bloc qui aura la bonne couleur (le bloc "gagnant")
	local correctPartIndex = math.random(1, #colorBoard:GetChildren())

	-- On parcourt tous les blocs présents dans le plateau de couleurs
	for index, part in ipairs(colorBoard:GetChildren()) do

		-- On vérifie que l'objet est bien un "BasePart" (un bloc, pas un script ou autre chose)
		if part:IsA("BasePart") then
			print(index, correctPartIndex)
			-- Si c'est le bloc tiré au sort, on lui donne la couleur de référence (le bon bloc)
			if index == correctPartIndex then
				part.Color = referenceColor
			else
				-- Sinon, on lui donne une couleur totalement aléatoire (un bloc piège)
				part.Color = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
			end
		end
	end
	
	return referenceColor	
end

local referenceColor = chooseColor(referenceColorPart, colorBoard)

-- On parcourt tous les blocs présents dans le plateau de couleurs
for index, part in pairs(colorBoard:GetChildren()) do

	-- On vérifie que l'objet est bien un "BasePart" (un bloc, pas un script ou autre chose)
	if part:IsA("BasePart") then
		part.Material = Enum.Material.Plastic
		part.Anchored = true
		part.CanCollide = true

		-- On surveille si un joueur touche ce bloc
		part.Touched:Connect(function(hit)

			-- "hit" est la partie du joueur qui a touché le bloc (souvent une main ou un pied)
			-- Son "Parent" est le personnage (le modèle) du joueur
			local character = hit.Parent
			if not character then return end -- si on ne trouve pas de personnage, on arrête ici

			-- On cherche l'Humanoid du personnage, c'est lui qui gère la vie (Health)
			local humanoid = character:FindFirstChildOfClass("Humanoid")
			if not humanoid then return end -- si pas d'Humanoid, on arrête ici (ce n'est pas un joueur)
			
			if part.Color == Color3.fromRGB(255, 255, 255) then return end

			-- On compare la couleur du bloc touché avec la couleur de référence
			if part.Color == referenceColor then
				-- Bonne couleur : le joueur récupère toute sa vie
				humanoid.Health = 100
				part.Color = Color3.fromRGB(255, 255, 255)
				part.Material = Enum.Material.Neon
				task.spawn(function()
					task.wait(GAME_TIMEOUT)
					referenceColor = chooseColor(referenceColorPart, colorBoard)
					part.Material = Enum.Material.Plastic
				end)
			else
				-- Mauvaise couleur : le joueur perd 10 points de vie
				humanoid.Health -= LOSS_HEALTH
			end
		end)
	end
end


À toi de jouer !

Recrée dans le Workspace un dossier nommé « ColorsGame » contenant une Part nommée « ReferenceColor » et un dossier nommé « ColorBoard » rempli de plusieurs blocs. Copie ce script complet, lance le jeu en mode test, et essaie de retrouver le bon bloc avec ton personnage.

Modifie la valeur de LOSS_HEALTH pour la mettre à 25, relance le jeu, et observe en combien de mauvais choix ton personnage perd toute sa vie.

QCM :

  1. À quoi sert l’événement Touched ?
    • a) À déplacer un bloc.
    • b) À exécuter du code lorsqu’un contact se produit avec la Part.
    • c) À changer la couleur du plateau automatiquement.
  2. Pourquoi utilise-t-on task.spawn avant task.wait(GAME_TIMEOUT) ?
    • a) Pour arrêter complètement le jeu pendant l’attente.
    • b) Pour exécuter cette attente en parallèle, sans bloquer le reste du script.
    • c) Pour supprimer le bloc touché.

Étape 8 : Améliorations pour aller plus loin

But : Utiliser tous les concepts appris pour faire évoluer le jeu par toi-même, en ajoutant de nouvelles règles.

Concepts clés : réinvestissement des concepts précédents, créativité.

Explications :

Maintenant que tu comprends l’ensemble du script, tu es capable de le modifier pour créer tes propres règles. Voici quelques pistes, de la plus simple à la plus avancée :

Ajouter un score : crée une variable playerScore initialisée à 0, augmente-la de 1 à chaque bonne réponse, et affiche-la avec print ou dans une interface.

Ajouter un chronomètre : utilise RunService.Heartbeat pour calculer le temps du jeu afin de contrôler le temps de chaque manche.

local RunService = game:GetService("RunService")
local temps = 0 -- Temps écoulé en secondes
RunService.Heartbeat:Connect(function(dt)
    temps += dt

    local tempsEntier = math.floor(temps)
    local minutes = math.floor(tempsEntier / 60)
    local secondes = tempsEntier % 60

    print(string.format("%02d:%02d", minutes, secondes))
end)

Ajouter une condition de victoire : écris une fonction checkWinCondition() qui vérifie si playerScore a atteint une valeur suffisante, et qui affiche un message de victoire si c’est le cas.

Ajouter des obstacles : place des blocs supplémentaires qui ne font pas partie du jeu de couleurs, mais qui font perdre de la vie au joueur s’il les touche, en réutilisant l’événement Touched.

À toi de jouer !

Tu peux t’inspirer de ce tuto : https://123codage.com/points-de-respawns-comptage-des-tours-meilleur-temps/

Choisis au moins une de ces améliorations et essaie de l’ajouter à ton script. N’hésite pas à utiliser print pour vérifier que tes nouvelles variables évoluent bien comme tu le souhaites.

QCM :

  1. Que faudrait-il faire pour ajouter un système de score au jeu ?
    • a) Créer une variable comme playerScore et l’augmenter à chaque bonne réponse.
    • b) Modifier uniquement la couleur des blocs.
    • c) Supprimer la fonction chooseColor.
  2. Pourquoi est-il utile de réutiliser des concepts déjà appris (variables, conditions, boucles, événements) pour ajouter de nouvelles règles ?
    • a) Parce que ce sont les seuls outils disponibles en Lua.
    • b) Parce que ces mêmes concepts permettent de construire des règles de jeu très différentes.
    • c) Parce que Roblox Studio l’exige.
-- =========================================================
-- JEU : Trouve la bonne couleur !
-- Le jeu choisit une couleur au hasard (rouge, vert ou bleu).
-- Un des blocs de la ColorBoard aura exactement cette couleur.
-- Si le joueur touche le bon bloc, il regagne toute sa vie.
-- Si le joueur touche un mauvais bloc, il perd 10 points de vie.
-- =========================================================

local LOSS_HEALTH = 10 -- perte de santé pour un mauvais choix
local GAME_TIMEOUT = 5 -- en secondes, pour un time out avent de rejouer la partie = 5

-- On récupère le dossier principal du jeu dans le Workspace
local colorsGameFolder = workspace:WaitForChild("ColorsGame")

-- On récupère la partie qui affiche la couleur de référence (celle à retrouver)
local referenceColorPart = colorsGameFolder:WaitForChild("ReferenceColor")

-- On récupère le plateau qui contient tous les blocs de couleur
local colorBoard = colorsGameFolder:WaitForChild("ColorBoard")


local winSound = colorsGameFolder.winner
local alarmSound = colorsGameFolder.alarm

-- Créer une fonction pour charger et tester un son
local function playSound(sound)
	if not sound then return end
	pcall(function() sound:Play() end)
end

local function chooseColor(referenceColorPart, colorBoard)
	-- Cette variable va contenir la couleur de référence à retrouver
	local referenceColor = nil
	-- On tire un nombre au hasard entre 1 et 3 pour choisir quelle couleur dominante on va utiliser
	local randomChoice = math.random(1, 3)
	-- Selon le nombre tiré, on crée une couleur avec un fort rouge, vert ou bleu
	-- math.random(150, 255) donne une couleur assez claire/vive, pas trop sombre
	if randomChoice == 1 then
		referenceColor = Color3.fromRGB(math.random(150, 255), 0, 0) -- couleur rouge
	elseif randomChoice == 2 then
		referenceColor = Color3.fromRGB(0, math.random(150, 255), 0) -- couleur verte
	elseif randomChoice == 3 then
		referenceColor = Color3.fromRGB(0, 0, math.random(150, 255)) -- couleur bleue
	end

	-- On applique cette couleur à la partie "ReferenceColor" pour que le joueur puisse la voir
	referenceColorPart.Color = referenceColor

	-- On choisit au hasard l'INDEX du bloc qui aura la bonne couleur (le bloc "gagnant")
	local correctPartIndex = math.random(1, #colorBoard:GetChildren())

	-- On parcourt tous les blocs présents dans le plateau de couleurs
	for index, part in ipairs(colorBoard:GetChildren()) do

		-- On vérifie que l'objet est bien un "BasePart" (un bloc, pas un script ou autre chose)
		if part:IsA("BasePart") then
			print(index, correctPartIndex)
			-- Si c'est le bloc tiré au sort, on lui donne la couleur de référence (le bon bloc)
			if index == correctPartIndex then
				part.Color = referenceColor
			else
				-- Sinon, on lui donne une couleur totalement aléatoire (un bloc piège)
				part.Color = Color3.fromRGB(math.random(0, 255), math.random(0, 255), math.random(0, 255))
			end
		end
	end
	
	return referenceColor	
end

local referenceColor = chooseColor(referenceColorPart, colorBoard)

-- On parcourt tous les blocs présents dans le plateau de couleurs
for index, part in pairs(colorBoard:GetChildren()) do

	-- On vérifie que l'objet est bien un "BasePart" (un bloc, pas un script ou autre chose)
	if part:IsA("BasePart") then
		part.Material = Enum.Material.Plastic
		part.Anchored = true
		part.CanCollide = true

		-- On surveille si un joueur touche ce bloc
		part.Touched:Connect(function(hit)

			-- "hit" est la partie du joueur qui a touché le bloc (souvent une main ou un pied)
			-- Son "Parent" est le personnage (le modèle) du joueur
			local character = hit.Parent
			if not character then return end -- si on ne trouve pas de personnage, on arrête ici

			-- On cherche l'Humanoid du personnage, c'est lui qui gère la vie (Health)
			local humanoid = character:FindFirstChildOfClass("Humanoid")
			if not humanoid then return end -- si pas d'Humanoid, on arrête ici (ce n'est pas un joueur)
			
			if part.Color == Color3.fromRGB(255, 255, 255) then return end

			-- On compare la couleur du bloc touché avec la couleur de référence
			if part.Color == referenceColor then
				-- Bonne couleur : le joueur récupère toute sa vie
				humanoid.Health = 100
				part.Color = Color3.fromRGB(255, 255, 255)
				part.Material = Enum.Material.Neon
				task.spawn(function()
					playSound(winSound)
					task.wait(GAME_TIMEOUT)
					referenceColor = chooseColor(referenceColorPart, colorBoard)
					part.Material = Enum.Material.Plastic
				end)
			else
				-- Mauvaise couleur : le joueur perd 10 points de vie
				humanoid.Health -= LOSS_HEALTH
				task.spawn(function()
					playSound(alarmSound)
				end)

			end
		end)
	end
end

Conclusion

Mets-toi maintenant à la place d’un joueur qui découvre ton jeu pour la première fois : est-il facile à comprendre ? La règle est-elle claire dès les premières secondes ? Puis imagine ce même joueur devenir peu à peu un expert, capable de battre le jeu très rapidement : le jeu reste-t-il intéressant, ou devient-il trop simple ?

Ces deux points de vue, celui du débutant et celui de l’expert, sont essentiels pour améliorer un jeu vidéo : un bon jeu doit rester accessible au début, tout en offrant un défi qui évolue avec le joueur.

Tu peux maintenant partager ton jeu avec tes camarades et observer comment ils y jouent, ou continuer à le faire évoluer, par exemple en ajoutant un système de vies limitées, plusieurs niveaux de difficulté, ou un mode à plusieurs joueurs. Chaque nouvelle règle que tu ajouteras réutilisera les mêmes bases que tu viens d’apprendre : des variables pour stocker des informations, des conditions pour prendre des décisions, des boucles pour répéter des actions, des fonctions pour organiser le code, et des événements pour réagir à ce que fait le joueur.