Python pygame не будет перерисовываться после функции сортировки

#python #pygame #draw

#python #пигмеи #рисовать

Вопрос:

Я пытаюсь создать программу на python, чтобы нарисовать несколько столбцов, а затем отсортировать их от маленьких к большим. Рисование будет выполняться с помощью модуля pygame.

Программа работает до сих пор: с помощью клавиши c новый набор столбцов произвольной длины помещается в список. Это сразу видно в окне pygame. Если вы нажмете клавишу c более одного раза, в окне появятся новые столбцы, как и ожидалось.

С помощью клавиши s должна быть вызвана процедура сортировки, и после сортировки столбцы должны быть перерисованы в окне pygame. Такого перерисовывания из этой функции не происходит. Я попытался ввести несколько операторов печати (сейчас они закомментированы в коде), чтобы попытаться проследить за тем, что происходит. Это показывает, что существует какая-то сортировка, поскольку порядок столбцов в списке действительно меняется. Он только не будет печатать новый порядок в окне.

Код выглядит следующим образом:

 import pygame
import math
import random
from queue import PriorityQueue

WIDTH = 800
WIN = pygame.display.set_mode((WIDTH, WIDTH))
pygame.display.set_caption("Sorting Columns")

RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
TURQUOISE = (64, 224, 208)

class Column:
    def __init__(self, col, HIGHT, WIDTH, total_cols):
        self.col = col
        self.hight = HIGHT
        self.x = col * WIDTH
        self.y = WIDTH
        self.color = TURQUOISE
        self.neighbors = []
        self.WIDTH = WIDTH
        self.total_cols = total_cols

    def get_pos(self):
        return self.col

    def get_hight(self):
        return self.HIGHT

    def is_open(self):
        return self.color == GREEN

    def make_newcolumn(self):
        self.color = TURQUOISE

    def make_sorted(self):
        self.color = BLUE

    def update_neighbors(self, grid):
        pass

    def draw(self, win):
        pygame.draw.rect(win, self.color, (self.x, 800-self.hight, self.WIDTH, 800))

    def __lt__(self, other):
        return False


def sort_columns(draw, COLS, grid):
    for i in range(COLS):
        #print(grid[i].hight)
        count = i   1
        #print(count)
        #print(len(grid))
        #print(i)
        #print(COLS)
        #print(grid[(count)].hight)
        if count < len(grid):
            #print("nnn")
            #print(grid[i].hight)
            #print(grid[count].hight)
            if grid[i].hight > grid[count].hight:
                #print(grid[i].hight)
                #print(grid[count].hight)
                temp1 = grid[i]
                grid[i] = grid[count]
                grid[count] = temp1
                #print(grid[i].hight)
                #print(grid[count].hight)
                #print("hello")
                count  = 1
    for k in range(COLS):
        print(grid[k].hight)
            
    draw()

    return False
    


def make_cols(cols, WIDTH):
    columns = []
    gap = WIDTH // cols
    for i in range(cols):
        h = random.randrange(10, 790, 10)
        print(h)
        kolom = Column(i, h, gap, cols)
        columns.append(kolom)

    return columns


def draw_cols(win, cols, WIDTH):
    gap = WIDTH // cols
    for j in range(cols):
        pygame.draw.line(win, GREY, (j * gap, 0), (j * gap, WIDTH))


def draw(win, grid, cols, WIDTH):
    win.fill(WHITE)

    for Column in grid:
        Column.draw(win)

    draw_cols(win, cols, WIDTH)
    pygame.display.update()


def main(win, WIDTH):
    COLS = 5
    grid = make_cols(COLS, WIDTH)

    run = True
    while run:
        draw(win, grid, COLS, WIDTH)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    pass

                if event.key == pygame.K_c:
                    grid = make_cols(COLS, WIDTH)
                    draw(win, grid, COLS, WIDTH)

                if event.key == pygame.K_s:
                    print("n")
                    sort_columns(lambda: draw(win, grid, COLS, WIDTH),COLS, grid)
                    draw(win, grid, COLS, WIDTH)

    pygame.quit()

main(WIN, WIDTH)
 

Через лямбда-функцию в mainloop вызывается функция рисования.
У кого-нибудь есть какие-нибудь намеки, почему это не работает?

PS Я прекрасно понимаю, что функция сортировки далека от готовности, я работаю над этим. Будет полезно, если на графике будет показан порядок следования столбцов в списке, чтобы я мог продолжить работу над этим.

Ответ №1:

Вам нужно скопировать сетку вместо изменения исходной. Также list имеет встроенную функцию сортировки, которая может сортировать элементы на основе ключа. Вы также пытаетесь вызвать draw в функции сортировки. Это не сработает, потому что сортировка происходит только до тех пор, пока удерживается нажатой клавиша s.

И последнее, поскольку окно имеет размер 800 пикселей, оно исчезает с экрана, поэтому вы не можете видеть целые столбцы, что делает вещи странными.

 import pygame
import math
import random
from queue import PriorityQueue

WIDTH = 800
WIN = pygame.display.set_mode((WIDTH, WIDTH))
pygame.display.set_caption("Sorting Columns")

RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 255, 0)
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
TURQUOISE = (64, 224, 208)

class Column:
    def __init__(self, col, HIGHT, WIDTH, total_cols):
        self.col = col
        self.hight = HIGHT
        self.x = col * WIDTH
        self.y = WIDTH
        self.color = TURQUOISE
        self.neighbors = []
        self.WIDTH = WIDTH
        self.total_cols = total_cols

    def get_pos(self):
        return self.col

    def get_hight(self):
        return self.HIGHT

    def is_open(self):
        return self.color == GREEN

    def make_newcolumn(self):
        self.color = TURQUOISE

    def make_sorted(self):
        self.color = BLUE

    def update_neighbors(self, grid):
        pass

    def draw(self, win):
        pygame.draw.rect(win, self.color, (self.x, 800 - self.hight, self.WIDTH, 800))

    def __lt__(self, other):
        return False


def sort_columns(grid):
    grid.sort(key=lambda h: h.hight)
    return grid


def make_cols(cols, WIDTH):
    columns = []
    gap = WIDTH // cols
    for i in range(cols):
        h = random.randrange(10, 790, 10)
        kolom = Column(i, h, gap, cols)
        columns.append(kolom)

    return columns


def draw_cols(win, cols, WIDTH):
    gap = WIDTH // cols
    for j in range(cols):
        pygame.draw.line(win, GREY, (j * gap, 0), (j * gap, WIDTH))


def draw(win, grid, cols, WIDTH):

    for Column in grid:
        Column.draw(win)

    draw_cols(win, cols, WIDTH)
    pygame.display.update()


def main(win, WIDTH):
    COLS = 3
    grid = make_cols(COLS, WIDTH)
    grid_ = make_cols(COLS, WIDTH)
    run = True
    while run:
        win.fill(WHITE)
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_SPACE:
                    pass

                if event.key == pygame.K_c:
                    grid_ = make_cols(COLS, WIDTH)

                if event.key == pygame.K_s:
                    gird = sort_columns(grid)
                    grid_ = grid
                    
        draw(win, grid_, COLS, WIDTH)
                

    pygame.quit()

main(WIN, WIDTH)
 

Ответ №2:

pygame.draw.rect(win, self.color, (self.x, 800 - self.hight, self.WIDTH, 800))

Вы не обновили x. Несмотря Column на то, что s отсортированы в сетке, каждый Column из них перерисовывается в одном и том же месте.