使用for循环移动Pyglet精灵位置而非使用Pyglet时钟
我正在写我的第一个 pyglet 应用程序,用来可视化另一个脚本的计算结果。可惜我卡住了,不知道接下来该怎么做。
我想用一个循环把一个精灵从一个位置移动到另一个位置,所以在每次循环结束时,精灵的位置会根据上一个位置变化一个特定的距离,这个距离是循环计算出来的。
这是我正在写的代码的简化版本(希望这能帮助到有类似问题的人,然后我再复制我自己的具体项目)。
@window.event
def on_draw():
window.clear()
batch.draw()
def update(yd):
Ball.y += yd
distance = [2,1,3,-2,-3,2,4,-5,1,2,3,-4,3,5,2,-2,3,2,3,-2,]
### test update in loop ###
for i in distance:
time.sleep(0.1)
update(i)
### Run app ##
pyglet.app.run()
我不想使用 pyglet.clock.schedule_interval(update())
,因为循环的计算可能会比 clock.schedule
花更长的时间,这样移动就不会很流畅,但这没关系。
我遇到的问题是,在循环完成之前什么都不会发生,只有在 Python 完成循环后才会调用 pyglet.app.run()
,但是如果我在循环之前调用 pyglet.app.run()
,它只会在我关闭 pyglet 窗口后才运行循环。
1 个回答
1
在使用 pyglet
的时候,你并不能控制程序的主循环。
主循环是通过 pyglet.app.run()
启动的,你可以通过 window.event
装饰器来处理事件。
你在主循环启动之前运行你的循环,这就是为什么你会觉得什么都没有发生。
如果你想每0.1秒调用一次 update
,你应该使用 clock.schedule_interval
,这个方法需要一个要调用的函数和一个时间间隔参数。如果你想根据 distance
中的每个值移动你的精灵,你可以使用一个迭代器和一个嵌套函数,像这样:
def update():
g = iter(distance)
def inner():
try:
update(next(g))
except StopIteration:
pass
return inner
pyglet.clock.schedule_interval(update(), .1)
根据你的评论进行编辑:
给定你的循环:
for i in distance:
time.sleep(0.1)
update(i)
你可以把它变成一个迭代器:
def calculate():
for i in distance:
time.sleep(0.1) # just some expensive calculation
yield i
然后在 on_draw()
中使用它:
calc = calculate()
@window.event
def on_draw():
window.clear()
batch.draw()
try: update(next(calc))
except StopIteration: pass