python - 相应地更新显示以使每帧产生函数
问题描述
我正在尝试使用我的算法上的 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 的算法函数结束时逐个节点而不是每个访问的节点着色?
为了更好地理解,这里是一次完成所有节点着色后网格的样子:
视频来表示过程中的算法:
解决方案
您的事件循环或主游戏循环中不应有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.
推荐阅读
- html - 剪辑路径无法正确缩放
- google-cloud-platform - 我正在尝试在谷歌云功能中添加验证 jwt 令牌方法,但它显示错误
- javascript - 如何从表格的最后一行获取输入类型文本的值
- java - 2 个按钮 2 个 EditTexts 字符串输入 1 个 TextVew 输出
- react-native - React Native Reanimated 动画属性列表
- reactjs - 为什么指定道具的对象属性不起作用?
- react-native - RingCentral 双向通信
- java - 在加工中建造战舰。我如何将船只连接在一起并随机化船只的位置?
- python - Django模板在下拉选择中对搜索结果进行排序
- apache - 为什么我的 CORS 请求因 http 401 错误而失败