我正在使用PyGame为基于python3的Go的2播放器套接字编写代码。在开发板的更新功能期间,我得到一条消息,即在发白期间不得锁定屏幕表面(在应该将发板背景图像发到屏幕的行中)。
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”命令,将(板的)图像涂抹在屏幕上,而将UI的其余部分涂抹在图像上。我只是尝试使用unlock(),并尝试了一段时间(surface.get_locked()):surface.unlock(),但它没有任何改变。
UI最初是在屏幕表面上模糊化的,但是随后更新不起作用(面板图像上仍保留有前一帧文字)。
基础表面(显示)和主表面(屏幕),运行方式为:
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循环中尝试try catch块以消除表面错误(看来可行)。