首页 > 解决方案 > pygame中带有慢速动画的寻路模拟

问题描述

我正在尝试创建一个寻路表示(使用 Dijkstra)。我的图形工作方式如下:

    def run_visuals(self):
    """
    runs the visuals in a loop
    """
    run = True
    self.draw_grid()
    while run:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                run = False

            elif event.type == pygame.MOUSEBUTTONDOWN:  # mouse click
                x, y = event.pos
                row = x // BLOCK_SIZE
                col = y // BLOCK_SIZE
                if event.button == RIGHT_MOUSE_CLICK:  # right click - source and dest
                    if not self.is_src_button_init:
                        init_src_node()
                    elif not self.is_dest_button_init:
                        init_dest_node()
                elif event.button == LEFT_MOUSE_CLICK:  # left click - bad nodes
                    self.add_bad_nodes_with_mouse(x, y)
                    self.draw_nodes("bad")
                    self.graph.remove_edges_of_bad_nodes(self.bad_nodes)

            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:  # pressed enter - run algorithm
                    dijkstra(self.graph, self.source_node, self.window, self.dest_node)
        pygame.display.update()
        self.clock.tick(FPS)

请注意ENTER单击键时,这就是我调用算法的地方:

source.set_dist_from_source(0)
Q = build_min_heap(graph)  # O(V)
while Q:  # O(V)
    u = heapq.heappop(Q)  # pops the min val based on dist from source (get value and remove from heap) O(logV)
    if u == dest:
        break
    neighbors_of_u = graph.get_neighbors()[u.name]
    for v in neighbors_of_u:  # O(E)
        # drawing neighbors:
        if not v.is_colored:
            block = get_block_from_node(v)
            block.draw(window, VISITED_COLOR)
        # checking min path:
        weight_u_v = graph.get_edge_weight(u.name, v.name)
        v_dist = v.dist_from_source
        u_dist = u.dist_from_source
        if v_dist > u_dist + weight_u_v:
            v.set_dist_from_source(u_dist + weight_u_v)
            v.set_prev(u) # updating prev is done to reconstruct the path itself
            heapq.heappush(Q, v)  # O(logV)
print_path(window, source, dest)

注意线条

block = get_block_from_node(v)
block.draw(window, VISITED_COLOR)

这是我希望展示的部分,但有延迟。这段代码目前可以工作,但是块的颜色太快了,用户看不到绘画的过程。我试过在clock.tick(10)下面添加一个block.draw(window, VISITED_COLOR), where clock=pygame.time.Clock(),但这似乎让一切都停止了(使窗口崩溃)

这显然不是完整的代码,但我相信这是所有相关的代码,不胜感激!

标签: pythonpygame

解决方案


如果您想在每个块之后显示更改,那么您必须在每个块之后更新显示并处理事件。请参阅以下文档pygame.event.pump()

对于游戏的每一帧,您都需要对事件队列进行某种调用。这确保您的程序可以在内部与操作系统的其余部分进行交互。

pygame.time.Clock.tick此外,您可以通过例如控制每秒的成名:

clock=pygame.time.Clock()
while Q:  # O(V)
    # [...]

    for v in neighbors_of_u:  # O(E)
        # [...]

        # drawing neighbors:
        if not v.is_colored:
            block = get_block_from_node(v)
            block.draw(window, VISITED_COLOR)

            display.flip()
            pygame.event.pump()
            clock.tick(10)

        # [...]

推荐阅读