python - pygame 多线程客户端套接字 GUI 阻塞
问题描述
我想用服务器和客户端写一个五子棋游戏,终端版本很好,但是pygame版本刚刚被阻止,无法破解任何东西
这是游戏执行功能
首先它启动一个套接字连接
self._running = True
在init
,从服务器获取包就像{"grid":GRID(strings with 0 and 1), "x":X, "y":Y, "player":LAST_PLAYER, "next_player":CURRENT_PLAYER, "gameover":IS_GAMEOVER}
在循环中:
- 解析包
- 检查是否游戏结束,如果是,则显示有关游戏结束的信息并关闭套接字
- 如果当前玩家是我,调用
on_event
并让用户移动(我怀疑这一步是错误的,所以解析包步骤阻塞了主线程?但是我应该如何解决这个问题)然后将新的移动包发送到服务器 - 如果当前玩家不是我,则向我正在等待的服务器发送一个特殊包(我知道这有点愚蠢)
这是像这样的循环
while self._running:
data = self.client_thread.reply_q.get(True)
if data:
self.last_player = data["player"]
self.grid = self.grid_str_2_matrix(data["grid"])
self.lastPosition = [data["x"], data["y"]]
self.gomoku_board_init()
if data["gameover"] == -1:
if data["next_player"] != self.player:
self.client_thread.cmd_q.put(ClientCommand(ClientCommand.SEND, {"wait": True}))
print("waiting")
else:
for event in pygame.event.get():
self.on_event(event)
print("new move")
else:
print("game over")
self._running = False
if data["gameover"] == 0:
self.winner = 0
else:
self.winner = data["player"]
self.client_thread.cmd_q.put(ClientCommand(ClientCommand.CLOSE))
break
self.on_render()
self.on_cleanup()
并on_event
在中间调用该函数以接受用户的下一步动作
if data["gameover"] == -1:
if data["next_player"] != self.player:
...
else:
for event in pygame.event.get():
self.on_event(event)
像这样的代码
def on_event(self, event):
print(event.type == pygame.MOUSEBUTTONUP)
if event.type == pygame.MOUSEBUTTONUP:
pos = pygame.mouse.get_pos()
r = (pos[0] - PADDING + WIDTH // 2) // (WIDTH + MARGIN)
c = (pos[1] - PADDING + WIDTH // 2) // (WIDTH + MARGIN)
print(r, c)
if 0 <= r < self.board_row and 0 <= c < self.board_column and self.grid[r][c] == 0:
self.grid[r][c] = self.player
data = {"grid":self.grid, "x":r, "y":c, "player":self.player}
self.client_thread.cmd_q.put(ClientCommand(ClientCommand.SEND, data))
我试过的:
我添加了一个打印
on_event
print(event.type == pygame.MOUSEBUTTONUP)
,当然MOUSEBUTTONUP
从来没有发生过(但我想知道为什么?)所以我决定使用随机输入跳过这个
代码如下
#for event in pygame.event.get():
# self.on_event(event)
x, y = self.random_position()
self.grid[x][y] = self.player
data = {"grid":self.grid, "x":x, "y":y, "player":self.player}
self.client_thread.cmd_q.put(ClientCommand(ClientCommand.SEND, data))
结果是包一切正常,但GUI 仍然阻塞,甚至我sleep
在 while 循环中添加,它只在gameover
我是python多线程的新手,也是带socket的pygame,我写了一个pygame部分它工作得很好,终端+socket也是如此。
解决方案
推荐阅读
- vue.js - Vuetify / 离线图标
- android - UTM 和 Google 的 Firebase
- html - 使用 selenium 在本地 html 中为嵌套表抓取表
- r - 在 R 中,增加一个列表和增加一个向量一样低效吗?
- matlab - 函数句柄元胞数组的总和
- django - 添加指向自定义 django 管理视图的链接
- google-sheets - GAS:如何检查文件是否存在于特定文件夹中,如果存在则进行下一次迭代
- python - 检查索引处的numpy数组的值
- php - 如何为 Jetpack Lazyload 使用 apply_filter()
- c - 为什么这个检查一行是否是回文的程序会返回一个段错误?