Я не знаю, если это действительно ответ для вас, но я использовал систему анимации на основе сопрограмм в моей основе на основе Pygame. И если вы хотите использовать его, вы можете сделать то, что вы хотите с ним.
Код таков:
from timeit import default_timer as timer
class GameEngineError(Exception): pass
coroutine_dict = {}
Coroutine_list = []
class WaitForLoop():
def __init__(self,number):
if number < 1:
number = 1
self.number = number
class WaitForSecond():
def __init__(self,time):
self.time = timer() + time
def StartCoroutine(generator,*args,**kwargs):
"""Starts generator function with args and kwargs"""
gen = generator(*args,**kwargs)
Coroutine_list.append(gen)
coroutine_dict[gen] = WaitForLoop(1)
def Invoke(f,time,*args,**kwargs):
"""Call f function or generator after time second(s) with args and kwargs"""
def Invoker():
yield WaitForSecond(time)
f(*args,**kwargs)
StartCoroutine(Invoker)
def Coroutines():
"""Call that per frame"""
global coroutine_dict
if len(Coroutine_list) != 0:
will_remove= []
for cor in Coroutine_list:
yielded = coroutine_dict[cor]
if type(yielded)==WaitForSecond:
if timer() >= yielded.time:
try:
new_yield = next(cor)
except StopIteration:
will_remove.append(cor)
else:
coroutine_dict[cor] = new_yield
elif type(yielded)==WaitForLoop:
yielded.number -= 1
if yielded.number==0:
try:
new_yield = next(cor)
except StopIteration:
will_remove.append(cor)
else:
coroutine_dict[cor] = new_yield
else:
raise GameEngineError("Type of coroutine yield must be WaitForSecond or WaitForLoop. Not "+str(type(yielded))+" . Check your generator definition which named '"+cor.__name__+"' .")
for i in will_remove:
Coroutine_list.remove(i)
coroutine_dict.pop(i)
Вы должны вызывать Coroutines каждый кадр в основном цикле. Затем, как использовать этот большой блок кода:
Сделать анимацию так:
def my_animation():
make_something()
yield WaitForSecond(1) # waits 1 second but not blocing your game or main loop
make_another_thing()
Затем вы можете запустить эту анимацию в любое время, написав:
StartCoroutine(my_animation)
Например, этот код пишет «Hello» каждую секунду:
def write_per_second(text):
while True:
print(text)
yield WaitForSecond(1) # waits 1 second but not blocing your game or main loop
StartCoroutine(write_per_second,"hello") # "hello" will be first -and only- argument of write_per_second.
Но не забывайте вызывать сопрограммы для каждого кадра в основном цикле.
Также это не сработает:
def write_per_second(text):
second = WaitForSecond(1) # that is invalid using. You should instance WaitForSecond when you are yielding it.
while True:
print(text)
yield second
Если вы используете WaitForLoop (n) вместо WaitForSecond (n), он будет ждать n кадров вместо ожидания n секунд. Вы можете использовать float в качестве аргумента WaitForSecond.
Надеюсь, это поможет вам!