pygame - 在 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 块,以解决表面错误(这似乎有效)。
解决方案
推荐阅读
- asp.net-mvc-4 - 视图模型中的 IFormfile 未绑定
- reactjs - 如何使用酶/Jest 测试 useState
- python - 如何在 Django 中添加 SQLServer 全文搜索?
- unity3d - 无法冻结具有平移功能的对象的旋转
- scala - 如何异步管理表单请求
- angular - 如何使用角度剑道限制日期选择器中的范围选择
- powershell - 为 IP 地址调用“解析”的异常 - 为什么?
- jenkins - 永久存储 Jenkins 工件的好位置是什么?
- javascript - 将反应调度箭头函数转换为 tyescript
- java - 客户端-服务器应用程序的 JPA 悲观锁逻辑