0

我正在使用 pygame 构建一个国际象棋 gui,其中主游戏循环调用单独类中的一个方法(GameState 类中的移动),然后进一步调用同一类中的另一个方法(pawn_promotion)。在pawn_promotion 方法中,一个表面promotion_menu 被blit 到窗口中。

但它只出现在屏幕上一帧。如果我在这里错了,请纠正我,但我认为正在发生的是表面正在被 blit 但是当游戏循环再次迭代时,它会被棋盘覆盖到窗口上。

class GameWindow:
    def __init__(self):
        load()
        gs = GameState()
        m = MoveList
        run = True
        square_selected = ()
        clicks = []
        while run:
            win.blit(board_surface, (467, 132))
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    run = False
                if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_ESCAPE:
                        MainMenu()
                        run = False
                # Mouse ui
                if event.type == pygame.MOUSEBUTTONDOWN:  # checking for clicks
                    location = (pygame.mouse.get_pos()[0] - 467, pygame.mouse.get_pos()[1] - 132)
                    if 600 >= location[0] >= 0 and 600 >= location[1] >= 0:
                        column = location[0] // Square_size
                        row = location[1] // Square_size
                    # checking for repeat clicks
                        if square_selected == (row, column):
                            square_selected = ()
                            clicks = []  # if click is repeat, clear previous click
                        else:
                            # Player selects a square
                            square_selected = (row, column)
                            clicks.append(square_selected)

                        if len(clicks) == 2:
                            # second click moves the piece
                            self.move = m(clicks[0], clicks[1], gs.board)
                            gs.Move(self.move)
                            square_selected = ()
                            clicks = []
                            if gs.close_window:
                                run = False
class GameState:
...irrelavant code...
    def pawn_promotion(self, move):
        print(move.endrow, move.endcol)
        self.is_prmt = True
        promotion_menu = pygame.Surface((int(Square_size), int(Square_size * 4)))
        promotion_menu.fill(white)
        prmt_confirm = ''
        if self.white_turn:
            prmt_white_queen = Button(board_surface, (move.endcol + 1) * Square_size, 50, pieces_dict['wQ'], 1)
            prmt_white_rook = Button(board_surface, (move.endcol + 1) * Square_size, 50 + Square_size,
                                     pieces_dict['wR'], 1)
            prmt_white_knight = Button(board_surface, (move.endcol + 1) * Square_size, 50 + (2 * Square_size),
                                       pieces_dict['wN'], 1)
            prmt_white_bishop = Button(board_surface, (move.endcol + 1) * Square_size, 50 + (3 * Square_size),
                                       pieces_dict['wB'], 1)

            if self.run_promote_menu:
                print(self.run_promote_menu)
                board_surface.blit(promotion_menu, ((move.endcol + 1) * Square_size, (move.endrow * Square_size) + 50))
                prmt_queen = Button.draw(prmt_white_queen)
                prmt_rook = Button.draw(prmt_white_rook)
                prmt_knight = Button.draw(prmt_white_knight)
                prmt_bishop = Button.draw(prmt_white_bishop)

                if prmt_queen:
                    prmt_confirm = 'wQ'
                    # run_promote_menu = False
                if prmt_rook:
                    prmt_confirm = 'wR'
                    # run_promote_menu = False
                if prmt_knight:
                    prmt_confirm = 'wN'
                    # run_promote_menu = False
                if prmt_bishop:
                    prmt_confirm = 'wB'
                    # run_promote_menu = False
                for event in pygame.event.get():
                    if event.type == pygame.QUIT:
                        self.run_promote_menu = False
                        close_window = True
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_z:
                            self.run_promote_menu = False
                if prmt_confirm != '':
                    self.run_promote_menu = False
                    self.board[move.endrow][move.endcol] = prmt_confirm
                pygame.display.update()

我正在使用以下类在表面上创建 4 个按钮

class Button:
    def __init__(self, surface, x, y, image, scale):
        image_width = image.get_width()
        image_height = image.get_height()
        self.image = pygame.transform.scale(image, (int(image_width * scale), int(image_height * scale)))
        self.image_rect = image.get_rect(topleft=(x, y))
        self.surface = surface
        self.clicked = False
        self.image_bg = pygame.Surface((self.image_rect.width + 10, self.image_rect.height + 5))
        self.image_bg.set_alpha(0)

    def draw(self):
        action = False
        pos = pygame.mouse.get_pos()
        if self.image_rect.collidepoint(pos):
            self.image_bg.set_alpha(1)
            for event in pygame.event.get():
                if pygame.mouse.get_pressed()[0] == 1 and not self.clicked:
                    self.clicked = True
                    action = True
                if pygame.mouse.get_pressed()[1] == 0:
                    self.clicked = False
        else:
            self.image_bg.set_alpha(0)
        self.surface.blit(self.image_bg, (self.image_rect.x - 5, self.image_rect.y))
        self.surface.blit(self.image, (self.image_rect.x, self.image_rect.y))
        return action

我对这个类还有另一个小问题, set_alpha() 行似乎在每帧增加 alpha 的值,而不是将其设置为常数值。是否有另一个命令可以保持 alpha 不变?

如果我在 pawn_promotion 中使用 while 循环,它可以完美运行,但由于它本质上是两个嵌套的 while 循环,因此会产生很多滞后。我试图通过使用 clock.tick() 来减少这种滞后,但它并没有完全摆脱它。

4

0 回答 0