Catégories
Jeu vidéo ROBLOX

Afficher un chrono du temps de parcours

Ce système affiche un chrono qui mesure le temps mis par un joueur pour aller d’un bloc de départ à un bloc d’arrivée.

Le script serveur est placé sur les blocs (départ/arrivée) : il détecte quand le joueur les touche (Touched) et décide quand le chrono doit démarrer ou s’arrêter.

Le LocalScript, lui, tourne uniquement sur l’ordinateur du joueur : il gère l’affichage du chrono à l’écran (le TextLabel).

Le serveur ne peut pas modifier directement l’écran d’un joueur : il doit envoyer un message au client via un RemoteEvent.

Le RemoteEvent fonctionne comme une messagerie entre le serveur et le client : quand le joueur touche le bloc de départ, le serveur « fire » (envoie) l’événement StartEvent.

Le LocalScript écoute cet événement avec OnClientEvent:Connect(...) et, dès qu’il le reçoit, enregistre l’heure de départ (tick()) et active running = true.

De la même façon, quand le joueur touche le bloc d’arrivée, le serveur envoie WinEvent, et le LocalScript reçoit ce signal pour arrêter le chrono (running = false).

Pendant que running est actif, la fonction RunService.Heartbeat recalcule et affiche le temps écoulé à chaque frame (60 fois par seconde environ).

La fonction formatTime transforme le nombre de secondes brut en un affichage lisible du type 01:23 (minutes:secondes).

En résumé : le serveur décide (quand démarrer/arrêter), les RemoteEvents transmettent l’info, et le LocalScript affiche le résultat à l’écran du joueur.

    Petit rappel pour bien comprendre

    • Script serveur : tourne sur l’ordinateur qui héberge la partie. Il contrôle les règles du jeu, mais ne peut pas modifier ce qui s’affiche à l’écran d’un joueur précis.
    • LocalScript : tourne uniquement sur l’ordinateur du joueur. Il gère l’affichage (interface, sons, caméra…) mais ne peut pas être utilisé pour des règles importantes du jeu (sinon un joueur pourrait tricher).
    • RemoteEvent : le « pont » entre les deux. Le serveur envoie une info avec FireClient(), et le LocalScript la reçoit avec OnClientEvent:Connect().

    QCM pour bien comprendre

    1. Où s’exécute un LocalScript ?
    A. Sur le serveur du jeu
    B. Sur l’ordinateur du joueur uniquement
    C. Sur tous les ordinateurs en même temps
    D. Nulle part, c’est juste un fichier texte

    2. Pourquoi ne peut-on pas modifier directement le TextLabel depuis le script serveur ?
    A. Parce que c’est interdit par Roblox
    B. Parce que le serveur n’a pas accès à l’affichage local de chaque joueur
    C. Parce que le TextLabel n’existe pas sur le serveur
    D. Parce que ça coûte trop cher en mémoire

    3. À quoi sert un RemoteEvent ?
    A. À supprimer un joueur du jeu
    B. À transmettre une information entre le serveur et un client
    C. À changer la couleur d’un bloc automatiquement
    D. À sauvegarder les données du joueur

    4. Que fait startEvent:FireClient(player) côté serveur ?
    A. Il supprime le joueur
    B. Il envoie un signal au client précis pour déclencher une action
    C. Il démarre le jeu pour tous les joueurs
    D. Il crée un nouveau RemoteEvent

    5. Que fait RunService.Heartbeat dans ce script ?
    A. Il vérifie les battements de cœur du joueur
    B. Il exécute du code à chaque frame, ici pour actualiser l’affichage du chrono
    C. Il redémarre le serveur régulièrement
    D. Il compte le nombre de joueurs connectés

    6. Que se passe-t-il si running vaut false ?
    A. Le chrono continue de s’incrémenter
    B. Le texte du chrono arrête de se mettre à jour
    C. Le joueur est téléporté au départ
    D. Le RemoteEvent est détruit

    Crée un part pour déterminer le départ du chrono et un part pour déterminer le stop du chrono.

    Puis deux RemoteEvent pour gérer le démarrage et l’arrêt du chrono :

    Puis script sur le serveur pour gérer les collisions entre le player et les parts de départ et d’arrivée :

    local replicatedStorage = game:GetService("ReplicatedStorage")
    local remoteEvent = replicatedStorage:WaitForChild("Coursetimecheck")
    
    local startEvent = remoteEvent.StartEvent
    local winEvent = remoteEvent.WinEvent
    
    local start = script.Parent.StartPart
    local succes = script.Parent.SuccessPart
    
    succes.SurfaceGui.Enabled = false
    succes.ParticleEmitter.Enabled = false
    
    succes.Anchored = true
    succes.CanCollide = true
    succes.CanTouch = true
    
    start.Anchored = true
    start.CanCollide = false
    start.CanTouch = true
    start.Transparency = 1
    
    succes.Touched:Connect(function(hit)
    	local character = hit.Parent
    	local humanoid = character and character:FindFirstChild("Humanoid")
    	if not humanoid then return end
    	if succes.SurfaceGui.Enabled then return end
    	
    	remoteEvent.WinEvent:FireClient(game.Players:GetPlayerFromCharacter(character))
    
    	succes.SurfaceGui.Enabled = true
    	succes.ParticleEmitter.Enabled = true
    end)
    
    start.Touched:Connect(function(hit)
    	local character = hit.Parent
    	local humanoid = character and character:FindFirstChild("Humanoid")
    	if not humanoid then return end
    	
    	local player = game.Players:GetPlayerFromCharacter(character)
    	if not player then return end -- sécurité si ce n'est pas un joueur (NPC par ex.)
    
    	print("StartEvent déclenché pour " .. player.Name)
    
    	startEvent:FireClient(player)
    	
    end)

    Et également un localScript pour l’affichage du chrono pour le joueur :

    -- Récupération des services
    local Players = game:GetService("Players")
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local RunService = game:GetService("RunService")
    
    -- Récupération du joueur actuel et de la PlayerGui
    local player = Players.LocalPlayer
    local playerGui = player:WaitForChild("PlayerGui")
    
    -- Récupération de l'UI du chrono
    local chrono = playerGui:WaitForChild("ScreenGui"):WaitForChild("Frame"):WaitForChild("ChronoLabel")
    
    -- Récupération des RemoteEvents start et stop du chrono
    local remoteEventsFolder = ReplicatedStorage:WaitForChild("Coursetimecheck")
    local startEvent = remoteEventsFolder:WaitForChild("StartEvent")
    local stopEvent = remoteEventsFolder:WaitForChild("WinEvent")
    
    -- Fonction pour formater le temps en minutes:secondes
    local function formatTime(t)
    	local minutes = math.floor(t / 60)
    	local seconds = math.floor(t % 60)
    	return string.format("%02d:%02d", minutes, seconds)
    end
    
    -- Variables globales pour suivre le temps et l'état du chrono
    local startTime = nil
    chrono.Text = "00:00"
    local running = false
    
    -- Connexion des événements serveur au client
    startEvent.OnClientEvent:Connect(function()
    	startTime = tick()
    	running = true
    end)
    
    stopEvent.OnClientEvent:Connect(function()
    	running = false
    end)
    
    -- Mise à jour continue de l'affichage du chrono
    RunService.Heartbeat:Connect(function()
    	if not running or not startTime then return end
    	chrono.Text = formatTime(tick() - startTime)
    end)