python - 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()
,但这似乎让一切都停止了(使窗口崩溃)
这显然不是完整的代码,但我相信这是所有相关的代码,不胜感激!
解决方案
如果您想在每个块之后显示更改,那么您必须在每个块之后更新显示并处理事件。请参阅以下文档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)
# [...]
推荐阅读
- gitlab - 我应该在 Gitlab 中使用什么文本编辑器以及如何安装它?
- python - 文档自动化
- firefox - mouseMove 在 Firefox 中不起作用;不允许使用 http 方法
- hyperledger-fabric - 如何在模型文件中有一个均匀的关系?
- backup - scp 备份带有变量文件夹的路径
- javascript - 如何使用javascript获取应用于HTML元素的rotateY值?
- c# - 恢复多个数据库时,测试中止但没有抛出错误?
- react-native - BottomTabNavigator - 反应原生
- javascript - noscript 和禁用 javascript
- java - Spring Boot 应用程序不创建 .jar 文件