How to Fill a rectangle with color every time the user clicks it? pygame

Viewed 751

I know that there are several similar questions online, but none of them really helped me. I simply want to draw a grid and give the user the option to click into those grid cells. Every time the user clicks, the color/fill of the cell should change from black to white. What I'm doing at the moment is the following:

BLACK = (0, 0, 0)
WHITE = (200, 200, 200)

def drawGrid(h, w, blocksize):
    for x in range(w):
        for y in range(h):
            rect = pygame.Rect(x*blocksize, y*blocksize,
                               blocksize, blocksize)
            pygame.draw.rect(SCREEN, WHITE, rect, 1)


def handle_events():
    col = WHITE

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN:
                col = WHITE
                # determine mouse position
                mpos_x, mpos_y = event.pos
                # determine cell number
                coord = mpos_x // blocksize, mpos_y // blocksize

                rect = pygame.Rect(coord[0]*blocksize, coord[1]*blocksize, 
                                    blocksize, blocksize)
                pygame.draw.rect(SCREEN, col, rect, 1)
            pygame.display.update()

def main():

    global SCREEN, CLOCK, blocksize

    w = int( sys.argv[1] )
    h = int( sys.argv[2] )
    blocksize = int( sys.argv[3] )

    pygame.init()
    SCREEN = pygame.display.set_mode((h, w))
    CLOCK = pygame.time.Clock()
    SCREEN.fill(BLACK)
    
    drawGrid(h,w,blocksize)
    handle_events()
    
        


if __name__ == "__main__": 
    main()    

The program is printing the grid. However, when I click somewhere nothing happens. I know this is not the best code, so I would appreciate for any suggestion.

1 Answers

I changed the code a little and it worked properly, pygame.draw.rect(SCREEN, col, rect, 1) you draw same thing and you can't see the change. You should use pygame.draw.rect(SCREEN, col, rect):

import pygame
import sys

BLACK = (0, 0, 0)
WHITE = (200, 200, 200)
# WINDOW_HEIGHT = 400
# WINDOW_WIDTH = 400


def drawGrid(h, w, blocksize):
    #blockSize = 20 #Set the size of the grid block
    for x in range(w):
        for y in range(h):
            rect = pygame.Rect(x*blocksize, y*blocksize,
                               blocksize, blocksize)
            pygame.draw.rect(SCREEN, WHITE, rect, 1)


def handle_events():
    #coords_list = []
    col = WHITE

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            if event.type == pygame.MOUSEBUTTONDOWN:
                col = WHITE
                # determine mouse position
                mpos_x, mpos_y = event.pos
                # determine cell number
                coord = mpos_x // 32, mpos_y // 32

                rect = pygame.Rect(coord[0]*32, coord[1]*32, 
                                    32, 32)
                pygame.draw.rect(SCREEN, col, rect)
                #coords_list.append(coord)

            pygame.display.update()         

    #return coords_list

def main():

    global SCREEN, CLOCK, blocksize



    pygame.init()
    SCREEN = pygame.display.set_mode((480, 640))
    CLOCK = pygame.time.Clock()
    SCREEN.fill(BLACK)
    
    drawGrid(480,640,32)
    handle_events()
    
        


if __name__ == "__main__": 
    main()    

As a suggestion, I think you should use sprite for every cell. For example like this:

class Cell(pygame.sprite.Sprite):
    def __init__(self, sprite_group, x, y, cell_dimension, color=BLACK):
        self.groups = sprite_group
        pygame.sprite.Sprite.__init__(self, self.groups)
        self.image = pygame.Surface((cell_dimension, cell_dimension))
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.x = x * cell_dimension
        self.rect.y = y * cell_dimension
        
        self.clicked = False
    
    def update(self):
        if self.clicked:
            self.image.fill(WHITE)
Related