В настоящее время я работаю над небольшой игрой на python и сейчас пытаюсь легко писать сценарии небольших игровых событий, диалогов и т. Д. На уровне. Тем не менее, я столкнулся с проблемой - как я могу это сделать, если она не будет ужасно грязной в тех случаях, когда я ожидаю завершения ранее инициированного события.
Рабочая система не использовала потоки, а вместо этого связывала цепочку обратных вызовов после завершения каждого события
def te2():
loadNewLevel(endLevel)
def textEnded():
labLabel.text = "Sadly, you must go The people must see what I have created!"
te = Character.TextEvent(1,5,labLabel, te2)
te.fire()
def labLoaded():
labLabel.text = "Ah, my son! Born without any natural parents! It worked!"
te = Character.TextEvent(1,5,labLabel, textEnded)
te.fire()
В этом примере labLoaded вызывается при загрузке уровня, а последним параметром для конструктора TextEvent является функция, которая будет вызываться только после завершения отображения TextEvent.
Это, очевидно, очень грязно, и на более сложном уровне, я думаю, это будет выглядеть серьезно. Потоки оказались очевидным следующим шагом, но потоки и opengl плохо сочетаются друг с другом.
Оптимально, можно написать сценарий для любого отдельного события (например, в данном случае загрузки уровня) в одной функции и вызвать что-то вроде te.waitUntilOut()
или, возможно, более реалистично waitForTextEvent(te)
.
Переход на что-то вроде asyncio кажется почти радикальным и, вероятно, потребует полной переделки всего моего существующего кода. Однако я не уверен, какие варианты у меня есть. Одна идея состоит в том, чтобы использовать yield
, чтобы разбить мои сценарии, а затем выполнить своего рода обратный вызов, как только что-то закончится. Это, однако, не очень читабельно, и я не думаю, что это целесообразно, но я не эксперт.