unlucky_chap
unlucky_chap

Reputation: 73

Drawing a rectangle on mouse position in Python using pygame

I'm tryng to draw a rectangle on the mouse position on the screen when I press the left mouse button but I can't seem to make it work. Nothing happens when I press any mouse button. I've recently started using Python so can you please help?

Here's the game loop code...

game_over = False
while not game_over:

    mouse_pos = pygame.mouse.get_pos()

    for event in pygame.event.get():
        print(event)
        if event.type == pygame.QUIT:
            game_over = True
        if event.type == pygame.MOUSEBUTTONDOWN:
            pygame.draw.rect(display, rect_color, [mouse_pos[0], mouse_pos[1], rect_size, rect_size])
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                game_over = True

    display.fill(background_color)
    draw_grid()

    pygame.display.update()
    clock.tick(250)

pygame.quit()
quit()

Upvotes: 1

Views: 2080

Answers (2)

Rabbid76
Rabbid76

Reputation: 211219

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

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:

enter image description here

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()

Upvotes: 2

codingwith3dv
codingwith3dv

Reputation: 369

The problem lies in order of rendering You need to fill the screen with display.fill(bgColor) at the start of the loop.

And then you need to draw the grid and rectangle. Then after that you need to call pygame.display.update() and all the other stuff

Upvotes: 1

Related Questions