How to find the button on the entered position by user and change it's color in pygame?

Viewed 55
import pygame

pygame.init()

width = 800
height = 600
running = True
screen = pygame.display.set_mode((width, height))

def drawGrid():
    for y in range (50):
        for x in range (50):
            pygame.draw.rect (screen , ( 0 , 0 , 255 ) , ( ( x * 20 ) , ( y * 20 ) , 20 , 20 ) , 1)
        for event in pygame.event.get():    
            if event.type == pygame.MOUSEBUTTONUP:
                pos = event.pos
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
    screen.fill((0, 0, 0))
    drawGrid()
    pygame.display.update()

So I basically create a grid and I also figured out how to get the position at which the user clicks the screen. What I want to do now is that using the position which the user has clicked, I want to find the corresponding button at that location. Once I find which button corresponds to the position at which the user clicked, I want to then change the color of the button to something else.


Edit:

import pygame

pygame.init()

width = 800
height = 600
running = True
screen = pygame.display.set_mode((width, height))

cell_size = 20
size_x = width // cell_size
size_y = height // cell_size
grid = [[False for y in range(size_y)] for x in range(size_x)]

def drawGrid():
    mouse_pos = pygame.mouse.get_pos()
    for y in range (size_y):
        for x in range (size_x):
            # rectangle and color of cell
            cell_rect = pygame.Rect(x * 20, y * 20, 20, 20)           
            cell_color = (0, 0, 255)

            # change color of button if the mouse is on the button
            if cell_rect.collidepoint(mouse_pos):
                cell_color = (255, 255, 255)
            elif grid[x][y]:
                cell_color = (0, 255, 255)
            pygame.draw.rect(screen, cell_color, cell_rect, 1)   

z = 0

while running and z < 2:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            cell_x, cell_y = event.pos[0] // cell_size, event.pos[1] // cell_size
            grid[cell_x][cell_y] = not grid[cell_x][cell_y]
            z += 1
    screen.fill((0, 0, 0))
    drawGrid()
    pygame.display.update()

So basically what I want to do is that I want to stop clicking a rectangle in after two rectangles. So like if the user has already clicked two boxes (starting point and ending point), then I want to no longer add more boxes whenever the user clicks over a rectangle. I got it to work but the issue is that I only got it to work when two clicks are done the whole window closes. How can I fix this?

1 Answers

Never get the events (pygame.event.get()) multiple times in the application loop.

Use pygame.mouse.get_pos() to get the position of the mouse. Create a pygame.Rect object with the size of the cell and us collidepoint() to evaluate if the mouse is in the cell.

def drawGrid():

    # get current mouse position
    mosue_pos = pygame.mouse.get_pos()

    for y in range (50):
        for x in range (50):

            # rectangle and color of cell
            cell_rect = pygame.Rect(x * 20, y * 20, 20, 20)           
            cell_color = (0, 0, 255)

            # change color of button if the mouse is on the button
            if cell_rect.collidepoint(mosue_pos):
                cell_color = (255, 255, 255)

            pygame.draw.rect(screen, cell_color, cell_rect, 1)


If you want to change the cell on click, then you have to create a grid of states:

grid = [[False for y in range(size_y)] for x in range(size_x)]

Change the state of the cell when clicked on it:

if event.type == pygame.MOUSEBUTTONDOWN:
    cell_x, cell_y = event.pos[0] // cell_size, event.pos[1] // cell_size
    grid[cell_x][cell_y] = not grid[cell_x][cell_y]

Set the color dependent on the state of the cell:

if grid[x][y]:
    cell_color = (255, 255, 255)

See the example:

import pygame

pygame.init()

width = 800
height = 600
running = True
screen = pygame.display.set_mode((width, height))

cell_size = 20
size_x = width // cell_size
size_y = height // cell_size
grid = [[False for y in range(size_y)] for x in range(size_x)]

def drawGrid():

    for y in range(size_y):
        for x in range(size_x):

            # rectangle and color of cell
            cell_rect = pygame.Rect(x * 20, y * 20, 20, 20)           
            cell_color = (0, 0, 255)

            # change color of button if the mouse is on the button
            if grid[x][y]:
                cell_color = (255, 255, 255)

            pygame.draw.rect(screen, cell_color, cell_rect, 1)

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            cell_x, cell_y = event.pos[0] // cell_size, event.pos[1] // cell_size
            grid[cell_x][cell_y] = not grid[cell_x][cell_y]

    screen.fill((0, 0, 0))
    drawGrid()
    pygame.display.update()

If you want to prevent to select cells, after 2 boxes have been clicked, then you have to evaluate the number of selected cells in the MOUSEBUTTONDOWN event:

z = 0
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

        if event.type == pygame.MOUSEBUTTONDOWN:

            if z < 2:

                cell_x, cell_y = event.pos[0] // cell_size, event.pos[1] // cell_size
                grid[cell_x][cell_y] = not grid[cell_x][cell_y]
                z += 1 if grid[cell_x][cell_y] else -1

    # [...]
Related