使用 while 循环在 Roblox Lua 中制作秒表

我正在制作一款 Roblox 游戏,我想要它有一个秒表。秒表能够工作,但是由于某些原因它计数得非常缓慢。 以下是我在 StarterGui 中的 ScreenGui: ScreenGui stopwatch

以下是 LocalScript 中的代码:

local timer = script.Parent.Timer
local tms = 00
local ts = 00
local tm = 00
local tt
local tts
local y = 0
local whichtower = game.Players.LocalPlayer:FindFirstChild("WhichTower")
while true do
    wait(0.01)
    if whichtower.Value == "" then
        tms = 00
        ts = 00
        tm = 00
        tts = 0
    else
        tms = tms + 1
        if tms == 100 then
            ts = ts + 1
            tms = 0
            tts = tts + 1
            if ts == 60 then
                tm = tm + 1
                ts = 0
            end
        end
        tt = tostring(tm)..":"..tostring(ts)..":"..tostring(tms)
        timer.Text = tt
        game.Players.LocalPlayer:FindFirstChild("Time").Value = tt
    end
end
点赞
用户2474008
用户2474008
任意的wait()和循环可能导致时间问题,虽然我看不出有什么具体的原因可能会导致它变慢。你确定 WHichTower 上的 FindFirstChild 总是会返回结果吗?在那里添加一个print语句,这样你就可以在调试窗口中获得一系列的值,并确认它是否找到了一个合适的塔。

此外,只有当有塔时才会更新文本;对于你将值设为0的代码,没有计时器.Text更新。

但如果你认为那不是问题:

我建议将你的代码放在一个心跳事件函数中,定期调用并绑定到刷新速率上(我想是这样的)。然后你就不需要while循环和wait()命令了。心跳事件只会以与刷新速率相同的速度运行,因此,没有必要比屏幕更新速度更快的运行任何东西,因为屏幕不会更新。

local lPlayers = game:GetService("Players") local lRunSvc = game:GetService("RunService")

local function onPlayerAdded(pPlayer) -- pPlayer (变量名由您决定)是加入玩家的引用。 print(pPlayer.Name .. " 加入了游戏。")

lRunSvc.Heartbeat:Connect(function()

    print("whichtower.value is:" .. whichtower.Value) -- 在输出控制台中查看打印信息
    if whichtower.Value == "" then
        tms = 00
        ts = 00
        tm = 00
        tts = 0
    else
        tms = tms + 1
        if tms == 100 then
            ts = ts + 1
            tms = 0
            tts = tts + 1
            if ts == 60 then
                tm = tm + 1
                ts = 0
            end
        end
        tt = tostring(tm)..":"..tostring(ts)..":"..tostring(tms)
        timer.Text = tt
        game.Players.LocalPlayer:FindFirstChild("Time").Value = tt
    end
end)

end

lPlayers.PlayerAdded:Connect(onPlayerAdded) -- 玩家加入时调用 ```

2021-01-16 15:54:11
用户2860267
用户2860267

正如 Vexen Crabtree 所指出的,wait() 实际暂停脚本的时间基于系统时钟对经过时间的最佳猜测。与毫秒计数不同,计算经过时间的更可靠方法是使用 tick() 函数。

tick() 会给出当前时代时间,即自 1970 年 1 月 1 日以来经过的毫秒数。

因此,如果你知道起始时间,你可以从当前时间中减去它并得到经过的毫秒数。这种方法不依赖循环时间,并且将给出更准确的经过时间。你选择的 wait() 的时间只会反映值更新的速度。

local timer = script.Parent.Timer
local whichtower = game.Players.LocalPlayer:FindFirstChild("WhichTower")
local playerTime = game.Players.LocalPlayer:FindFirstChild("Time")

local startingTime = 0
local isTiming = false

-- 附加一个监听器以知道何时启动时钟
whichTower.Changed:Connect(function(newValue)
    -- 当值为空时重置时钟为零
    isTiming = newValue ~= ""

    if not isTiming then
        startingTime = 0
    else
        -- 开始时钟!
        startingTime = tick()
    end
end)

local refreshTime = 0.01
while true do
    wait(refreshTime)

    if isTiming then
        -- 计算经过的时间
        local ms = tick() - startingTime

        -- 计算经过的分钟数
        local tm = ms - (ms % (60 * 1000))
        ms = ms - tm
        tm = tm / 1000

        -- 计算经过的秒数
        local ts = ms - (ms % 1000)
        ms = ms - ts
        ts = ts / 1000

        -- 格式化余数
        local tms = ms / 1000
        if #tostring(tms) > 2 then
            tms = string.sub(tostring(tms), 3)
        else
            tms = "0"
        end

        -- 格式化时间为 mm:ss.ss 例如) 123:01.123
        local tt = string.format("%.2d:%.2d.%s", tm, ts, tms)

        timer.Text = tt
        playerTime.Value = tt
    end
end
2021-01-17 00:42:55
用户13591145
用户13591145

我使用了另一组代码解决了这个问题。Roblox将等待参数限制在最小0.3秒,因此我的先前代码无法工作。

如果你正在看这个问题,请使用 task.wait(time)

2022-04-16 19:51:01