Why is my mouse movement so sluggish/laggy?

Viewed 37

I am following a tutorial on YouTube for the GUI portion of a chess program in Python. However, whenever I drag a piece around the board, it feels very sluggish, as if the piece cannot keep up with the mouse's position.

At the start of the loop, I blit the background, and then I blit the pieces over the background. I then check if a piece is being dragged, if it is, we blit the piece icon.

  • I thought that here, I could try to update the mouse position before blitting, but it does not seem to work

Then we check the state of the mouse, if the mouse button is being pressed down, we update the mouse position, we then check if the clicked square has a piece, if it does, we save the initial position of the piece, set that as the active piece being dragged, and set dragging boolean to True.

If there is mouse motion and the dragging boolean is True, we update the position of the mouse, blit the bg, blit the other pieces, then blit the dragged piece icon.

Once the mouse is released, we set the boolean to False and clear the active dragging piece.

  • I think to many things are being blitted but I am not sure if there is anyway I can change the code without visual bugs

MAINLOOP


 def mainloop(self):

        game = self.game
        screen = self.screen
        drag = self.game.drag
        board = self.game.board

        while True:

            game.show_bg(screen)
            game.show_pieces(screen)

            if drag.dragging:
                drag.blit_icon(screen)

            for event in pygame.event.get():

                #  mouse click
                if event.type == pygame.MOUSEBUTTONDOWN:
                    drag.update_mouse(event.pos)

                    clicked_row = drag.mouseY // SQSIZE
                    clicked_col = drag.mouseX // SQSIZE


                    # does clicked square contain a piece
                    if board.squares[clicked_row][clicked_col].has_piece():
                        clicked_piece = board.squares[clicked_row][clicked_col].piece
                        drag.save_initial_pos(event.pos)
                        drag.drag_piece(clicked_piece)

                # mouse movement
                elif event.type == pygame.MOUSEMOTION:
                    if drag.dragging:
                        drag.update_mouse(event.pos)
                        game.show_bg(screen)
                        game.show_pieces(screen)
                        drag.blit_icon(screen)

                # click released
                elif event.type == pygame.MOUSEBUTTONUP:
                    drag.undrag_piece()

                # quit
                elif event.type == pygame.QUIT:
                    pygame.quit()
                    sys.exit()

            pygame.display.update()

DRAG CLASS

class Drag:

    def __init__(self):
        self.mouseX = 0
        self.mouseY = 0
        self.initial_row = 0
        self.initial_col = 0
        self.piece = None
        self.dragging = False

    def update_mouse(self, pos):
        self.mouseX, self.mouseY = pos  # (x,y)

    def save_initial_pos(self, pos):
        initial_row = pos[1] // SQSIZE
        initial_col = pos[0] // SQSIZE

    def drag_piece(self, piece):
        self.piece = piece
        self.dragging = True

    def undrag_piece(self):
        self.piece = None
        self.dragging = False

    def blit_icon(self, surface):
        img_center = self.mouseX, self.mouseY
        self.piece.texture_rect = self.piece.img.get_rect(center=img_center)
        surface.blit(self.piece.img, self.piece.texture_rect)

SHOW PIECES/BG

def show_bg(self, surface):

        for row in range(ROWS):
            for col in range(COLS):
                if (row + col) % 2 == 0:
                    color = (240, 236, 184)  # light squares
                else:
                    color = (75, 115, 153, 255)  # dark squares

                rect = (col * SQSIZE, row * SQSIZE, SQSIZE, SQSIZE)

                pygame.draw.rect(surface, color, rect)

    def show_pieces(self, surface):
        for row in range(ROWS):
            for col in range(COLS):
                if self.board.squares[row][col].has_piece():
                    piece = self.board.squares[row][col].piece

                    # make sure piece is not being dragged before blit
                    if piece is not self.drag.piece:
                        piece.img = pygame.image.load(piece.texture).convert_alpha()
                        img_center = col * SQSIZE + SQSIZE // 2, row * SQSIZE + SQSIZE // 2  # center y first, then x
                        piece.texture_rect = piece.img.get_rect(center=img_center)
                        surface.blit(piece.img, piece.texture_rect)
0 Answers
Related