I'm new to pygame and I'm writing a program that allows the user to click and drag a rectangle around the pygame window, then sends it's coordinates through a socket. I can move the rectangle on mouse click, but I've been messing around with it for a while and still can't figure out how to implement click and drag. Any help would be appreciated. Here's the relevant code:
from pygame.locals import *
import socket, pygame, time
#define variables
x = y = 0
screen = pygame.display.set_mode((430, 410))
targetRectangle = pygame.draw.rect(screen, (255, 0, 0), (176, 134, 7, 7))
pygame.display.flip()
#define smaller functions
#define function to start pygame window
def startPygame():
pygame.display.set_caption(option + " Tracking System")
pygame.mouse.set_visible(True)
screen.fill((255, 255, 255))
targetRectangle = pygame.draw.rect(screen, (255, 0, 0), (176, 134, 7, 7))
pygame.display.flip()
#define function to update pygame window
def updateWindow():
screen.fill((255, 255, 255))
global targetRectangle
global xPosition
global yPosition
targetRectangle = pygame.draw.rect(screen, (255, 0, 0), (xPosition, yPosition, 7, 7))
pygame.display.flip()
#define main functions
def collectMouseData():
startPygame()
print "\n"
print "mouse tracking system"
#wait until a mouse button is clicked
running = 1
while running == 1:
event = pygame.event.poll()
if event.type == pygame.QUIT:
c.send("quit")
pygame.quit()
running = 0
#see if a mousebutton is down
elif event.type == pygame.MOUSEBUTTONDOWN:
xMouse = event.pos[0]
yMouse = event.pos[1]
#see if mouse click collides with targetRectangle
if targetRectangle.collidepoint(xMouse, yMouse):
global xPosition
xPosition = event.pos[0]
global yPosition
yPosition = event.pos[1]
updateWindow()
global targetRectangle
sendData(targetRectangle)
You have to use
MOUSEBUTTONDOWN
to check if object was clicked and set drag = True
(and remember offset between mouse position and rectangle top-left corner)MOUSEBUTTONUP
to set drag = False
MOUSEMOTION
to move object when drag == True
using mouse position and offset.Working example
import pygame
# --- constants --- (UPPER_CASE names)
SCREEN_WIDTH = 430
SCREEN_HEIGHT = 410
#BLACK = ( 0, 0, 0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
FPS = 30
# --- classses --- (CamelCase names)
# empty
# --- functions --- (lower_case names)
# empty
# --- main ---
# - init -
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
#screen_rect = screen.get_rect()
pygame.display.set_caption("Tracking System")
# - objects -
rectangle = pygame.rect.Rect(176, 134, 17, 17)
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
# - updates (without draws) -
# empty
# - 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()
EDIT: other examples with many rectangles or circles and buttons on GitHub:
furas/python-examples/pygame/drag-rectangles-circles
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With