RBX:如何精确地让出/暂停脚本长达几毫秒?

问题描述 投票:0回答:1

好吧,基本上我有一个脚本,可以用像素(帧)在 SurfaceGui 上绘制 ECG,问题是,脚本运行速度非常慢,比预期慢两倍或三倍,就像当我需要脚本绘制某个特定内容时一样长度为 80 ms 的波,它会在 160 ms 或更长的时间内绘制它。

我想出了使用

os.clock()
来查看发生了什么,并发现
wait()
task.wait()
在非常短的等待时间(例如 1/60 秒)下变得非常不准确。

我尝试使用相同的

os.clock()
来准确测量时间。它在纸上工作得很好,但在实践中它使我的电脑滞后并不断导致
Script exhausted execution time
错误。我正在使用这个功能:

local function AccurateWait(time)
    local start = os.clock()
    while os.clock() - start < time do 
        -- Nothing
    end
end

现在我不知道该怎么办,这是完整的脚本,也许会有所帮助。我需要让脚本正好等待 1 帧(60 FPS)或 0.017 秒。

local leadFrame = script.Parent.blackBg.I_leadFrame
local leadFrameWidth = leadFrame.Size.X.Offset
local leadFrameUpdateTick = 1

local pixelSize = 2 -- def: 
local pixels = {}

local step = 3 -- DO NOT CHANGE THIS VALUE, def: 4

local colGreen = Color3.fromRGB(25, 255, 25)

local heartBPM = 60 / 60 * 1000 -- Will need it later, for now let it remain as 60

local linePosX = 0
local linePosY = 0
local linePosY_Scale = 0.5
local lineAccuracy = 16 -- def: 16
local lineReachedFrameWidth = false
local lineLoops = true
local lineClearanceOffset = 20
local lineClearing = false

local section = 0
local sectionInMS = 0
local sectionMaxWidth = 0

local wholeBeatLength = 0

local function DrawLine()
    if linePosX >= leadFrameWidth - pixelSize then
        if lineLoops then
            linePosX = 0
        end
        lineReachedFrameWidth = true
        return
    end
    
    if linePosX >= leadFrameWidth - pixelSize - lineClearanceOffset or lineClearing then
        lineClearing = true
        pixels[1]:Destroy()
        table.remove(pixels, 1)
    end
    
    if linePosY ~= linePosY then
        linePosY = 0
    end
    
    local pixel = Instance.new("Frame", leadFrame)
    pixel.Size = UDim2.new(0, pixelSize, 0, pixelSize)
    pixel.Position = UDim2.new(0, linePosX, linePosY_Scale, linePosY)

    pixel.BackgroundColor3 = colGreen
    pixel.BackgroundTransparency = 0
    pixel.BorderSizePixel = 0
    pixel.Name = "pixel"
    
    table.insert(pixels, pixel)
end

local function DrawP_Wave()
    local durationP_Wave = 80 -- In ms, assume it is normal duration at 60 bpm
    local durationPR_Segment = durationP_Wave + 40
    
    local startTime = os.clock()
    while sectionInMS < durationP_Wave do
        -- At these parameters length of P wave is 90 ms
        local A = 15 * step / 4 -- Scale of P wave, def: 15
        local B = 2.4 -- Width of P wave, def: 2.2 (the higher - the shorter)
        local C = 1.5 -- Can't describe, better not touch it, def: 1.5
        local D = 0.4 -- Height of P wave, def:
        local E = 1 -- Polarity of P wave, def: 1
        
        for i = 1, lineAccuracy do
            linePosY = -E * (A * D * math.sin(B * section / A))^C
            
            DrawLine()
            
            linePosX += step/lineAccuracy
            section += step/lineAccuracy
            sectionInMS = ((section/(60*step))*1000)
            
            if sectionInMS > durationP_Wave then
                break
            end
        end
        wait(1/60)
    end
    print("P wave: "..((os.clock()-startTime)*1000).." ms")
    
    while sectionInMS < durationPR_Segment do
        for i = 1, lineAccuracy do
            DrawLine()

            linePosX += step/lineAccuracy
            section += step/lineAccuracy
            sectionInMS = ((section/(60*step))*1000)
            
            if sectionInMS > durationPR_Segment then
                break
            end
        end
        wait(1/60)
        wholeBeatLength += 1/60*1000
    end
    print("PQ segment: "..((os.clock()-startTime)*1000).." ms")
    
    section = 0
    sectionInMS = 0
end

local function DrawQRS_Complex()
    local durationQRS_Complex = 90
    local durationST_Segment = 100 + durationQRS_Complex
    
    local startTime = os.clock()
    while sectionInMS < durationQRS_Complex do
        local A = 1.7 -- Width of QRS, def: 1.5 (the higher A - the shorter QRS)
        local B = 1.7 -- Height of QRS, def: 1.7
        local C = 3.6
        local D = 3.5
        local E = 5 -- def: 5
        local F = 1.1 -- Proportions of Q to S (bigger num -> deeper peak Q), def: 1.1
        local G = 15 * step / 4 -- Scale, def: 15
        
        for i = 1, lineAccuracy do
            linePosY = -G*((B*(math.sin(A/G * section))^E)^D-
                       (math.sin(A/G*F * section))^C)
            
            DrawLine()
            
            linePosX += step/lineAccuracy
            section += step/lineAccuracy
            sectionInMS = ((section/(60*step))*1000)
            
            if sectionInMS > durationQRS_Complex then
                break
            end
        end
        wait(1/60)
        wholeBeatLength += 1/60*1000
    end
    print("QRS complex: "..((os.clock()-startTime)*1000).." ms")
    
    while sectionInMS < durationST_Segment do
        for i = 1, lineAccuracy do
            DrawLine()

            linePosX += step/lineAccuracy
            section += step/lineAccuracy
            sectionInMS = ((section/(60*step))*1000)
            
            if sectionInMS > durationST_Segment then
                break
            end
        end
        wait(1/60)
        wholeBeatLength += 1/60*1000
    end
    print("ST segment: "..((os.clock()-startTime)*1000).." ms")
    
    section = 0
    sectionInMS = 0
end

local function DrawT_Wave()
    local durationT_Wave = 160
    
    local startTime = os.clock()
    while sectionInMS < durationT_Wave do
        local A = 1.1
        local B = 1.6
        local C = 3.6
        local D = 0.9
        local E = 5
        local F = 1.1
        local G = 15 * step / 4
        local H = 2.1
        
        for i = 1, lineAccuracy do
            linePosY = -G*((B*(math.sin(A/G * section))^E)^D-
                ((math.sin(A/G*F * section))^H)^C)
            
            DrawLine()
            
            linePosX += step/lineAccuracy
            section += step/lineAccuracy
            sectionInMS = ((section/(60*step))*1000)
            
            if sectionInMS > durationT_Wave then
                break
            end
        end
        wait(1/60)
        wholeBeatLength += 1/60*1000
    end
    print("T wave: "..((os.clock()-startTime)*1000).." ms")
    
    section = 0
    sectionInMS = 0
end

local function BreakBetweenBeats()
    local startTime = os.clock()
    while wholeBeatLength < heartBPM do
        for i = 1, lineAccuracy do
            DrawLine()

            linePosX += step/lineAccuracy
            section += step/lineAccuracy
            sectionInMS = ((section/(60*step))*1000)
        end
        wait(1/60)
        wholeBeatLength += 1/60*1000
    end
    print("Pause: "..((os.clock()-startTime)*1000).." ms")
    
    section = 0
    sectionInMS = 0
    wholeBeatLength = 0
end

while true do
    DrawP_Wave()
    DrawQRS_Complex()
    DrawT_Wave()
    BreakBetweenBeats()
end
print("ECG session has ended.")
lua wait roblox roblox-studio
1个回答
0
投票

只要使用task.wait() 为什么你想得太多

© www.soinside.com 2019 - 2024. All rights reserved.