低调的菜鸡 发表于 2019-11-29 20:46

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*算法地图可以直接用坦克类的静态地图,感兴趣的朋友可以自己加上哦。

低调的菜鸡 发表于 2020-3-17 16:04

xwl 发表于 2020-3-17 11:40
很好奇,语言是怎么在控制台绘图以及接受按键事件的?

打印特殊字符用于绘图,按键事件,可以用检测按键状态实现,也可以自己直接读取控制台的按键事件队列,这些都是能实现的

低调的菜鸡 发表于 2019-11-29 22:41

雨后de水滴 发表于 2019-11-29 22:40
厉害
请问绘制文字部分是封装独立成函数的吗,还是和逻辑写在一起的

绘制文字部分是有一个基础的库文件,自己写的,然后在类里面调用进行绘制的

等风来~ 发表于 2019-11-29 21:08

大佬{:1_927:}666

ccyf1314 发表于 2019-11-29 21:15

大佬{:1_927:}:victory:666

1677 发表于 2019-11-29 21:45

可以分享下你的2017 软件吗

低调的菜鸡 发表于 2019-11-29 21:50

1677 发表于 2019-11-29 21:45
可以分享下你的2017 软件吗

其实都一样啦,2017,2019,19的优化更爽

低调的菜鸡 发表于 2019-11-29 21:53

1677 发表于 2019-11-29 21:45
可以分享下你的2017 软件吗

19的可以在微软官网下载,比我分享百度网盘快多了

hxw0204 发表于 2019-11-29 22:01

谢谢分享。厉害厉害

cherrypi 发表于 2019-11-29 22:16

学习大佬了。

mojie 发表于 2019-11-29 22:35

楼主真棒,我最近想用python做一个

低调的菜鸡 发表于 2019-11-29 22:36

mojie 发表于 2019-11-29 22:35
楼主真棒,我最近想用python做一个

那就去做吧,里面太多坑了:lol
页: [1] 2 3 4
查看完整版本: c++1400行代码实现的控制台坦克大战(麻雀虽小,五脏俱全)