首页 > 解决方案 > 相应地更新显示以使每帧产生函数

问题描述

我正在尝试使用我的算法上的 yield 函数来实现寻路算法可视化器,该函数在每次访问我的函数末尾的节点时都会产生访问节点的列表:

# Breadth First Search Algorithm
def bfs(graph, start, goal):
    explored = []

    # Queue for traversing the
    # graph in the BFS
    queue = [[start]]

    # If the desired node is
    # reached
    if start == goal:
        return

    # Loop to traverse the graph
    # with the help of the queue

    while queue:
        path = queue.pop(0)
        node = path[-1]
        y, x = node
        # Codition to check if the
        # current node is not visited

        if node not in explored and nodes_rows[x][y].color is not BLACK:

            neighbours = graph[node]

            # Loop to iterate over the
            # neighbours of the node
            for neighbour in neighbours:
                new_path = list(path)
                new_path.append(neighbour)
                queue.append(new_path)

                # Condition to check if the
                # neighbour node is the goal
                if neighbour == goal:
                    new_path.remove(start)
                    new_path.remove(goal)
                    return new_path

            explored.append(node)
            yield explored
    return None

nodes_rows[x][y].color is not BLACK- 避免墙壁颜色为黑色

我有一个主循环,可以在按下输入按钮时显示算法:

if event.key == pygame.K_RETURN:
    algorithm = bfs(neihgbours, (start[0]), (end[0]))
    ticks = None        

    try:
        while True:
            if not ticks or pygame.time.get_ticks() - ticks >= 500:
                ticks = pygame.time.get_ticks()
                nodes = next(algorithm)
                nodes_rows[nodes[-1][1]][nodes[-1][0]].color = LIGHT_BLUE
                pygame.display.update()
    except StopIteration:
        pass

nodes_rows[nodes[-1][1]][nodes[-1][0]].color = LIGHT_BLUE这个令人困惑的部分基本上是取列表中最后一个元素的行,然后是列表nodes[-1][1]中最后一个元素的列nodes[-1][0],然后在nodes_rows矩阵中它相应地更改节点颜色,列表由(行,列) 元组以便更好地说明。为了更好地表示,如果我打印nodes = next(algorithm)输出将如下所示:

[(7, 6)]
[(7, 6), (8, 6)]
[(7, 6), (8, 6), (6, 6)]
[(7, 6), (8, 6), (6, 6), (7, 5)]
[(7, 6), (8, 6), (6, 6), (7, 5), (7, 7)]
[(7, 6), (8, 6), (6, 6), (7, 5), (7, 7), (9, 6)]
...

我试图让算法每半秒为网格上的节点着色一个节点,如果我打印它,它确实适用于产量函数,它实际上确实每 0.5 个节点添加一个节点到访问的节点列表,但出于某种原因当我尝试更新屏幕并为它们着色时,它只是一次等待所有刻度和颜色的总数,而不是更多的动画外观。如何更新显示,以便在使用 yield 的算法函数结束时逐个节点而不是每个访问的节点着色?

为了更好地理解,这里是一次完成所有节点着色后网格的样子:

在此处输入图像描述

视频来表示过程中的算法:

https://cdn.discordapp.com/attachments/772816508015083552/832303260911272046/PowerPoint_-_1_2021-04-15_20-13-35_Trim.mp4

标签: pythonanimationpygamegrid

解决方案


您的事件循环或主游戏循环中不应有while循环。使用标志来指示是否更新算法:


algorithm = None
update_timer = 0
clock = pygame.time.Clock()

while running:
    dt = clock.tick()
    for event in pygame.event.get():
        # ... Other event handling
        if event.key == pygame.K_RETURN:
            algorithm = bfs(neihgbours, (start[0]), (end[0]))
            update_timer = 500 # To make sure we update first time

    update_timer += dt
    if algorithm and update_timer > 500:
        update_timer -= 500
        try:
            nodes = next(algorithm)
        except StopIteration:
            algorithm = None
        else:
            nodes_rows[nodes[-1][1]][nodes[-1][0]].color = LIGHT_BLUE
     
     # The actual rendering should happen here.


推荐阅读