首页 > 解决方案 > 在 blit 期间锁定 PyGame 表面

问题描述

我正在使用 PyGame 在 python3 上为基于 Go 的 2 玩家套接字编写代码。在我的电路板更新功能期间,我收到消息说屏幕表面在 blit 期间不能被锁定(在应该将电路板背景图像blit到屏幕上的行中)。

 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”命令,并将一个图像(板的)blitted 到它上面,而 UI 的其余部分 blit 到图像上。我尝试只使用unlock(),并尝试做一段时间(surface.get_locked()):surface.unlock(),但它没有改变任何东西。

UI 最初是 blit 到屏幕表面上的,但后来更新不起作用(板图像上仍然有前一帧文本)。

基础表面(显示器)和主表面(屏幕)并运行为:

    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>)

UI 更新功能是一堆文本渲染 + blit 像这样:

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 函数更新棋盘。

我假设另一个线程正在调用实例化对象的函数这一事实导致访问表面的并发性。目前,我的解决方案是在一个 while 循环内尝试 catch 块,以解决表面错误(这似乎有效)。

标签: pygamepygame-surface

解决方案


推荐阅读