Programmer
Programmer

Reputation: 314

Blit surface on pygame display depending on mouse position

in this program I have a surface that has a grid on it. I'm trying to make a program that detects mouse position on surface and if my mouse is in one of the squares, the square turns green. The problem is that I've managed to get only 1 square working. I want all of the squares work like the one in upper left corner. Can anyone help?

import pygame
pygame.init()

WIDTH = 540
TILESIZE = 60
RED = (255, 0, 0)
BLACK = (0, 0, 0)
GREY = (211, 211, 211)
GREEN = (0, 255, 0)


win = pygame.display.set_mode((WIDTH+1, WIDTH+1))
win.fill(GREY)
surface = pygame.Surface((TILESIZE-1, TILESIZE-1))
surface.fill(RED)

def mouse_pos():
    surface_place = (1, 1)
    for x in range(0, 9, TILESIZE):
        for y in range(x):
            surface_place = list(surface_place)
            surface_place[0] += TILESIZE
            surface_place[1] += TILESIZE
            surface_place = tuple(surface_place)
            win.blit(surface, surface_place)

    if surface.get_rect().collidepoint(pygame.mouse.get_pos()):
        win.blit(surface, surface_place)
        surface.fill(GREEN)
    else:
        win.blit(surface, surface_place)
        surface.fill(RED)

def draw_grid():
    for x in range(0, WIDTH+1, TILESIZE):
        pygame.draw.line(win, BLACK, (x, 0), (x, WIDTH))
    for y in range(0, WIDTH+1, TILESIZE):
        pygame.draw.line(win, BLACK, (0, y), (WIDTH, y))

clicked = False
while not clicked:
    draw_grid()
    mouse_pos()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            clicked = True

    pygame.display.update()

Upvotes: 4

Views: 163

Answers (1)

sloth
sloth

Reputation: 101042

There are of course multiple solutions to this.

One is to range/loop over WIDTH, like you do to draw the grid, and use some Rect-magic to draw the tile green or red, like this:

def mouse_pos():
    for x in range(1, WIDTH+1, TILESIZE):
        for y in range(1, WIDTH+1, TILESIZE):
            rect = pygame.Rect(x, y, TILESIZE, TILESIZE).inflate(-1, -1)
            win.fill(GREEN if rect.collidepoint(pygame.mouse.get_pos()) else RED, rect)

Here we start the loop at 1 instead of 0 and shrink the rect by 1 pixel, using inflate, so we don't paint over the grid lines.

But what solution is right for you depends on what your trying to achieve in the end. Like, do you need a logical representation of your grid in your code? To you need to work with Surfaces instead of just filling a solid color?

Upvotes: 3

Related Questions