Pyglet перемещает позицию спрайта из цикла for вместо использования часов pyglet

Я пишу свое первое приложение pyglet, чтобы визуализировать некоторые вычисления, которые делает другой скрипт. К сожалению, я застрял и не могу понять, куда идти дальше.

Я пытаюсь переместить спрайт из его положения в другое положение с помощью цикла for, поэтому в конце каждого цикла он меняет положение спрайта относительно старого положения на определенное расстояние, рассчитанное циклом.

Это упрощенная версия кода, который я пишу (надеюсь, это поможет другим с похожей проблемой, а затем скопирует мой собственный конкретный проект).

@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.schudule, движение не будет плавным, но это нормально.

У меня проблема в том, что ничего не происходит, пока цикл не завершится, только после того, как python пройдёт цикл, он вызывает pyglet.app.run(), но если я вызову pyglet.app.run() перед циклом, он запустит цикл только после того, как я закрою окна pyglet.


person user2879397    schedule 11.06.2014    source источник
comment
разве вы не должны запускать on_draw() в цикле или в обновлении?   -  person el3ien    schedule 11.06.2014
comment
@ EL3PHANTEN нет, pyglet — это среда, управляемая событиями, и on_draw неоднократно вызывается самим pyglet, когда основной цикл был запущен с app.run().   -  person sloth    schedule 11.06.2014


Ответы (1)


При использовании pyglet вы не контролируете основной цикл программы.

Основной цикл запускается pyglet.app.run(), и вы можете подключиться к событиям с помощью декоратора window.event.

Вы запускаете свой цикл до запуска основного цикла. Вот почему кажется, что ничего не происходит.

Если вы хотите вызывать update каждые 0,1 секунды, вам следует использовать 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
person sloth    schedule 11.06.2014
comment
поэтому я вызываю pyglet.clock.schedule_interval() внутри своего цикла? моя проблема в том, что я не знаю, сколько времени потребуется для расчета цикла, в конце цикла у меня есть переменная со временем, которое потребовалось для расчета, и рассчитанным расстоянием. по этой причине я пытаюсь вызвать update() как последнюю строку цикла - person user2879397; 11.06.2014
comment
в цикле в вопросе я поставил это time.sleep(0.1) для имитации времени, которое требуется для расчета цикла, внутри цикла гораздо больше кода, который не имеет отношения к вопросу о поросенке. - person user2879397; 11.06.2014
comment
@user2879397 user2879397 Может быть, я неправильно понял вашу проблему. Итак, у вас есть цикл, и в этом цикле вы хотите выполнить затратные вычисления, а затем обновить позицию спрайта несколько раз? Если это так, вы можете использовать ту же технику (используя итератор) и просто использовать ее в on_draw(). Я обновлю свой ответ. - person sloth; 11.06.2014
comment
Я понял, думаю, вызовите update(), который я сделал в вопросе, в событии on_draw(), он работает. Происходит что-то очень странное, цикл останавливается в каком-то случайном месте и продолжается только тогда, когда я перемещаю мышь внутри окна pyglet. может быть, это должны быть другие вопросы? - person user2879397; 11.06.2014