Home > Software engineering >  Mouse pos not lining up with grid
Mouse pos not lining up with grid

Time:09-03

This is my 2nd/3rd time making an array backed grid in pygame, that changes cell colour on click. However, despite using my previous code, I have been unable to figure out why my current code is not working.

The problem I am facing is that, when I click a cell on the grid, a totally different cell gets coloured and I cannot work out why or what the relation to these unexpected cells is. (I think it potentially seems to be that the coloured cell matches with what the grid coords are, but the mouse pos does not align to the correct grid coord (not confirmed))

For reference, 'pxl_size' is the height and width of a cell and 'pxls_width'/'pxls_height' is how many cells make up the width of the window.

My click detection code:

elif event.type == pygame.MOUSEBUTTONDOWN:
            column = mouse_pos[0] // (self.pixel_size   pixel_margin)
            row = mouse_pos[1] // (self.pixel_size   pixel_margin)

            print(row, column)
            if self.canvas.grid[row][column] != 1:
                self.canvas.grid[row][column] = 1
                colour = black
            
                self.canvas.update_pixel(row, column, colour)

My grid code:

class Canvas():
def __init__(self, pixel_size, screen):
    self.screen = screen

    self.pxl_size = pixel_size
    self.pxls_width = int(round(screen_width/self.pxl_size, 0))
    self.pxls_height = int(round(screen_height/self.pxl_size, 0))

    self.generate_canvas()

def generate_canvas(self):
    #Logical grid
    self.grid = []
    for row in range(self.pxls_height):
        self.grid.append([]) 
        for column in range(self.pxls_width):
            self.grid[row].append(0)

    self.canvas_surface = pygame.Surface((screen_width, screen_height))
    self.canvas_surface.fill(grey)

    #Visual grid
    for row in range (self.pxls_height):
        for column in range (self.pxls_width):
            self.update_pixel(row, column, white)
    
def update_pixel(self, row, column, colour):
    pygame.draw.rect(self.canvas_surface, colour, [(pixel_margin   self.pxl_size) * column   pixel_margin, 
                            (pixel_margin   self.pxl_size) * row   pixel_margin,
                            self.pxl_size,
                            self.pxl_size])

    self.screen.blit(self.canvas_surface, (0, 0))
    pygame.display.update()

Edit (additional info):

def __init__(self):
    global mouse_pos
    mouse_pos = pygame.mouse.get_pos()

    screen.fill(grey)
    self.pixel_size = 12
    
    self.canvas = Canvas(self.pixel_size, screen)

CodePudding user response:

You must determine the mouse position each time the button is clicked. The MOUSEBUTTONDOWN event has an attribute pos that specifies the position of the click:

for event in event_list:
    # [...]

    elif event.type == pygame.MOUSEBUTTONDOWN:
        column = event.pos[0] // (self.canvas.pxl_size   pixel_margin)
        row =    event.pos[1] // (self.canvas.pxl_size   pixel_margin)

        if self.canvas.grid[row][column] != 1:
            self.canvas.grid[row][column] = 1
            self.canvas.update_pixel(row, column, black)
  • Related