Python pygame 在排序函数后不会重绘

问题描述

我正在尝试用python制作一个程序来绘制一些列,然后将它们从小到大排序。 绘图将使用 pygame 模块完成。

该程序目前有效: 使用 c-key 将一组新的随机长度列放置在列表中。这在 pygame 窗口中立即可见。当您多次按下 c 键时,窗口将显示新列,正如预期的那样。

使用 s-key 必须调用排序例程,并且在排序后必须在 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)
GREEN = (0,255,0)
BLUE = (0,0)
WHITE = (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("\n\n\n")
            #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),WIDTH))


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

    for Column in grid:
        Column.draw(win)

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


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

    run = True
    while run:
        draw(win,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,WIDTH)

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

    pygame.quit()

main(WIN,WIDTH)

通过主循环中的 lambda 函数调用 draw 函数。 任何人都暗示为什么这不起作用?

附言我很清楚排序功能还远未准备好,我正在努力。 如果图形能够显示列列表的顺序会很有帮助,这样我就可以继续。

解决方法

您需要复制网格而不是修改原始网格。 list 也有一个内置的排序功能,可以根据键对元素进行排序。您还试图在排序功能中调用 draw。这行不通,因为排序只会在按住 s-key 时发生。

最后一件事,因为窗口是 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)
GREEN = (0,255,0)
BLUE = (0,0)
WHITE = (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),WIDTH))


def draw(win,grid,WIDTH):

    for Column in grid:
        Column.draw(win)

    draw_cols(win,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)
,

pygame.draw.rect(win,800))

您还没有更新 x。尽管 Column 在网格中排序,但每个 Column 都会在同一位置重绘。