Bartłomiej 'furas' Burek
furas.pl
# prywatne notatki - Python, Linux, Machine Learning, etc.

PyGame: Przeciąganie obiektu po ekranie za pomocą myszy

Najpierw trzeba stworzyć obiekt do przesuwania (jego wielkość i pozycja jest w Rect()) oraz zmienną do przechowywania informacji czy obiekt jest przeciągany

rectangle = pygame.rect.Rect(176, 134, 30, 30)
rectangle_draging = False

Następnie należy użyć:

MOUSEBUTTONDOWN aby sprawdzić czy obiekt został kliknięty i ustawić drag = True i zapamiętać offset pomiędzy pozycją myszy a górny-lewym rogiem obiektu.

    elif event.type == pygame.MOUSEBUTTONDOWN:
        if event.button == 1:            
            if rectangle.collidepoint(event.pos):
                rectangle_draging = True
                mouse_x, mouse_y = event.pos
                offset_x = rectangle.x - mouse_x
                offset_y = rectangle.y - mouse_y

MOUSEBUTTONUP aby ustawić drag = False gdy obiekt zostanie puszczony

    elif event.type == pygame.MOUSEBUTTONUP:
        if event.button == 1:            
            rectangle_draging = False

MOUSEMOTION aby przesuwać obiekt gdy drag == True z użyciem pozycji myszy i offsetu.

    elif event.type == pygame.MOUSEMOTION:
        if rectangle_draging:
            mouse_x, mouse_y = event.pos
            rectangle.x = mouse_x + offset_x
            rectangle.y = mouse_y + offset_y

Działający przykład

import pygame

# --- constants --- (UPPER_CASE names)

SCREEN_WIDTH = 430
SCREEN_HEIGHT = 410
WHITE = (255, 255, 255)
RED   = (255,   0,   0)
FPS = 30

# --- main ---

# - init -

pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))

# - objects -

rectangle = pygame.rect.Rect(176, 134, 30, 30)
rectangle_draging = False

# - mainloop -

clock = pygame.time.Clock()

running = True

while running:

    # - events -

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        elif event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:            
                if rectangle.collidepoint(event.pos):
                    rectangle_draging = True
                    mouse_x, mouse_y = event.pos
                    offset_x = rectangle.x - mouse_x
                    offset_y = rectangle.y - mouse_y

        elif event.type == pygame.MOUSEBUTTONUP:
            if event.button == 1:            
                rectangle_draging = False

        elif event.type == pygame.MOUSEMOTION:
            if rectangle_draging:
                mouse_x, mouse_y = event.pos
                rectangle.x = mouse_x + offset_x
                rectangle.y = mouse_y + offset_y

    # - draws (without updates) -

    screen.fill(WHITE)
    pygame.draw.rect(screen, RED, rectangle)
    pygame.display.flip()

    # - constant game speed / FPS -

    clock.tick(FPS)

# - end -

pygame.quit()

Inne przykłady z wieloma kwadratami lub kołami i przyciskami (buttons) na GitHub: furas/python-examples/pygame/drag-rectangles-circles

Książki: python-dla-kazdego-podstawy-programowania python-wprowadzenie python-leksykon-kieszonkowy python-receptury python-programuj-szybko-i-wydajnie python-projekty-do-wykorzystania black-hat-python-jezyk-python-dla-hackerow-i-pentesterow efektywny-python-59-sposobow-na-lepszy-kod tdd-w-praktyce-niezawodny-kod-w-jezyku-python aplikacje-internetowe-z-django-najlepsze-receptury