c++1400行代码实现的控制台坦克大战(麻雀虽小,五脏俱全)
先放上游戏截图和代码吧,各位大佬看个乐呵,如果觉得对大家有帮助的话,欢迎点赞投币哦:lol代码下载链接:https://pan.baidu.com/s/1MJE2xG_v1hVV41dDLxB3Mg 提取码:vpss编译环境vs2017 + windows10
具体设计思路
一、大致设想
1.坦克类,子弹类,每个类维护一张地图
* 关于坦克:地图中只保存当前坦克不能过的地方(墙、河流)
* 关于子弹:地图中只保存子弹能撞到的东西(不在草地里的坦克,子弹,墙)
* 游戏对象:地图中只保存障碍物
2. 地图的作用
* 坦克对象:根据当前模式,选择用a*规划路径,还是直接获取传入的方向移动,根据地图可以判断是否能够移动
* 子弹:根据子弹的类型(普通弹、跟踪弹、爆破弹),选择用a*规划路径,还是直接根据当前方向移动,根据地图可以判断是否碰撞
3. 三者的交互
* 坦克类地图的修改:
* 被子弹击中(游戏类中实现(未完成))
* 自己移动(已完成)
* 游戏地图对象的修改
* 子弹撞到障碍物
4. a星算法的使用
* 输入:起点,终点,地图
* 输出:当前起点的第一个移动方向
* 对于子弹:
* 终点为目标坦克
* 地图中的障碍物只有墙,其他坦克
* 对于坦克
* 终点为目标坦克
* 地图中的障碍物只有水流,墙,其他坦克
5. 游戏初始化:
* 加载地图
* 初始化2只玩家坦克和4只ai坦克于重生点
6.游戏主循环:
* 循环获取玩家一和玩家二的输入
* 如果有按键按下:判断玩家1和玩家2的坦克是否到达了响应时间
* 遍历敌方坦克数组,判断是否到达响应时间,使用A*还是随机移动
* 遍历子弹数组,判断是否达到响应时间,根据子弹的类型进行移动或者A*
7.关于坦克地图:
* 地图里所有的障碍物都会范围加一圈,因为坦克走不过去
* 删除障碍物,如墙的时候,坦克地图中也是直接少一圈,游戏地图中也是,相当于子弹的爆破范围为9*9的格子
二、类的实现
1.坦克类:
* 数据:
* 方向
* 坐标
* 坦克专属静态地图,从游戏类地图继承而来,用于坦克碰撞检测和坦克的a*算法
* 静态坦克形状数组,可以根据坦克类型来画不同的坦克
* 方法
* 坦克移动(需修改自己的地图类对象):
* 带方向的(玩家坦克):根据玩家方向,进行碰撞检测,移动,修改回坦克地图
* 不带方向的(敌方坦克):或随机,或a*,进行碰撞检测,移动,修改回坦克地图
* 坦克碰撞检测(需读取自己的地图类对象)
* 载入地图:将游戏类的地图修改为坦克专版后,放入坦克类地图
* 画坦克
* 清除坦克
* 坦克是否在该点范围内存在
2. 子弹类:
* 数据:
* 坐标
* 方向
* 方法
* 移动
3. 地图类:
* 数据:
* 一个40*40的二维数组
* 方法
* 存入数据
* 读出数据
* 从文件加载地图
* 保存地图到文件
* 转换地图为坦克专用,返回一个地图对象
4. 游戏类
* 数据:
* 一个地图类对象
* 2只友方坦克
* 4只敌方坦克数组
* 方法
* 加载地图
* 创建子弹
* 坦克初始化
* 游戏运行主循环
* 子弹碰撞检测
* 获取用户输入
* 游戏初始化(隐藏光标,更改标题名,切换输入法,将地图转换到坦克专用)
* 地图编辑
5. A*算法类
* 数据:
* 一张特殊地图,装有障碍物
* 起点
* 终点
* 方法
* 获取路径,返回一个路径数组,保存路劲
* 获取方向,返回一个方向,为当前路劲最近的方向
三、类的包含关系
坦克类包含地图类,A*算法类
子弹类包含坦克类
地图类啥也不需要包含
游戏类包含子弹类
四、 一些全局定义的宏
1.坦克类型,为了方便调用坦克的形状
* 玩家坦克 10
* 敌方坦克 11
2.地图类型
* 空地 0
* 砖墙 1
* 铁墙 2
* 草地 3
* 河流 4
五、 很方便的宏
//判断指定的按键是否按下(8000可以同时检测多个,8004只能检测一个)
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code)&&0x8000)?1:0)
//判断指定的按键是否弹起
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code)&&0x8000)?1:0)
六、关于界面切换和处理的一些小问题
1. 游戏运行的主要界面
* 开机界面
* 游戏模式选择界面(单人,双人,地图编辑)
* 单人和双人都有存档读取界面,是否读取
* 单人游戏界面(有操作提示,只显示一个玩家的数据:血量,移速,攻击力,分数,杀敌数)
* 双人游戏界面(有操作提示,显示两个玩家的数据:血量,移速,攻击力,分数,杀敌数)
* 地图编辑界面(有操作提示)
2.用一个游戏管理方法来管理界面
* 先打开开机界面
* 进入游戏模式选择界面,w,s切换,j确认
* 根据游戏模式进入对应的界面
* 单人
* 是否读取存档(根据选项选择是直接加载关卡地图,刷新坦克,还是)
* 双人
* 是否读取存档
* 地图编辑
* 是否保存地图
* 选择2个关卡地图
七、 为什么最后没有加上A*算法
* 由于时间关系啦,加上代码行数实在过多,所以只能先忍一手
* 如何加上?
* 在游戏管理类的moveNpc函数中,调用a*,传入坦克自身的坐标和目的坐标,a*算法地图可以直接用坦克类的静态地图,感兴趣的朋友可以自己加上哦。 xwl 发表于 2020-3-17 11:40
很好奇,语言是怎么在控制台绘图以及接受按键事件的?
打印特殊字符用于绘图,按键事件,可以用检测按键状态实现,也可以自己直接读取控制台的按键事件队列,这些都是能实现的 雨后de水滴 发表于 2019-11-29 22:40
厉害
请问绘制文字部分是封装独立成函数的吗,还是和逻辑写在一起的
绘制文字部分是有一个基础的库文件,自己写的,然后在类里面调用进行绘制的 大佬{:1_927:}666 大佬{:1_927:}:victory:666 可以分享下你的2017 软件吗 1677 发表于 2019-11-29 21:45
可以分享下你的2017 软件吗
其实都一样啦,2017,2019,19的优化更爽 1677 发表于 2019-11-29 21:45
可以分享下你的2017 软件吗
19的可以在微软官网下载,比我分享百度网盘快多了 谢谢分享。厉害厉害 学习大佬了。 楼主真棒,我最近想用python做一个 mojie 发表于 2019-11-29 22:35
楼主真棒,我最近想用python做一个
那就去做吧,里面太多坑了:lol