我不知道这是否真的适合你,但我在基于 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)
您必须在主循环中的每一帧调用协程。
那么,这就是如何使用那个大代码块了;
制作这样的动画:
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 秒。
您可以使用浮点数作为 WaitForSecond 的参数。
希望对你有帮助!