Поверхность PyGame заблокирована во время блита - PullRequest
1 голос
/ 27 сентября 2019

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

 Traceback (most recent call last):
 File "/usr/lib/python3.7/threading.py", line 926, in _bootstrap_inner
 self.run()
 File "/usr/lib/python3.7/threading.py", line 870, in run
 self._target(*self._args, **self._kwargs)
 File ".../game.py", line 482, in runGame
 self.board.refresh()
 File ".../game.py", line 237, in refresh
 self.screen.blit(self.board_img, self.board_rect)

 pygame.error: Surfaces must not be locked during blit

При поиске я смог найти упоминания только о конкретных структурах PyGame, которые я не использую.Я использую только команду «pg.display.set_mode» для поверхности экрана, и изображение (с доски) на нем слипается, а остальная часть пользовательского интерфейса на изображении.Я попытался просто использовать unlock (), и попытался сделать некоторое время (surface.get_locked ()): surface.unlock (), но это ничего не изменило.

Изначально пользовательский интерфейс был перенаправлен наПоверхность экрана, но затем обновление не сработало (на изображении доски все еще был текст предыдущего кадра).

Базовая поверхность (дисплей) и основная поверхность (экран) и выполняются как:

    screen = pg.display.set_mode((W_SIZE, W_SIZE))
    self.board = Board(BOARD, screen, self.p1,
                       self.p2, self.SOCK)

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            if event.type == pg.MOUSEBUTTONDOWN:
                mouse_pos = event.pos

                self.board.move_piece(mouse_pos)

        self.board.refresh()
        pg.display.flip()
        clock.tick(60)

Функции обновления платы:

class Board():

...

def refresh(self):
    # Board
    self.screen.fill([161, 149, 109])
    self.screen.blit(self.board_img, self.board_rect) # Error line
    # This function is only for redrawing the same frame
...

def reload_bg(self):
    # Board
    self.screen.fill([161, 149, 109])
    self.board_img = pg.image.load(BOARD)
    self.board_img = pg.transform.scale(
        self.board_img, (W_SIZE, W_SIZE))
    self.screen.blit(self.board_img, self.board_rect)

    self.refresh() # Tried with and without this line

    # This function is used when new UI elements (text) are drawn,
      to "erase" the previous elements. The UI is blit using                                 
      self.board_img.blit(<UI text elements>)

Функция обновления пользовательского интерфейса представляет собой связку текста рендеринга + блиц, как это:

def updateUI(self):
    self.board.reload_bg()

    self.piece1_txt = self.scorefont.render(
        str(self.p1p), True, self.color1)
    self.board.board_img.blit(self.piece1_txt, (60, 550))

Буду признателен за любые предложения, решения ипонимание.Заранее спасибо:)

ОБНОВЛЕНИЕ: Я почти уверен, что это проблема в теме.У меня есть нить для связи через сокеты и другая для запуска игрового экземпляра Game.Когда сокет получает уведомление о движении противника, он вызывает функцию класса Game.played_piece (), которая пытается обновить доску с помощью функции updateUI.

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

...