编写了一个函数,该函数将在循环中左右移动矩形。 我希望它能以恒定的速度移动。实际发生的是运动粗糙。 机芯将改变其速度。 如何使其匀速运动?
def btn_start_press():
global x1, x2, y1, y2, canvas_width
size = int(entry_size.get())
x2 = x1 + size
y2 = y1 + size
label_size["text"] = size * 2
forward = True
while True:
if forward:
x1 += 1
x2 += 1
else:
x1 -= 1
x2 -= 1
if x2 + size >= canvas_width:
forward = False
elif x1 <= 0 :
forward = True
time.sleep(0.005)
canvas.coords(rect,x1,y1,x2,y2)
canvas.update()
答案 0 :(得分:2)
您的代码之外,计算机中发生了很多事情,这意味着您的代码并不是争夺资源的唯一方法。在您的情况下,最终结果是循环在每次迭代中花费的时间都不相同,因此最终成为锯齿状的运动。在您的情况下,睡眠时间也很短,以至于会占用大量时间分配给您的应用程序。
在这种情况下可能会起作用的幼稚修复方法是改为使用两次重绘之间的经过时间,并使用该时间来计算将按钮移动多远。
如果您使用time.sleep(0.015)
,则您的应用程序将尝试以75 fps的速度运行其代码(减去您花费在代码上的时间)。您可以使用time.time()
来获取当前时间(以毫秒为单位)。请注意,此时间信息可能很粗略,并且存在其他问题(例如,如果调整了计算机的时钟,则会发生变化)。有are better timers available,但对于此用例,它应该足够好。
pixels_per_second = 100
previous_time = time.time()
while True:
new_time = time.time()
elapsed = new_time - previous_time
pixels = pixels_per_second * elapsed
if forward:
x1 += pixels
x2 += pixels
else:
x1 -= pixels
x2 -= pixels
if x2 + size >= canvas_width:
forward = False
elif x1 <= 0 :
forward = True
previous_time = new_time
canvas.coords(rect,x1,y1,x2,y2)
canvas.update()
time.sleep(0.015)
答案 1 :(得分:1)
我猜这不是时机,而是可视化并不顺利。您是否尝试在没有可视化的情况下打印出步骤?
您正在尝试每秒更新您的画布200次。这似乎很多。我们看到了25-60 fps的平稳运动。
更新:
我确实需要动作要如此快,甚至更快。除了多次更新画布之外,是否有其他方法可以表示运动?
您仍然可以快速更改您的值,但是如果眼睛看不到任何差异,则无需进行如此频繁的视觉更新。您可以尝试在第10步更新框架。
但是更好的方法是运行计算和可视化异步处理,因为无论可视化需要多长时间,您可能想要的是步骤之间的固定时间。