I dont know if that is really a answer for you, but i used coroutine based animation system in my pygame based framework. And if you want to use it, you can make what you want with it.
Code is that:
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)
You must call Coroutines every frame in your mainloop.
Then, that is how to use that big code block;
Make animation like that:
def my_animation():
make_something()
yield WaitForSecond(1) # waits 1 second but not blocing your game or main loop
make_another_thing()
Then you can start that animation any time by writing that:
StartCoroutine(my_animation)
For example this code write "Hello" every second:
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.
But dont forget calling Coroutines every frame in your mainloop.
Also that won't work true:
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
If you use WaitForLoop(n) instead of WaitForSecond(n), that will wait n frame instead of waiting n second.
You can use floats as argument of WaitForSecond.
I hope that helps you!
self.draw_frame()do? How isdelete_ball_sequence()called? - Johnny Mopp