I been using pygame to try to color a box I choose in some grid. The box is supposed to be colored when I hover over it with my mouse and press ‘s’ on the keyboard. Only thing is that the wrong box is being colored in the grid. It is always the first box which is being colored and not the one I pick.
The box I choose is supposed to turn green when I hover over it and press ‘s’.
Can someone look at my code to see if I have an obvious mistake? I can’t seem to figure out what’s wrong after trying to debug it for hours.
The class node represents the boxes and the grid class represents the drawn grid that holds the nodes.
This is my main.py that controls the flow of my code:
import sys from grid import * # Window details height = 700 width = 700 window = pygame.display.set_mode((height, width)) window.fill(white) pygame.display.set_caption("Path Finding Visualizer") # Get the clicked position of the mouse to find the node def get_clicked_position(mouse_position, rows): node_margin = width // rows x, y = mouse_position row = x // node_margin column = y // node_margin return row, column # Code is controlled from here def main(window, width): # Initialize pygame pygame.init() # Create specific sized grid amount_of_rows = 20 amount_of_columns = 20 grid = Grid(amount_of_rows, amount_of_columns, window, width) grid_array = grid.draw_grid() # To keep the window running run = True while run == True: for event in pygame.event.get(): # User closes the window or something, end right away if event.type == pygame.QUIT: run = False # If a button is pressed if event.type == pygame.KEYDOWN: # User hovers over square and clicks 's' on the keyboard if event.key == pygame.K_s: mouse_position = pygame.mouse.get_pos() clicked_row, clicked_column = get_clicked_position(mouse_position, amount_of_rows) node = grid_array[clicked_row][clicked_column] node.set_start() grid_array[clicked_row][clicked_column] = node print(str(node.x) + ', ' + str(node.y)) # Update the grid with any new events grid.update_grid(grid_array) print("Set start") # User hovers over square and clicks 'e' on the keyboard if event.key == pygame.K_e: mouse_position = pygame.mouse.get_pos() clicked_row, clicked_column = get_clicked_position(mouse_position, amount_of_rows) node = grid_array[clicked_row][clicked_column] node.set_end() grid_array[clicked_row][clicked_column] = node # Update the grid with any new events grid.update_grid(grid_array) print("Set end") #pygame.display.update() main(window, width)
This is my grid.py:
from node import * class Grid: def __init__(self, number_of_rows, number_of_columns, window, window_width): self.number_of_rows = number_of_rows self.number_of_columns = number_of_columns self.window = window self.window_width = window_width # Initialize an empty list to represent the grid and then add nodes to it self.grid_list = [] # Initializes the grid by drawing it onto the screen and returns the grid's array that holds all of the nodes def draw_grid(self): self.draw_squares() self.draw_lines(1) pygame.display.update() return self.grid_list # Draw squares onto the screen def draw_squares(self): for row in self.grid_list: for node in row: pygame.draw.rect(self.window, node.color, (node.x, node.y, node.node_margin, node.node_margin)) # Draw the lines onto the screen def draw_lines(self, initial_grid=None): # Initialize the node's margin by doing integer division between the size of the window and amount of rows node_margin = self.window_width // self.number_of_rows # Kind of complicated but pretty much if the grid_array is empty then intialize it with this, else update the grid if(initial_grid != None): for x in range(self.number_of_rows): # For every row, a list will be appended to grid and add all of the columns and its respective nodes self.grid_list.append([]) # Draw the rows onto the window pygame.draw.line(self.window, grey, (0, x * node_margin), (self.window_width, x * node_margin)) for y in range(self.number_of_columns): # Initialize the node and make all nodes white. Then append to the row node = Node(white, x, y, node_margin, self.window_width) self.grid_list[x].append(node) # Draw the columns onto the window pygame.draw.line(self.window, grey, (y * node_margin, 0), (y * node_margin, self.window_width)) # Just draws the lines to update the grid since the grid is already initialized else: for x in range(self.number_of_rows): # Draw the rows onto the window pygame.draw.line(self.window, grey, (0, x * node_margin), (self.window_width, x * node_margin)) for y in range(self.number_of_columns): # Draw the columns onto the window pygame.draw.line(self.window, grey, (y * node_margin, 0), (y * node_margin, self.window_width)) # Every time an event occurs the grid will update the nodes that have been changed def update_grid(self, new_grid_list): self.grid_list = new_grid_list self.draw_squares() self.draw_lines() pygame.display.update()
This is my node.py:
import pygame # Board and path colors red = (255, 0, 0) green = (0, 255, 0) blue = (0, 0, 255) yellow = (255, 255, 0) white = (255, 255, 255) black = (0, 0, 0) purple = (128, 0, 128) orange = (255, 165, 0) grey = (128, 128, 128) turquoise = (64, 224, 208) # These are the squares that will be marked in the grid class Node: def __init__(self, color, row, column, node_margin, board_width): self.color = color self.row = row self.column = column self.board_width = board_width self.x = row * board_width self.y = column * board_width self.node_margin = node_margin # Returns position of node def get_position(self): return row, column # Checks if the node is the starting node for the search algorithm def is_start(self): if self.color == green: return True else: return False # Checks if the node is the ending node for the search algorithm def is_end(self): if self.color == red: return True else: return False # Resets the node to white to show nothing has happened to it def reset_node(self): self.color = white # Sets starting node to green def set_start(self): self.color = green # Sets starting node to red def set_end(self): self.color = red
Advertisement
Answer
You have to multiply row
respectively column
by node_margin
rather than board_width
in the constructor of Node
:
class Node: def __init__(self, color, row, column, node_margin, board_width): # [...] self.x = row * node_margin self.y = column * node_margin