Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

stopping a for loop?

Asked by
NotSoNorm 777 Moderation Voter
9 years ago

So this script needs to end the for loop after the calloff = true else statement, after it runs those ending lines, It still loops, How would I fix that from looping after 'else'?

        for racewait = 100, 0, -1 do
        if calloff == false then
            wait(1)
            game.Workspace.StartingLine.Timer.SurfaceGui.Time.Text = "Race time: "..racewait
                for _, Player in pairs(game.Players:GetChildren()) do
                    if Player:IsA("Player") then
                        Player.PlayerGui.MainGui.TimeFrame.Timer.Text = "Race time: "..racewait
                    end
                end
        else
                wait(3)
            game.Workspace.StartingLine.Timer.SurfaceGui.Time.Text = game.Workspace.Positions.First.Value.." has won!"
                for _, Player in pairs(game.Players:GetChildren()) do
                if Player:IsA("Player") then
                Player.PlayerGui.MainGui.TimeFrame.Timer.Text = game.Workspace.Positions.First.Value.." has won!"
            end
                end
                wait(2)
                            game.Workspace.StartingLine.Timer.SurfaceGui.Time.Text = game.Workspace.Positions.Second.Value.." came in 2nd"
                for _, Player in pairs(game.Players:GetChildren()) do
                if Player:IsA("Player") then
                Player.PlayerGui.MainGui.TimeFrame.Timer.Text = game.Workspace.Positions.Second.Value.." came in 2nd"
            end
                end
                wait(2)
                            game.Workspace.StartingLine.Timer.SurfaceGui.Time.Text = game.Workspace.Positions.Third.Value.." came in 3rd"
                for _, Player in pairs(game.Players:GetChildren()) do
                if Player:IsA("Player") then
                Player.PlayerGui.MainGui.TimeFrame.Timer.Text = game.Workspace.Positions.Third.Value.." came in 3rd"
                wait(2)
            end
        end
    end
1
You would use the break keyword to end a loop abruptly. FearMeIAmLag 1161 — 9y
0
thx NotSoNorm 777 — 9y

1 answer

Log in to vote
1
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

Cleaning Up

While it's OK when your code works, it's great when your code works and is elegant. This code can be significantly cleaned up.

First: tab your code correctly. This is so incredibly important!

Next: Use :GetPlayers() instead of :GetChildren(). This also obviates the need for the :IsA("Player") check.

Next: Notice that you have a big chunk of code that's repeated, and no functions! All good code uses functions!

Let's write a function to setText:

-- you can use `workspace` instead of `game.Workspace`

function setText(text)
    workspace.StartingLine.Timer.SurfaceGui.Time.Text = text
    for _, player in pairs(game.Players:GetPlayers()) do
        player.PlayerGui.MainGui.TimeFrame.Timer.Text = text
    end
end

Note that you're putting a lot of trust that this GUI actually exists, which won't be the case for players that are still joining. That's dangerous because you can get errors. You should probably use :FindFirstChild to check:

function setText(text)
    workspace.StartingLine.Timer.SurfaceGui.Time.Text = text
    for _, player in pairs(game.Players:GetPlayers()) do
        local playerGui = player:FindFirstChild("PlayerGui")
        if playerGui then
            local main = playerGui:FindFirstChild("MainGui")
            if main then
                local frame = main:FindFirstChild("TimeFrame")
                if frame and frame:FindFirstChild("Timer") then
                    frame.Timer.Text = text
                end
            end
        end
    end
end

This unfortunately gets a little long. If there's only one thing called Timer in the player we can also just use recursive search. That's good in that we can stop caring about how you organize GUIs in the player, but also bad for the same reason.

function setText(text)
    workspace.StartingLine.Timer.SurfaceGui.Time.Text = text
    for _, player in pairs(game.Players:GetPlayers()) do
        local timer = player:FindFirstChild("Timer", true)
        if timer then
            timer.Text = text
        end
    end
end

You can now use this function to make the rest of the code look trivial:

for racewait = 100, 0, -1 do
    if calloff == false then
        wait(1)
        setText("Race time: " .. racewait)
    else
        wait(3)
        setText(workspace.Positions.First.Value .. " has won!")
        wait(2)
        setText(workspace.Positions.Second.Value .. " came in 2nd")
        wait(2)
        setText(workspace.Positions.Third.Value .. " came in 3rd")
    end

Break

If you want to stop a loop, you use the break keyword:

for racewait = 100, 0, -1 do
    if calloff == false then
        wait(1)
        setText("Race time: " .. racewait)
    else
        wait(3)
        setText(workspace.Positions.First.Value .. " has won!")
        wait(2)
        setText(workspace.Positions.Second.Value .. " came in 2nd")
        wait(2)
        setText(workspace.Positions.Third.Value .. " came in 3rd")

        break
    end

    ... whatever other stuff
end

The fact that you're using "calloff" suggests that what you're doing is weird. Instead of using calloff, I suggest organizing it like this:

for time = 100, 0, -1 do
    wait(1)
    setText("Race itme:" .. time)
    if (race if over early) then
        break
    end
end
-- Announce winners always at end of race:
setText(workspace.Positions.First.Value .. " has won!")
wait(2)
setText(workspace.Positions.Second.Value .. " came in 2nd")
wait(2)
setText(workspace.Positions.Third.Value .. " came in 3rd")
Ad

Answer this question