Pygame Drawing a Rectangle

Pygame not drawing rectangle while clicking

To make the rectangle permanent, you need to draw the rectangle in the application loop. The event occurs only once in a single frame. Add a variable clicked = False. Set the variable when the event occurs. And draw the rectangle dependent on the state of the variable:

clicked = False
while True:

screen.fill(background)

mouse = pygame.mouse.get_pos()
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
if 10 <= mouse[0] <= 10 + 180 and 10 <= mouse[1] <= 10 + 190:
clicked = True
line_color = (212, 212, 255)
draw_line()
highlight()
if clicked:
pygame.draw.rect(screen,background,(10,10,180,190))
pygame.display.update()

Simplify your code:

  • Create a list of pygame.Rect objects for the rectangles

    rect_list = [pygame.Rect(10, 10, 180, 190), ...]
  • Create a list for the stated of the fields

    clicked_list = [0 for _ in rect_list]
  • Use collideponit to test if the mouse is on a rectangle:

    for rect in rect_list:
    if rect.collidepoint(mouse):
    pygame.draw.rect(screen, hover_color, rect)
  • Use collidepoint to evaluate whether a field is clicked and to change the state of the field

    if ev.type == pygame.MOUSEBUTTONDOWN:
    for i, rect in enumerate(rect_list):
    if rect.collidepoint(ev.pos):
    clicked_list[i] = 1
  • Draw the field in a loop depending on its state:

    for i, rect in enumerate(rect_list):
    if clicked_list[i]:
    pygame.draw.rect(screen,background,rect)

Complete code:

import pygame
pygame.init()

res = (600,600)
screen = pygame.display.set_mode(res)
pygame.display.set_caption("Tic Tac Toe")

background = (255,150,150)
color_light = (170,170,170)
color_dark = (100,100,100)
hover_color = (255, 204, 203)
width = screen.get_width()
height = screen.get_height()

def draw_line():

pygame.draw.rect(screen, line_color, (190,10,10,580))
pygame.draw.rect(screen, line_color, (390, 10, 10, 580))
pygame.draw.rect(screen, line_color, (10, 200, 580, 10))
pygame.draw.rect(screen, line_color, (10, 390, 580, 10))

rect_list = [
pygame.Rect(10, 10, 180, 190),
pygame.Rect(200, 10, 180, 190),
pygame.Rect(400, 10, 180, 190),
pygame.Rect(10, 210, 180, 190),
pygame.Rect(200, 210, 180, 190),
pygame.Rect(400, 210, 180, 190),
pygame.Rect(10, 400, 180, 190),
pygame.Rect(200, 400, 180, 190),
pygame.Rect(400, 400, 180, 190)]
clicked_list = [0 for _ in rect_list]

def highlight():
for rect in rect_list:
if rect.collidepoint(mouse):
pygame.draw.rect(screen, hover_color, rect)

while True:
mouse = pygame.mouse.get_pos()
for ev in pygame.event.get():
if ev.type == pygame.QUIT:
pygame.quit()
if ev.type == pygame.MOUSEBUTTONDOWN:
for i, rect in enumerate(rect_list):
if rect.collidepoint(ev.pos):
clicked_list[i] = 1

line_color = (212, 212, 255)
screen.fill(background)
draw_line()
highlight()
for i, rect in enumerate(rect_list):
if clicked_list[i] == 1:
pygame.draw.rect(screen,background,rect)
pygame.display.update()

How can i draw rectangles in multiple rows and columns in pygame?

Use nested loops:

no_of_rows = 8
no_of_cols = 8

x0, y0 = 20, 20 # just for example
dx, dy = 70, 16 # just for example

for row in range(no_of_rows):
for col in range(no_of_cols):
pygame.draw.rect(screen1, brick_colors[b], (x0 + col*dx, y0 + row*dy, 60, 12))

I recommend making a list of the block locations and drawing the block rectangles from the locations in the list. If a block is destroyed, all you have to do is remove the location from the list:

blocks = []
for row in range(no_of_rows):
for col in range(no_of_cols):
blocks.append((x0 + col*dx, y0 + row*dy))
for pos in blocks:
pygame.draw.rect(screen1, brick_colors[b], (pos[0], pos[1], 60, 12))

This can be further improved by using pygame.Rect objects:

blocks = []
for row in range(no_of_rows):
for col in range(no_of_cols):
rect = pygame.Rect(x0 + col*dx, y0 + row*dy, 60, 12)
blocks.append(rect )
for rect in blocks:
pygame.draw.rect(screen1, brick_colors[b], rect )

If you want to draw checkered tiles overall the screen, the draw the tiles on a background surface before the application loop and blit the background surface on the screen in the application loop for best performance.

Sample Image

import pygame

screen = pygame.display.set_mode([500, 500])
clock = pygame.time.Clock()

background = pygame.Surface(screen.get_size())
color1 = (64, 64, 128)
color2 = (196, 128, 64)
sx, sy = 50, 50
for i in range((screen.get_width() + sx -1) // sx):
for j in range((screen.get_height() +sy - 1) // sy):
c = color1 if (i+j) % 2 == 0 else color2
pygame.draw.rect(background, c, (i*sx, j*sy, sx, sy))

run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False

screen.blit(background, (0, 0))

pygame.display.update()

pygame.quit()

Drawing a rectangle on mouse position in Python using pygame

You have to manage the rectangles in a list. Crate a list for the positions of the rectangles:

pos_list = []

Add a new position to the list when clicked with the mouse:

for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.MOUSEBUTTONDOWN:
pos_list.append(event.pos)

After you clear the display and before you update the display, draw the rectangles in a loop at the positions stored in the list:

display.fill(background_color)
for x, y in pos_list:
pygame.draw.rect(display, rect_color, (x, y, rect_size, rect_size))
pygame.display.update()

Minimal example

Sample Image

import pygame

pygame.init()
display = pygame.display.set_mode((300, 300))
clock = pygame.time.Clock()
rect_color = "red"
rect_size = 40

pos_list = []
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
pos_list.append(event.pos)

display.fill(0)
for x, y in pos_list:
pygame.draw.rect(display, rect_color, (x, y, rect_size, rect_size))
pygame.display.update()
clock.tick(60)

pygame.quit()
exit()

If you want to align the rectangles on a grid, you have to calculate the row and column depending on the mouse position:

if event.type == pygame.MOUSEBUTTONDOWN:
col = event.pos[0] // rect_size
row = event.pos[1] // rect_size
pos_list.append((col, row))

Minimal example:

Sample Image

import pygame

pygame.init()
display = pygame.display.set_mode((320, 320))
clock = pygame.time.Clock()
rect_color = "red"
rect_size = 40

background = pygame.Surface(display.get_size())
ts, w, h, c1, c2 = 40, *display.get_size(), (32, 32, 32), (64, 64, 64)
tiles = [((x*ts, y*ts, ts, ts), c1 if (x+y) % 2 == 0 else c2) for x in range((w+ts-1)//ts) for y in range((h+ts-1)//ts)]
for rect, color in tiles:
pygame.draw.rect(background, color, rect)

pos_list = []
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONDOWN:
col = event.pos[0] // rect_size
row = event.pos[1] // rect_size
pos_list.append((col, row))

display.blit(background, (0, 0))
for col, row in pos_list:
pygame.draw.rect(display, rect_color, (col*rect_size, row*rect_size, rect_size, rect_size))
pygame.display.update()
clock.tick(60)

pygame.quit()
exit()

Pygame doesn't draw rectangles on the screen after a specific threshold

If data['n'] is greater than SCREEN_W, RECT_W is 0. A coordinate is truncated when drawing. You cannot draw a fraction of a pixel. The size of the rectangle can only be integral (0, 1, 2 ...). Hence, you cannot draw a rectangle with a size less than 1.

You can draw the rectangles on a large surface and scale down the surface. However, the rectangles get blurred. So, this is no good option.

How to draw rectangle and circles in Pygame environment

You have to create a pygame.Surface, instead of creating a new window (pygame.display.set_mode).

The pixel format of the Surface must include a per-pixel alpha (SRCALPHA). The center point of the circle must be the center of the Surface. The radius
must be half the size of the Surface:

self.image = pygame.Surface((size, size), pygame.SRCALPHA)
radius = size // 2
pygame.draw.circle(self.image, color, (radius, radius), radius)

Class Object:

class Object(pygame.sprite.Sprite):

def __init__(self, position, color, size, type):

# create square sprite
pygame.sprite.Sprite.__init__(self)

self.image = pygame.Surface((size, size), pygame.SRCALPHA)
self.rect = self.image.get_rect()

if type == 'agent':
self.image.fill(color)
else:
radius = size // 2
pygame.draw.circle(self.image, color, (radius, radius), radius)

# initial conditions
self.start_x = position[0]
self.start_y = position[1]
self.state = np.asarray([self.start_x, self.start_y])
self.rect.x = int((self.start_x * 500) + 100 - self.rect.size[0] / 2)
self.rect.y = int((self.start_y * 500) + 100 - self.rect.size[1] / 2)


Related Topics



Leave a reply



Submit