How To Click And Drag Objects In Pygame

Introduction

Being able to move items around the screen with the mouse adds an extra layer of input to a game or application and is easier to implement that it first seems.

The process can be broken down into these steps:

  1. Check if the mouse has been clicked
  2. Check if the mouse is positioned above one of the movable objects
  3. Detect mouse movement
  4. Use the mouse movement to move the object by the same amount.

We’ll go through each step below to put together the code, but first I need to create the individual movable objects.

Create a List of Rectangles

I’ll begin by creating a list of rectangles using random dimensions and positions to make them all different. Once created, these go into an overall list for easier access later.
				
					boxes = []
for i in range(5):
  x = random.randint(50, 700)
  y = random.randint(50, 350)
  w = random.randint(35, 65)
  h = random.randint(35, 65)
  box = pygame.Rect(x, y, w, h)
  boxes.append(box)
				
			

I also need to define a variable that tracks which (if any) of these boxes has been clicked on. I’ll set this variable to None to begin with.

				
					active_box = None
				
			

Check if The Mouse Has Been Clicked

This step can be done with pygame’s event handler, and will check for the MOUSEBUTTONDOWN event. I have covered these events in detail in another post, which you can check out here for a refresher.

We are specifically looking for a left click, so this is checked after the event is triggered.

				
					for event in pygame.event.get():
  if event.type == pygame.MOUSEBUTTONDOWN:
    if event.button == 1:
				
			

Check If the Mouse Is Positioned Above One Of The Objects

Next we need to check if the mouse is above one of the boxes that we created earlier. To do this, we expand the code from before to iterate through the boxes list. We use enumerate to track the index number of the boxes as we iterate through them.

As we do this, we check for collision with the mouse coordinates using the .collidepoint() method.

If a collision is detected, the active_box variable is updated with the index value of the box from the list.

				
					  for event in pygame.event.get():
    if event.type == pygame.MOUSEBUTTONDOWN:
      if event.button == 1:
        for num, box in enumerate(boxes):
          if box.collidepoint(event.pos):
            active_box = num
				
			

Detect Mouse Movement

This is done with another event, MOUSEMOTION. This event will trigger when the mouse is moved, and it returns a rel variable, which shows the distance in pixels that the mouse has moved.

				
					if event.type == pygame.MOUSEMOTION:
				
			

Move Object With Mouse

Now that mouse movement is being detected, we can use that to move the active box with the mouse. The above code can be updated like this:

				
					    if event.type == pygame.MOUSEMOTION:
      if active_box != None:
        boxes[active_box].move_ip(event.rel)
				
			

Line 2 checks that a box has been clicked on already and using the number of that box, we pick it out from the list and apply the move_ip() method to move it by the same amount as the mouse movement.

Check if The Mouse Has Been Released

Once all that is done, we need to check if the mouse button has been released so the box becomes deselected by setting the active_box variable back to None.

				
					    if event.type == pygame.MOUSEBUTTONUP:
      if event.button == 1:
        active_box = None
				
			

Pulling It All Together

We can pull all these sections of code together so the final code becomes:

				
					import pygame
import random

pygame.init()

#game window
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 450

screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption('Drag And Drop')

active_box = None
boxes = []
for i in range(5):
  x = random.randint(50, 700)
  y = random.randint(50, 350)
  w = random.randint(35, 65)
  h = random.randint(35, 65)
  box = pygame.Rect(x, y, w, h)
  boxes.append(box)

run = True
while run:

  screen.fill("turquoise1")

  #update and draw items
  for box in boxes:
    pygame.draw.rect(screen, "purple", box)

  for event in pygame.event.get():
    if event.type == pygame.MOUSEBUTTONDOWN:
      if event.button == 1:
        for num, box in enumerate(boxes):
          if box.collidepoint(event.pos):
            active_box = num

    if event.type == pygame.MOUSEBUTTONUP:
      if event.button == 1:
        active_box = None

    if event.type == pygame.MOUSEMOTION:
      if active_box != None:
        boxes[active_box].move_ip(event.rel)

    if event.type == pygame.QUIT:
      run = False

  pygame.display.flip()

pygame.quit()
				
			

Related Posts

3 thoughts on “How To Click And Drag Objects In Pygame

  1. Hi,
    is it possible that you create a Video about “localization”.
    How to translate text in the pygame for example from english to german, french, etc.
    So that if the game will started the game offer the language of the System is set to.

    And if the language is not available in the game that english is used for example.
    And my a malocalizationnual select option for the player to change the game language to a
    language that the gamer like

  2. Russ
    The moving boxes is a great help to many. I have been wondering if it is possible to move text across a screen. For example
    The quick _________ fox ____________ over ____ lazy dog

    Move the words brown lazy jumps
    into the spaces.

  3. Hi
    Can you make a video or something for ‘How to change the Recthangles in to pictures.’ because i do not know how to do it.

    Thank you
    WD

Leave a Reply

Your email address will not be published. Required fields are marked *