好吧,基本上我有一个脚本,可以用像素(帧)在 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.")
只要使用task.wait() 为什么你想得太多