首页 > 解决方案 > 使用 Pygame 为网格中的正方形着色,但只能为第一个框着色,不知道该怎么做

问题描述

我一直在使用 pygame 尝试为我在某个网格中选择的框着色。当我用鼠标悬停在它上面并按键盘上的“s”时,该框应该是彩色的。唯一的问题是错误的框在网格中被着色。它总是第一个被着色的盒子,而不是我选择的那个。

当我将鼠标悬停在它上面并按“s”时,我选择的框应该变成绿色。

有人可以看看我的代码,看看我是否有明显的错误吗?在尝试调试了几个小时后,我似乎无法弄清楚出了什么问题。

类节点表示框,网格类表示包含节点的绘制网格。

这是我的 main.py 控制我的代码流:

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)

这是我的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()

这是我的 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

标签: pythonpygame

解决方案


您必须row分别column乘以node_margin而不是board_width在构造函数中Node

class Node:
    def __init__(self, color, row, column, node_margin, board_width):
        # [...]

        self.x = row * node_margin
        self.y = column * node_margin

推荐阅读