Draw Shapes With The Mouse In Pygame By albro

When we press the mouse buttons, events such as MOUSEBUTTONDOWN and MOUSEBUTTONUP are generated. First of all, let's detect these events in our game loop and print a message on the console if they exist!
code>for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEBUTTONDOWN:
print(event)
elif event.type == MOUSEBUTTONUP:
print(event)
Now, if I left-click or right-click in the game window, the following events will be generated immediately and will be printed on the console.
<Event(1025-MouseButtonDown {'pos': (53, 53), 'button': 1, 'touch': False, 'window': None})>
<Event(1026-MouseButtonUp {'pos': (53, 53), 'button': 1, 'touch': False, 'window': None})>
<Event(1025-MouseButtonDown {'pos': (546, 249), 'button': 3, 'touch': False, 'window': None})>
<Event(1026-MouseButtonUp {'pos': (546, 249), 'button': 3, 'touch': False, 'window': None})>
Mouse movement in the game window causes the MOUSEMOTION event. So I can also add the following code to the program!
elif event.type == MOUSEMOTION:
print(event)
Draw a rectangle with mouse movement
I want to use mouse events to draw the rectangle. At the beginning, let's have an understanding of the process. As I said before, we need a display object and a color to draw a rectangle. Then we must have the upper-left corner point of the rectangle and its width and height. So, when the mouse is pressed in a point, the coordinates of that point in the window can be considered as the starting point of the drawing. Mouse movement determines the size of the rectangle. As soon as the mouse is released at an endpoint, I can calculate the size and draw the rectangle. So I need all three events above. I need a flag with a default value of False to tell if I'm drawing or not. In addition, I need another variable called size.
Let's first define the following four variables.
start = (0, 0)
size = (0, 0)
drawing = False
When the mouse is pressed, we must put the current position in the start and end variables and change the value of the drawing to True. This means we are drawing!
elif event.type == MOUSEBUTTONDOWN:
start = end = event.pos
size = (0, 0)
drawing = True
When the mouse button is released, I set the end value to the position of that point and return the drawing value to False to indicate that the drawing is finished.
elif event.type == MOUSEBUTTONUP:
if(event.pos[1]>start[1]):
end = event.pos
else:
start = event.pos
size = (end[0] - start[0], end[1] - start[1])
drawing = False
Finally, we need to check whether we are drawing or not when the mouse is moving. If the answer is yes, then let's use the current position as the end point:
elif event.type == MOUSEMOTION and drawing:
if(event.pos[1]>start[1]):
end = event.pos
else:
start = event.pos
size = (end[0] - start[0], end[1] - start[1])
One thing that should be noted and can be seen in the code above is that to calculate the size of the rectangle, it is enough to subtract the width and height coordinates. So when I want to calculate the width of the rectangle, it is enough to subtract the X coordinate value of the starting pont from the X coordinate value of the current point. I will also get help from the Y coordinate for the height!
At the end of the work, I draw the rectangle.
screen.fill(GRAY)
pygame.draw.rect(screen, RED, (start, size), 2)
pygame.display.update()
In fact, after all the events are over, I tell Pygame to do the drawing now!
import pygame,sys
from pygame.locals import *
RED = (255, 0, 0)
GRAY = (127, 127, 127)
pygame.init()
screen = pygame.display.set_mode((640, 400))
pygame.display.set_caption('Draw Shapes')
start = (0, 0)
size = (0, 0)
drawing = False
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEBUTTONDOWN:
start = end = event.pos
size = (0, 0)
drawing = True
elif event.type == MOUSEBUTTONUP:
if(event.pos[1]>start[1]):
end = event.pos
else:
start = event.pos
size = (end[0] - start[0], end[1] - start[1])
drawing = False
elif event.type == MOUSEMOTION and drawing:
if(event.pos[1]>start[1]):
end = event.pos
else:
start = event.pos
size = (end[0] - start[0], end[1] - start[1])
screen.fill(GRAY)
pygame.draw.rect(screen, RED, (start, size), 2)
pygame.display.update()
pygame.quit()
Now if I run the above code, pressing and releasing each of the mouse buttons will create something like the following:

Draw several rectangles with the mouse
If I want to draw multiple rectangles, I need to have a list to hold the rectangles!
rect_list = []
Now, in the previous code, when the mouse button is released, I need to create a rectangle object and add it to the list:
elif event.type == MOUSEBUTTONUP:
if(event.pos[1]>start[1]):
end = event.pos
else:
start = event.pos
size = (end[0] - start[0], end[1] - start[1])
rect = pygame.Rect(start, size)
rect_list.append(rect)
drawing = False
Then after I've painted the background, I need to draw the objects using a loop and finally draw the current rectangle in blue!
screen.fill(GRAY)
for rect in rect_list:
pygame.draw.rect(screen, RED, rect, 3)
pygame.draw.rect(screen, BLUE, (start, size), 1)
pygame.display.update()
So I have:
import pygame,sys
from pygame.locals import *
RED = (255, 0, 0)
BLUE = (0, 0, 255)
GRAY = (127, 127, 127)
pygame.init()
screen = pygame.display.set_mode((640, 400))
pygame.display.set_caption('Draw Shapes')
start = (0, 0)
size = (0, 0)
drawing = False
rect_list = []
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == MOUSEBUTTONDOWN:
start = end = event.pos
size = (0, 0)
drawing = True
elif event.type == MOUSEBUTTONUP:
if(event.pos[1]>start[1]):
end = event.pos
else:
start = event.pos
size = (end[0] - start[0], end[1] - start[1])
rect = pygame.Rect(start, size)
rect_list.append(rect)
drawing = False
elif event.type == MOUSEMOTION and drawing:
if(event.pos[1]>start[1]):
end = event.pos
else:
start = event.pos
size = (end[0] - start[0], end[1] - start[1])
screen.fill(GRAY)
for rect in rect_list:
pygame.draw.rect(screen, RED, rect, 3)
pygame.draw.rect(screen, BLUE, (start, size), 1)
pygame.display.update()
pygame.quit()

Draw a polygon with the mouse
To draw a polygon we need to add all the points to an array of points. First, we define an array called points and a drawing flag:
drawing = False
points = []
In the following code for handling the MOUSEBUTTONDOWN event, we add the current point to the array and set the drawing flag to True:
elif event.type == MOUSEBUTTONDOWN:
points. append(event.pos)
drawing = True
When the MOUSEBUTTONUP event occurs, we disable the drawing flag:
elif event.type == MOUSEBUTTONUP:
drawing = False
If the flag is set, and the MOUSEMOTION event occurs, we move the last point from the polygon list:
elif event.type == MOUSEMOTION and drawing:
points[-1] = event.pos
If there are more than 2 points in the points array, we draw a green border line for the polygon. A polygon is drawn inside this line. Calling the pygame.draw function returns a Rect or bounding rectangle for the polygon. This rectangle encloses the polygon. We display this rectangle in green.
screen.fill(GRAY)
if len(points)>1:
rect = pygame.draw.lines(screen, RED, True, points, 3)
pygame.draw.rect(screen, GREEN, rect, 1)
pygame.display.update()
Pressing the ESCAPE key removes the last dot in the array:
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
if len(points) > 0:
points.pop()
So
import pygame,sys
from pygame.locals import *
RED = (255, 0, 0)
GREEN = (0, 255, 0)
GRAY = (150, 150, 150)
pygame. init()
screen = pygame.display.set_mode((640, 240))
drawing = False
points = []
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
elif event.type == KEYDOWN:
if event.key == K_ESCAPE:
if len(points) > 0:
points.pop()
elif event.type == MOUSEBUTTONDOWN:
points.append(event.pos)
drawing = True
elif event.type == MOUSEBUTTONUP:
drawing = False
elif event.type == MOUSEMOTION and drawing:
points[-1] = event.pos
screen.fill(GRAY)
if len(points)>1:
rect = pygame.draw.lines(screen, RED, True, points, 3)
pygame.draw.rect(screen, GREEN, rect, 1)
pygame.display.update()
pygame.quit()











Comments