前言
时隔两个月,也没想到自己居然会回来挖坟,不过这次导航系统确实有种魔力,让我着了魔地去思索和编程。
前后总共花了2周时间,写了4000行的代码才实现了整个系统。回想起来感觉自己好像在做毕设一样^_^
作品:下载地址
数据结构
对我来说,学习数据结构是很痛苦的,我数学并不是很好,学习这个也十分耗费心神,不过正因为难所以数据结构和算法才是编程的重中之重。
数据结构这门课到底是学了点东西的
- 时间复杂度 (用求和公式和用for循环累加的执行效率是几何级的)
- 数据结构存储方式 (不同的方式对应了不同的遍历递归方案,在不同的操作环境下各有优劣)
- 排序与哈希值 (排序对于存储的作用以及排序的方法)
数据结构大作业的要求
老师罗列了很多要求。
总结起来有如下几点
- 信息查询功能
- 导航功能
- 后台数据管理功能
模块上需要包含以下几点
- 用户界面
- 输入模块(读相关的数据文件)
- 输出模块(更新后的数据保存到文件)
- 查询功能模块:如查询目标的相关信息
- 线路规划模块
- 后台管理功能:如添加、修改或者删除道路、区间信息等
测试用例要求
- 通道路不少于12条,高速道路不少于6条。
- 普通道路每个区间除了端点目标和交叉口目标
SFML框架
为了更好地实现图形化界面,我借助了C++的SFML库来实现效果。
SFML全称是Simple and Fast Multimedia Library,是基于OpenGL实现多媒体跨平台、多语言支持的C++库。
SFML 官网:https://www.sfml-dev.org/
SFML在国外是一个比较流行的图形化界面游戏开发库,通过对OpenGL的封装实现更加简便的图形、音频操作,大大简化了代码的复杂程度。
接触SFML完全是因为Lynda.com上面有一套C++游戏开发的教程,我想着图形化界面最契合的就是用游戏框架去开发了,所以果断选择了SFML框架。
数据结构设计
逻辑结构定义
导航系统使用了数据结构图的功能,通过迪杰斯特拉算法,实现寻路的功能。
通过结构体定义图的基本结构
我自己用C++写了Path类和Circle类从而方便我更好地使用SFML库
通过读取数据库将信息存放到了图的结构体变量当中
- ArcCell代表道路
- VertexTyoe 代表景点
- MGraph 代表图的基本单元
Circle类则包含了 景点的序号、类型、名称、评价、花费 等public变量
另外还有很多关于SFML反馈的函数
Path 类则包含了 道路的类型、名称、起点序号、终点序号、序号、距离、限制速度 等public变量。
当然这里也有很多关于SFML反馈的函数
通过迪杰斯特拉算法实现最短路径的寻找
设置相应的动态数组 初始化变量的数值
通过三个for循环实现迪杰斯特拉算法
存储结构定义
通过C++的流操作读取txt数据将数据存入二维数组当中
功能模块实现
IO模块
用户界面
通过不同的用户名和密码实现 普通用户 和 系统管理员 的级别区分
输入模块
输入用户名和密码来登录系统
用户名输入支持中文输入法
密码仅支持英文数字和特殊符号
系统会读取用户数据的数据库进行匹配验证用户输入的信息是否正确
输入正确和错误均有相应的系统提示
查询功能
通过图形化界面,用户可以直接通过点击相应的图形反馈查询到相关的信息
系统设置
在系统设置当中实现音量控制、画面全屏、寻路动画、寻路方式等功能的实现
后台管理功能模块
后台管理功能
通过图形化界面对相应的景点和道路进行信息修改
按编辑可以实现信息的修改
点击编辑之后会出现相应的输入框
这样就可以对输入框进行修改
点击确定会显示修改成功
并且将修改的信息储存到数据库当中
同时也再次读取数据库的信息实现画面的信息更新
用户数据后台管理功能
将用户的数据信息保存到数据库中实现对数据库的增删改查
线路规划模块
通过直接绘制实现图形化的数据添加和删除
这些绘制都会直接保存到数据库中
每次保存都会更新算法信息
保证寻路的准确性
系统测试与结果展示
登录界面
获取系统管理员界面
忘记密码
注册账号
普通用户界面
系统管理员界面
路线分析界面
总结
SFML主要用于基于OpenGL的C++小游戏的开发,在国外的C++圈子里比较流行,但是国内的并未普及。所以国内的资料非常稀缺,我所有的学习基本都是看网上的英文API文档以及借助国外的论坛、网站来解决问题的。
这前前后后也踩了很多很多的坑,我做完这个系统深刻的感受到SFML其实并不适合进行软件开发,图形化的软件界面有更好的C++库可以实现,而且实现效率要比复杂的游戏开发库高得多,诸如imgui之类的,很多国外软件都是使用它来开发gui的,另外qt也非常流行,国内也有不少的资料。鉴于自己已经把坑开了,所以也要硬着头皮把坑填完。
当中当然也查询了很多C++的操作,比如变量类型的转换,流操作实现txt文本的存储和读取,这也多亏了国内的CSDN论坛的相助。成功解决了我大量的问题。
在整个制作过程中最让我印象深刻的就是通过SFML制作输入文本框,SFML并不像qt或者MFC那样有组件控件的开发方式,也没有提供相关的文本框输入封装的类,所以要实现用户名输入等等的文本框操作,我只能自己去写文本框的输入逻辑,然而网上完全没有这方面的资料,搜索到的也是用其他的gui库来简化实现复杂度,最后我只能通过自己的摸索以及解读SFML 的API文档实现了。虽然最后文本框输入不能使用鼠标切换输入位置,不过基础的功能都实现了,我还是挺欣慰的。
当然开发文本框的时候最蛋疼的莫过于中文输入的问题了,这当中也让我纠结了好了久,中文输入显示乱码,全都是因为中文编码是两个字节的不同于英文的单字节,这需要SFML提供额外的支持,同时又要让C++自带的string库可以与SFML的string库当中实现转换,这个过程也是一点点摸索才弄明白,SFML用的是wstring的宽字节输入方式,这样就支持unicode从而实现更多语言显示的支持,所以又在网上弄了很多资料,国内外的资料都搜罗了一遍才有了眉目。
最后,当然也是最让我颇有成就感的就是将迪杰斯特拉的算法放到了我的系统当中,实现了寻路的功能,整个寻路的方法基本都是看老师写的ppt的算法实现,因为老师使用了结构体,我也不想作死改成C++的类了。这当中的摸索我个人感觉并没有上面的SFML库那么艰辛,不过实现算法动态演示倒是个技术活,这需要对迪杰斯特拉算法有很深刻的了解,理解它的运行原理才可以做到,之前写了好多遍都遇到了各种各样的bug,比如找到的路径不是最短的,显示的路径有奇奇怪怪的错漏,经过一段时间的思考,才终于将最好完美地效果呈现出来。
现在蓦然回首,发现自己写了近4千行代码了,其中还不包括一些测试用的代码,感觉自己还是挺用心的把坑填完了,写了两个多星期。其实最初也没想过做到如此复杂,比如说绘制功能,用户数据管理功能,这些都是在制作过程突然产生了制作的想法,然后就孜孜不倦的尝试实现。为了实现这些功能我也不得不去推倒了很多已经写好的代码,不过也算是把一些落后的实现方式摒弃吧。