I want to write a gomoku game with server and client. The terminal version works well, but pygame version just blocked and can't rend anything.
Here is the game execute function
First it start a socket connection
self._running = True
ininit
, package get from server is like{"grid":GRID(strings with 0 and 1), "x":X, "y":Y, "player":LAST_PLAYER, "next_player":CURRENT_PLAYER, "gameover":IS_GAMEOVER}
In the the loop:
- parse the package
- check if gameover, if so show information about gameover and close the socket
- if current player is me, call
on_event
and let user move( I suspect this step is wrong, so the parse package step blocked the main thread? But how should I fix this ) and then send the new move package to server - if current player is not me, then send a special package to server I am waiting(I know this is a bit stupid)
This is the loop like
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()
and the on_event
function be called in the middle to accepet user's next move
if data["gameover"] == -1:
if data["next_player"] != self.player:
...
else:
for event in pygame.event.get():
self.on_event(event)
code as this
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))
What I've tried:
I added a print in
on_event
print(event.type == pygame.MOUSEBUTTONUP)
and of courseMOUSEBUTTONUP
never happened(But I wonder why?)So I decide just skip this using random input
code as follows
#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))
The result is package goes all right BUT GUI still blocking and even I add sleep
in the while loop, it rended only when gameover
I am new in python multithread and also pygame with socket, I wrote a just pygame part it works good, so does terminal+socket.