Блокировка GUI сокета многопоточного клиента Pygame - PullRequest
0 голосов
/ 02 октября 2018

Я хочу написать игру гомоку с сервером и клиентом, терминальная версия работает хорошо, но версия 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}

  • В цикле:

    • парсинг пакета
    • проверить, находится ли gameover, если да, показать информацию о 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, а также в Pygame с сокетом. Я написал только что написанную часть Pygame, она хорошо работает, как и терминал + сокет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...