Flutter for OpenHarmony 可视化教学:A* 寻路算法的交互式演示
Flutter for OpenHarmony 可视化教学A* 寻路算法的交互式演示在人工智能、游戏开发和机器人导航等领域路径规划Pathfinding是一项基础而关键的技术。其中A*A-Star算法因其高效性与最优性成为最广为人知的启发式搜索算法之一。然而其背后的“开启列表”、“关闭列表”、“f g h”等概念对初学者而言仍显抽象。本文将深入解析一段完整的Flutter 应用代码该应用通过直观的网格界面、动态的颜色反馈和流畅的动画效果将 A* 算法的执行过程转化为一场沉浸式的可视化学习体验。你将看到如何用 Dart 实现经典的 A* 逻辑如何利用GridView构建交互式地图以及如何设计一个既能教学又能娱乐的寻路模拟器。 加入社区 欢迎加入开源鸿蒙跨平台开发者社区获取最新资源与技术支持 开源鸿蒙跨平台开发者社区完整效果一、应用概览交互式寻路沙盒该应用提供了一个15×20 的网格世界用户可以点击任意空白格子添加或移除灰色障碍物墙壁点击“开始寻路”启动 A* 算法从绿色起点到红色终点寻找最短路径实时观察蓝色区域表示算法正在探索的节点黄色路径即为最终结果一键重置恢复初始状态或仅清除障碍物进行新实验。核心目标让抽象的图搜索算法变得可见、可操作、可理解。二、A* 算法原理简述A* 是一种最佳优先搜索算法它通过评估函数f(n) g(n) h(n)来决定下一个要探索的节点g(n)从起点到当前节点n的实际代价本例中为步数h(n)从节点n到终点的启发式估计代价本例使用曼哈顿距离f(n)总预估代价值越小优先级越高。算法维护两个关键集合开启列表Open List待检查的候选节点关闭列表Closed List已处理完毕的节点。通过不断从开启列表中选择f值最小的节点进行扩展并更新邻居的代价最终找到一条从起点到终点的最短路径若存在。三、代码实现详解1. 数据结构设计▶ 网格单元类型enumCellType{empty,wall,start,end,path,visited}清晰定义六种状态便于 UI 渲染与逻辑判断。▶ 二维坐标点classPoint{finalint x,y;// 重写 和 hashCode使其可作为 Map 的 key}支持集合操作如SetPoint和映射如MapPoint, Point是实现cameFrom路径回溯的关键。2. A* 核心逻辑 (_runAStar)▶ 初始化ListPointopenList[start];SetPointclosedList{};MapPoint,PointcameFrom{};// 记录父节点MapPoint,doublegScore{start:0};MapPoint,doublefScore{start:_heuristic(start,end)};▶ 主循环选点从openList中选出fScore最小的节点current终止条件若current end调用_reconstructPath回溯路径标记访问将current加入closedList并在 UI 上标记为蓝色CellType.visited探索邻居遍历上下左右四个方向跳过越界、墙壁或已在closedList中的点计算临时gScore若更优则更新gScore、fScore和cameFrom并将邻居加入openList。▶ 启发式函数曼哈顿距离double_heuristic(Pointa,Pointb){return(a.x-b.x).abs()(a.y-b.y).abs();}适用于只能上下左右移动的网格地图保证可采纳性Admissible即不会高估实际代价从而确保找到最优解。▶ 路径重构Futurevoid_reconstructPath(MapPoint,PointcameFrom,Pointcurrent)async{ListPointtotalPath[];while(cameFrom.containsKey(current)){currentcameFrom[current]!;totalPath.add(current);}// 从起点到终点反向遍历再反转totalPathtotalPath.reversed.toList();// 逐个高亮为黄色}3. 异步与动画await Future.delayed(...)在每次更新网格状态后暂停片刻形成“探索”和“绘制路径”的动画效果setState(() {})触发 UI 重绘实时反映算法进展isRunning标志防止用户在运行时误操作保证状态一致性。四、UI/UX 设计亮点1. 直观的色彩编码颜色含义 绿色起点 (start) 红色终点 (end)⚪ 透明/白色空地 (empty)⚫ 灰色障碍物 (wall) 蓝色半透已探索节点 (visited) 黄色最终路径 (path)这种设计让用户一眼就能分辨算法的当前状态。2. 交互式网格 (GridView.builder)每个格子都是一个GestureDetector点击即可切换空地/墙壁使用SliverGridDelegateWithFixedCrossAxisCount精确控制列数确保网格比例协调mainAxisSpacing和crossAxisSpacing添加 1px 间隙提升视觉清晰度。3. 控制面板三个功能按钮布局合理重置恢复初始布局含默认起点终点清空障碍保留起点终点仅移除墙壁方便快速测试不同障碍配置开始寻路核心操作运行时显示“运行中…”并禁用其他按钮。五、教育价值与应用场景教学场景算法课演示动态展示 A* 如何“聪明地”避开障碍优先向终点方向搜索启发式函数对比可轻松扩展为支持欧几里得距离、对角线移动等观察不同h(n)对搜索效率的影响失败案例分析当终点被完全包围时应用会弹出提示“未找到可达路径”帮助学生理解算法的局限性。开发参考游戏 AI可作为 NPC 自动寻路的基础模块地图应用室内导航、仓库机器人路径规划的简化模型性能基准通过调整网格大小测试算法在不同规模问题下的表现。六、总结这段 Flutter 代码不仅是一个功能完整的 A* 寻路演示器更是一个优秀的计算思维教学工具。它将复杂的图搜索过程分解为可视化的步骤通过颜色、动画和即时反馈极大地降低了学习门槛。完整代码importdart:uias ui;importpackage:flutter/material.dart;voidmain(){runApp(const PathFindingApp());}class PathFindingApp extends StatelessWidget{const PathFindingApp({super.key});override Widget build(BuildContext context){returnMaterialApp(title:A* 寻路算法, theme: ThemeData.dark(), home: const AStarVisualizer(), debugShowCheckedModeBanner: false,);}}// 网格状态枚举 enum CellType{empty, wall, start, end, path, visited}// 二维坐标点 class Point{final int x, y;Point(this.x, this.y);override bool operator(Object other){returnother is Pointxother.xyother.y;}override int get hashCodeObject.hash(x, y);}class AStarVisualizer extends StatefulWidget{const AStarVisualizer({super.key});override StateAStarVisualizercreateState()_AStarVisualizerState();}class _AStarVisualizerState extends StateAStarVisualizer{static const int rows15;static const int cols20;late ListListCellTypegrid;Point? start;Point? end;bool isRunningfalse;override voidinitState(){super.initState();_resetGrid();}void_resetGrid(){gridList.generate(rows,(i){returnList.generate(cols,(j){returnCellType.empty;});});startPoint(1,1);endPoint(rows -2, cols -2);grid[start!.x][start!.y]CellType.start;grid[end!.x][end!.y]CellType.end;}void_clearWalls(){for(int i0;irows;i){for(int j0;jcols;j){if(grid[i][j]CellType.wall){grid[i][j]CellType.empty;}}}}// A* 算法核心 Futurevoid_runAStar()async{if(startnull||endnull)return;setState((){ isRunningtrue;});//开启列表待检查的节点 ListPointopenList[Point(start!.x,start!.y)];//关闭列表已检查的节点 SetPointclosedList{};//记录路径(父节点映射)MapPoint,PointcameFrom{};//gScore:从起点到该节点的实际代价 MapPoint,doublegScore{};gScore[start!]0;//fScore:从起点经由该节点到终点的预估总代价 MapPoint,doublefScore{};fScore[start!]_heuristic(start!,end!);while(openList.isNotEmpty){//1.找到fScore最小的节点 Point currentopenList.reduce((a,b){ return(fScore[a]??double.infinity)(fScore[b]??double.infinity)?a:b;});//2.如果到达终点重构路径 if(currentend){ await _reconstructPath(cameFrom,current);setState((){ isRunningfalse;});return;}//3.将当前节点移出开启列表加入关闭列表 openList.remove(current);closedList.add(current);//可视化标记为已访问 if(grid[current.x][current.y]!CellType.startgrid[current.x][current.y]!CellType.end){ grid[current.x][current.y]CellType.visited;setState((){});await Future.delayed(const Duration(milliseconds:50));}//4. 检查邻居(上下左右)ListPointneighbors[Point(current.x -1, current.y), Point(current.x 1, current.y), Point(current.x, current.y -1), Point(current.x, current.y 1),];for(Point neighborinneighbors){int xneighbor.x;int yneighbor.y;// 检查是否越界或为墙壁if(x0||xrows||y0||ycols||grid[x][y]CellType.wall){continue;}// 如果已经在关闭列表跳过if(closedList.contains(neighbor)){continue;}// 计算临时的gScore(从起点到邻居的代价)double tentativeGScore(gScore[current]?? double.infinity)1;// 如果该邻居不在开启列表中或者找到了更短的路径if(!openList.contains(neighbor)||tentativeGScore(gScore[neighbor]?? double.infinity)){// 记录路径 cameFrom[neighbor]current;gScore[neighbor]tentativeGScore;fScore[neighbor]tentativeGScore _heuristic(neighbor, end!);if(!openList.contains(neighbor)){openList.add(neighbor);}}}}// 没有找到路径 ScaffoldMessenger.of(context).showSnackBar(const SnackBar(content: Text(未找到可达路径)),);setState((){ isRunningfalse;});}//启发式函数(曼哈顿距离)double _heuristic(Point a,Point b){ return((a.x-b.x).abs()(a.y-b.y).abs()).toDouble();}// 重构路径 Futurevoid_reconstructPath(MapPoint, PointcameFrom, Point current)async{ListPointtotalPath[current];while(cameFrom.containsKey(current)){currentcameFrom[current]!;totalPath.add(current);}totalPathtotalPath.reversed.toList();// 高亮显示路径for(Point pintotalPath){if(p!startp!end){grid[p.x][p.y]CellType.path;setState((){});await Future.delayed(const Duration(milliseconds:100));}}}override Widget build(BuildContext context){returnScaffold(appBar: AppBar(title: const Text(A* 寻路算法可视化),), body: Column(children:[const Text(绿色起点, Red终点, Gray障碍物, Blue探索中, Yellow路径), Expanded(child: GridView.builder(padding: const EdgeInsets.all(8), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: cols, mainAxisSpacing:1, crossAxisSpacing:1,), itemCount: rows * cols, itemBuilder:(context, index){int rowindex ~/ cols;int colindex % cols;bool isStartPoint(row, col)start;bool isEndPoint(row, col)end;Color colorColors.transparent;if(grid[row][col]CellType.wall){colorColors.grey;}elseif(grid[row][col]CellType.visited){colorColors.blue.withOpacity(0.5);}elseif(grid[row][col]CellType.path){colorColors.yellow;}elseif(isStart){colorColors.green;}elseif(isEnd){colorColors.red;}returnGestureDetector(onTap:(){if(isRunning)return;setState((){if(grid[row][col]CellType.empty){grid[row][col]CellType.wall;}elseif(grid[row][col]CellType.wall){grid[row][col]CellType.empty;}});}, child: Container(decoration: BoxDecoration(color: color), child: const SizedBox(),),);},),), Row(mainAxisAlignment: MainAxisAlignment.spaceEvenly, children:[ElevatedButton.icon(onPressed:(){if(!isRunning){_resetGrid();setState((){});}}, icon: const Icon(Icons.refresh), label: const Text(重置),), ElevatedButton.icon(onPressed:(){if(!isRunning){_clearWalls();setState((){});}}, icon: const Icon(Icons.delete), label: const Text(清空障碍),), ElevatedButton.icon(onPressed: _runAStar, icon: const Icon(Icons.route), label: Text(isRunning ?运行中...:开始寻路),),],),],),);}}

相关新闻

学术研究利器:11款AI论文写作工具盘点

学术研究利器:11款AI论文写作工具盘点

近年来,人工智能语言模型的飞速发展彻底改变了学术研究的格局。尤其是自 2022 年 11 月 OpenAI 发布 ChatGPT 以来,AI 工具在学术界的应用日益广泛,帮助科研人员节省时间、提高效率,从而专注于更有价值的任务。AI 学术工具本质上是…

2026/7/5 0:44:40 阅读更多 →
人工智能驱动的科研新范式及学科应用研究

人工智能驱动的科研新范式及学科应用研究

以下文章来源于“中国科学院院刊”,仅做学术分享 原文链接:https://mp.weixin.qq.com/s/_f1XvDtoE-ZHgSwuIRwWUw 本文刊载于《中国科学院院刊》2025年第2期"学科发展” 余江1,2 张越1,2* 周易1,3 1 中国科学院科技战略咨询研究院 2 中国科学…

2026/7/4 22:53:30 阅读更多 →
小程序毕设项目:基于springboot+小程序的温州博物馆小程序的设计与实现(源码+文档,讲解、调试运行,定制等)

小程序毕设项目:基于springboot+小程序的温州博物馆小程序的设计与实现(源码+文档,讲解、调试运行,定制等)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/4 2:28:40 阅读更多 →

最新新闻

Ceph自动化运维开发:openeuler/ceph_dev中Ansible与Terraform集成

Ceph自动化运维开发:openeuler/ceph_dev中Ansible与Terraform集成

Ceph自动化运维开发:openeuler/ceph_dev中Ansible与Terraform集成 【免费下载链接】ceph_dev ceph_dev is a project focus on some feature developing based on ceph 项目地址: https://gitcode.com/openeuler/ceph_dev 前往项目官网免费下载:h…

2026/7/5 0:43:58 阅读更多 →
【Springboot毕设全套源码+文档】基于springboot二次元商品商城系统的设计与实现(丰富项目+远程调试+讲解+定制)

【Springboot毕设全套源码+文档】基于springboot二次元商品商城系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/5 0:43:58 阅读更多 →
告别Selenium弹窗噩梦:Playwright实现无头浏览器文件自动下载实战

告别Selenium弹窗噩梦:Playwright实现无头浏览器文件自动下载实战

1. 项目概述:为什么我们要告别Selenium?如果你做过Web自动化测试或者数据抓取,尤其是涉及到文件下载的场景,那你大概率经历过“弹窗噩梦”。浏览器原生的“另存为”对话框,就像一堵无法逾越的高墙,横亘在你…

2026/7/5 0:39:55 阅读更多 →
从光学到产品:护眼钢化膜的技术原理与实现路径深度解析(以悟赫德 scinique 技术为例)

从光学到产品:护眼钢化膜的技术原理与实现路径深度解析(以悟赫德 scinique 技术为例)

1. 引言:为什么我们需要 "护眼" 的手机膜?随着 OLED 屏幕在智能手机中的全面普及,以及用户日均用屏时长的不断增加(据统计,2026 年国内用户日均手机使用时长已超过 6.5 小时),视疲劳正…

2026/7/5 0:39:55 阅读更多 →
ASM330LHH与PIC18F25K80的工业级运动跟踪系统设计

ASM330LHH与PIC18F25K80的工业级运动跟踪系统设计

1. 从传感器到系统:ASM330LHH与PIC18F25K80的硬件搭档当我在工业自动化项目中第一次接触到ASM330LHH这颗6DoF惯性测量单元(IMU)时,立刻被它的性能参数所震撼。作为意法半导体MEMS传感器家族的重要成员,它在一个3x2.5x0.83mm的封装内集成了三轴…

2026/7/5 0:35:54 阅读更多 →
Python3与Java Hutool实现SM2国密算法跨语言加解密互通方案

Python3与Java Hutool实现SM2国密算法跨语言加解密互通方案

1. 项目概述与核心价值最近在做一个需要跨语言数据交换的项目,后端是Java,用到了Hutool这个“瑞士军刀”库来处理SM2国密算法的加解密,而另一个数据处理服务是用Python3写的。这就引出了一个很实际的问题:Java这边用Hutool加密的数…

2026/7/5 0:33:53 阅读更多 →

日新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

周新闻

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容

B站视频下载神器BiliTools:5分钟学会轻松保存任何B站内容 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱,支持下载视频、番剧等等各类资源 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliTools …

2026/7/5 0:03:34 阅读更多 →
威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型全解析:从新手入门到实战应用,助你构建安全产品!

威胁模型的陌生现状在忙碌疲惫的一天里,参与了关于混合后量子密码学的讨论,应付端点攻击找茬的人,还参与留言板讨论后,发现“威胁模型”对多数人仍是陌生概念,且多被当作时髦用语。有趣的相关画作有一幅由 Embyr 创作的…

2026/7/5 0:03:34 阅读更多 →
渗透测试入门指南:从零基础到实战环境搭建

渗透测试入门指南:从零基础到实战环境搭建

1. 从“看热闹”到“入门”:我理解的渗透测试到底是什么?每次看到新闻里说某个大公司的数据被“黑”了,或者某个网站被攻击导致服务瘫痪,你是不是和我一样,心里会冒出两个念头:一是“这黑客真厉害”&#x…

2026/7/5 0:07:38 阅读更多 →

月新闻