Использование pygame.time.wait() между обновлениями дисплея
В настоящее время я разрабатываю простую анимацию Ханойской башни в Pygame, которая должна показывать правильное решение Ханойской башни, передвигаясь по одной части в секунду.
Однако, в моем алгоритме решения Ханоя я пытаюсь обновить отображение и использовать pygame.time.wait() после каждого движения; и вместо обновления одного движения и ожидания одной секунды, программа ожидает общее количество движений в секундах и затем отображает башню со всеми движениями, выполненными за один раз.
Что я хотел бы знать, так это то, что я неправильно использую функцию ожидания или в этой ситуации есть какая-то другая полезная функция, которую я упускаю.
Вот код:
def hanoi(n, origin, destination, aux):
# solves the game with n pieces
if n == 1:
positions[0] = destination
# updates and waits
printBackground()
printPieces(positions)
pg.time.wait(1000)
else:
hanoi(n-1, origin, aux, destination)
positions[n-1] = destination
#updates and waits
printBackground()
printPieces(positions)
pg.time.wait(1000)
hanoi(n-1, aux, destination, origin)
и цикл:
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
sys.exit()
if running:
hanoi(numPieces, 0, 2, 1)
running = False
Спасибо!
1 ответ
Вы должны отделить свой алгоритм от аспекта рисования вашего кода.
Простой способ обновить ваш код - использовать сопрограмму, которая на каждом этапе вашей рекурсии hanoi
функция возвращает управление главному циклу, который, в свою очередь, рисует экран, и возвращает управление hanoi
сопрограмма каждую секунду.
Вот упрощенный пример, который просто ведет обратный отсчет:
#-*- coding-utf8 -*-
import pygame
import pygame.freetype
pygame.init()
screen = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
font = pygame.freetype.SysFont(None, 30)
def hanoi(num):
# We calculated something and want to print it
# So we give control back to the main loop
yield num
# We go to the next step of the recursive algorithm
yield from hanoi(num-1) #
steps = hanoi(1000)
ticks = None
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
exit()
# step every second only
if not ticks or pygame.time.get_ticks() - ticks >= 1000:
ticks = pygame.time.get_ticks()
screen.fill((200, 200, 200))
# the value from the next step of the coroutine
value = str(next(steps))
# render stuff onto the screen
font.render_to(screen, (100, 100), value)
pygame.display.flip()
clock.tick(60)
В вашем коде вы должны заменить
# updates and waits
printBackground()
printPieces(positions)
pg.time.wait(1000)
с yield positions
вернуть контроль в основной цикл и
hanoi(n-1, aux, destination, origin)
с
yield from hanoi(n-1, aux, destination, origin)
держать сопрограмму и вызывать
...
screen.fill((200, 200, 200))
positions = next(steps)
printBackground()
printPieces(positions)
...
внутри if
в основном цикле.
(Если алгоритм закончится, он поднимет StopIterationException
который вы, вероятно, хотите поймать).