Экран Pygame не обновляется после добавления каждого элемента - PullRequest
1 голос
/ 24 января 2020

Я пытаюсь добавить графику для моей простой программы решения судоку. Я хочу, чтобы программа обновляла отображаемую доску судоку в режиме реального времени по мере ее решения (я думал, что сделаю это, вызывая функцию draw_number после каждого правильно решенного числа, а затем задерживая программу, чтобы она рисовала число , пауза, затем продолжить решение.)

Однако вместо этого программа решает все это в процессе замораживания, а затем отображает все решение сразу, когда оно выполнено.

Вот небольшая пример того, что я пытаюсь сделать, который иллюстрирует проблему:

import pygame

pygame.init()
window = pygame.display.set_mode((600, 600))

board = [
    [1,2,3],
    [7,5,6],
    [4,9,8],
]    

def draw_number(r, c, num):

    font = pygame.font.Font('freesansbold.ttf', 26)
    text = font.render(str(num), True, (0, 0, 0), (255, 255, 255))

    text_rect = text.get_rect()
    text_rect.center = ((c+1)*48+11, (r+1)*48+11)
    window.blit(text, text_rect)
    print("Drawing " + str(num) + " at " + str(r+1) + ", " + str(c+1))
    pygame.display.update()

run = True
while run:
    for i in board:
        for j in range(0, 3):
            draw_number(board.index(i), j, board[board.index(i)][j])

            pygame.display.update()
            pygame.time.delay(20)
    run = False
    pygame.time.delay(5000)

Когда мы запускаем это, простая сетка 3x3 должна рисовать индивидуально, с паузами, но вместо этого она заканчивает циклы for, затем делает паузы на 5000 мс , затем показывает результат в течение доли секунды, а затем закрывает программу.

Я знаю, что я делаю что-то здесь не так, но я новичок в Pygame и не уверен, каков правильный способ сделать это.

Ответы [ 2 ]

1 голос
/ 24 января 2020

PyGame использует управляемую событиями модель для программ. Код должен никогда вызывать time.sleep() или pygame.time.delay() et c. потому что это приостанавливает программу. Если он приостановится достаточно долго, оконный менеджер сочтет, что программа перестала отвечать.

Простой способ обойти это - синхронизировать операции с pygame.time.get_ticks(), который возвращает все увеличивающееся количество миллисекунд с момента программа pygame началась. Разработайте свою программу так, чтобы она смотрела на часы, чтобы решить, что делать дальше.

Скажем, вы хотите выполнять операцию только каждые 3 секунды. Посмотрите на время запуска, выполните операцию, но затем больше ничего не делайте (кроме опроса событий и обновления экрана), пока не пройдет 3000 миллисекунд.

Например:

def doTheThing():
    pass  # TODO: some super-interesting function


time_we_did_the_thing = 0           # When did we last do the thing
clock   = pygame.time.Clock()
running = True
while running:
    # check for events
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            running = False

    # paint the screen
    screen.fill( ( 0, 40, 200 ) )  # bluish

    # Do the thing, but only every 3 seconds
    time_now = pygame.time.get_ticks()
    if ( time_now > time_we_did_the_thing + 3000 ):
        doTheThing()
        time_we_did_the_thing = time_now

    # flush the screen-updates
    pygame.display.flip()
    clock.tick_busy_loop(60)   # max FPS=60

pygame.quit()
1 голос
/ 24 января 2020

Проблема в том, что когда вы делаете pygame.time.delay (), он замораживает все окно pygame. Чтобы предотвратить это, вам нужно импортировать модуль времени и затем использовать time.sleep (секунды) вместо pygame.time.delay (). Вот некоторый код:

import pygame
import time

Затем (пропуская ненужные части):

run = True
while run:
    for i in board:
        for j in range(0, 3):
            draw_number(board.index(i), j, board[board.index(i)][j])
            time.sleep(5)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...