C++控制台坦克大战

最近接了一个企业的C++定制培训班,在语法阶段结束后要求带学生做一个项目。思来想去就做一个控制台的坦克大战吧,在这里分享给大家。

工具类

  1. 坐标点类
class Point
{public:Point();Point(int x, int y);inline int getX(){return x;}inline int getY(){return y;}inline void setX(int x){this->x = x;}inline void setY(int y){this->y = y;}bool operator==(const Point& other);Point operator+(Point other);
private:int x;int y;
};

2.尺寸类

class Size
{public:Size();Size(int width, int height);inline int getWidth(){return width;}inline int getHeight(){return height;}inline void setWidth(int width){this->width = width;}inline void setHeight(int height){this->height = height;}bool operator==(const Size& other);
private:int width;int height;
};

3.矩形类

class Rect
{public:Rect();Rect(Point pos, Size size);inline Point getPos(){return pos;}inline Size getSize(){return size;}inline void setPos(Point pos){this->pos = pos;}inline void setSize(Size size){this->size = size;}bool contains(Point point);//包含点bool collide(Rect other);//矩形碰撞 AABB碰撞算法int minX();int maxX();int minY();int maxY();
private:Point pos;Size size;
};

类的继承关系

  1. 继承关系图
  2. Sprite类
class Sprite
{public:Sprite();
public:virtual void draw() = 0;//绘制virtual void clearDraw() = 0;//清理绘制virtual void update() = 0;//周期逻辑inline Rect getRect(){return Rect(pos, size);}//获得矩形对象inline Point getPos(){return pos;}inline Size getSize(){return size;}inline void setPos(Point pos){this->pos = pos;}inline void setSize(Size size){this->size = size;}
protected:Point pos;Size size;
};
  1. Role类
class Role : public Sprite
{public:Role();enum Direction_t{dir_up,dir_down,dir_left,dir_right};virtual void moveUp()=0;virtual void moveDown()=0;virtual void moveLeft()=0;virtual void moveRight()=0;inline void setSpeed(int speed){this->speed = speed;}inline void setDirection(Direction_t dir){direction = dir;}inline Direction_t getDirection(){return direction;}
protected:Direction_t direction;//移动方向int speed;//移动速度  多少帧移动一次int speedCount;//帧数计数
};
  1. Barrier类
class Barrier : public Sprite
{public:Barrier(char type);void draw();void clearDraw();void update();private:int status;string body[3][2] = {{"# #","# #"},  //静态物体样式{"@ @","@ @"},  //动态物体样式{"$ $","$ $"}   //老家样式};
};
  1. Hero类
class Hero : public Role
{public:Hero();void draw();void clearDraw();void moveUp();void moveDown();void moveLeft();void moveRight();void update();void fire();//开火bool canFire();//开火权限bool canMove();//移动权限bool collideBarrier();//碰到障碍物bool collideBarrier(Point newPos);//碰到障碍物private:string body[4][3] = {{"◢ ┃ ◣","┣ ● ┫","◥ ━ ◤"},{"◢ ━ ◣","┣ ● ┫","◥ ┃ ◤"},{"◢ ┳ ◣","━ ● ┃","◥ ┻ ◤"},{"◢ ┳ ◣","┃ ● ━","◥ ┻ ◤"}};int fireCD = 20;//开火冷却int fireCDCount = 0;//开火冷却计时
};
  1. Enemy类
class Enemy : public Role
{public:Enemy();~Enemy();void moveUp();void moveDown();void moveLeft();void moveRight();void draw();//绘制void clearDraw();//清理绘制void update();//周期逻辑   bool collideBarrier();//碰到障碍物bool collideBarrier(Point newPos);//碰到障碍物
private:void moveCtrl();//移动控制void fireCtrl();//开火控制void changeDirection();//改变移动方向private:string body[4][3] = {{"╔ ┃ ╗","╠ █ ╣","╚ ╩ ╝"},{"╔ ╦ ╗","╠ █ ╣","╚ ┃ ╝"},{"╔ ╦ ╗","━ █ ╣","╚ ╩ ╝"},{"╔ ╦ ╗","╠ █ ━","╚ ╩ ╝"}};enum Status_t{statusMove, //延当前方向移动statusStop  //停止时不移动,随机一个方向};int fireCD = 200;//开火冷却int fireCDCount = 0;//开火冷却计时Status_t status;//当前状态
};

7 .Bullet类

class Bullet : public Role
{public:enum Status_t{heroBullet,enemyBullet};Bullet(Status_t status);~Bullet();void moveUp();void moveDown();void moveLeft();void moveRight();void draw();//绘制void clearDraw();//清理绘制void update();//周期逻辑bool collideStaticBarrier(Point newPoint);//碰到静态障碍物bool collideDynamicBarrier(Point newPoint);//碰到静态障碍物bool collideHomeBarrier(Point newPoint);//碰到老家bool collideBarrier(Point newPoint, char type);//碰到障碍物
private:string show = "◎";Status_t status;
};

Scene类

Scane类主要是负责游戏主逻辑。也是观察者模式的接受者,处理各种信号。

  1. 游戏主逻辑:主要函数run在main函数中调用
int Scene::run()
{draw();//绘制整个游戏界面while(isRun){createEnemy();//创建敌人keyboard();//键盘输入监听rolesUpdate();//调用所有角色的updatecollideEnemy();//英雄子弹与敌人碰撞collideHero();//英雄与敌人子弹碰撞gameWin();//判定胜利Sleep(50);//每秒20帧}getchar();//输入任意键继续return overFlag;
}
  1. draw函数
    draw函数没有在循环中调用,因为控制台打印信息很多,刷新屏幕会闪,所以采用局部刷新,每个移动物体在移动时自行刷新。

  2. 获得按键信息

void Scene::keyboard()
{if (GetAsyncKeyState(VK_UP)& 0x8000)  keyboardEvent(KEY_UP);else if (GetAsyncKeyState(VK_DOWN)& 0x8000)  keyboardEvent(KEY_DOWN);else if (GetAsyncKeyState(VK_LEFT)& 0x8000)keyboardEvent(KEY_LEFT);else if (GetAsyncKeyState(VK_RIGHT)& 0x8000)  keyboardEvent(KEY_RIGHT);else if (GetAsyncKeyState( 0x1B )& 0x8000) exit(0);                              else if (GetAsyncKeyState( 0x20 )& 0x8000)  keyboardEvent(KEY_SPACE);
}

SignalManager类

观察者模式类,用来解耦

class Receiver;class SignalManager
{public:enum Signal_t{enemyFire,      //敌人开火heroBulletOutRange, //英雄子弹越界enemyBulletOutRange,//敌人子弹越界heroBulletCollideDynamicBarrier,//英雄子弹碰撞动态物体enemyBulletCollideDynamicBarrier,//敌人子弹碰撞动态物体bulletCollideHomeBarrier//子弹碰撞老家};void sendSignal(SignalManager::Signal_t signal, void* sender, void* data);void addSignal(SignalManager::Signal_t signal, Receiver* receiver);void removeSignal(SignalManager::Signal_t signal, Receiver* receiver);
private:map<Signal_t, vector<Receiver*> > receivers;void dispatch(SignalManager::Signal_t signal, void* sender, void* data);
public:static SignalManager* getInstance();static void releaseInstance();
private:SignalManager();~SignalManager();static SignalManager* instance;
};/*
接受者基类
*/
class Receiver
{public:virtual void receive(SignalManager::Signal_t signal, void* sender, void* data) = 0;
};

Utils 关卡信息和控制台window操作

  1. 关卡信息
//# 0静态物体,不可摧毁   @ 1动态物体,可摧毁   $2守护的老家
char map1[SCREEN_HEIGHT][SCREEN_WIDTH+1] = {"                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","         @1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1       ","         11111111111111111111111111111111111111111111       ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","         @1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1@1       ","         11111111111111111111111111111111111111111111       ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","         #0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0#0       ","         00000000000000000000000000000000000000000000       ","                                                            ","                                                            ","                                                            ","                           @1@1@1                           ","                           111111                           ","                           @1$2@1                           ","                           112211                           "
};char map2[SCREEN_HEIGHT][SCREEN_WIDTH+1] = {"                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                        @1          @1                      ","                        11          11                      ","                        @1          @1                      ","                        11          11                      ","                        @1@1@1@1@1@1@1                      ","                        11111111111111                      ","                        @1          @1                      ","                        11          11                      ","                        @1          @1                      ","                        11          11                      ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                                                            ","                           @1@1@1                           ","                           111111                           ","                           @1$2@1                           ","                           112211                           "
};char (*maps[])[SCREEN_WIDTH+1] = {map1, map2};
int level = 0;//关卡号
char(*currentMap)[SCREEN_WIDTH+1] = maps[level];
  1. 控制台移动光标
void goToPosition(Point pos)
{COORD  coord;        coord.X=pos.getX()*2+START_X;           coord.Y=pos.getY()+START_Y;HANDLE a=GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(a,coord);
}void hideCursor() // 用于隐藏光标
{CONSOLE_CURSOR_INFO cursor_info = {1, 0};  // 第二个值为0表示隐藏光标SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

最后附上源码:源码下载

C++控制台坦克大战相关推荐

  1. C++程序设计作业--坦克大战[分享]

    C++程序设计作业--坦克大战[分享] 1.设计目的 2.设计目标 1.基本目标 2.额外目标 3 程序设计思路 3.1 类的设计 3.1.1 CData 3.1.2 class Draw 3.1.3 ...

  2. C++坦克大战(新手)

    程序流程图 根据流程图我把程序分位四部分: 第一部分:游戏设置初始化 :设置窗口名称,大小 :隐藏光标,切换输入法(控制台赶紧去输入法是中文的) :背景音乐设置 第二部分:游戏菜单设计,选择游戏模式 ...

  3. win10使用C语言运行坦克大战游戏(转载)

    转自:C语言坦克大战 运行效果 注:本游戏win7可完美运行,win10的话,小坦克和子弹的打印会略有鬼畜(变形,只打印半边等).win10完美运行方案:点击屏幕左下角"开始"界面 ...

  4. 关于c语言坦克大战的

    这次我决定试试用思维导图的方式将C语言控制台版坦克大战的逻辑及流程写下了. ** 实现逻辑** 1.在此项目中需要什么函数? 2.它们之间有什么联系,怎样联系? 3.这些函数及联系又该怎样实现? 根据 ...

  5. 帧同步坦克大战匹配系统

    在介绍匹配系统之前,先说一下项目的整体结构. 项目主要有四个场景: start --> home --> choose --> game start_scene: 是游戏的开始场景, ...

  6. C/C++ 手写“90坦克大战游戏”

    今天给大家分享使用C语言配合easy-x图形库开发的一款控制台桌面小游戏.(IDE:请使用vs2010或者vs2019) 资源下载链接: 百度网盘 链接:https://pan.baidu.com/s ...

  7. c++实现坦克大战(开源)无bug

    用c++实现简易坦克大战源码 代旁边有注释: #include <stdio.h> #include <windows.h> #include <time.h> # ...

  8. C语言(C++)复刻《坦克大战2.0》

    本人代码的编写基于以下博主的代码之上,进行编写. C语言坦克大战_Rivival_S 的博客-CSDN博客_c语言坦克大战r 基于这位博主还原的红白游戏机的经典内容,我在此基础上,又进行了一系列的改进 ...

  9. Java坦克大战 跟学韩顺平老师视频开发

    这里写目录标题 TankBigWarGame 介绍 界面展示 项目架构 安装教程 游戏说明 项目涉及技术功能 游戏结束判断 项目不足与优化空间 相关代码展示 主方法Main 绘图界面 MyPanelF ...

最新文章

  1. 在Ubuntu 16.04.1 LTS上安装ats 5.3.2
  2. 大规模1.4亿中文知识图谱数据,我把它开源了
  3. 一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之登录窗口调试...
  4. Linq中两种更新操作
  5. 几百个Android开源个性化控件、工具库、项目、开发工具快快收藏
  6. Oracle数据库升级与补丁
  7. SAP CRM文本配置里的Continue标签,到底控制了什么行为
  8. 如何实现下拉框的绑定
  9. =空值返回空值_@ParameterizedTest在@CvsSource中具有空值
  10. 【渝粤教育】国家开放大学2019年春季 2080现代教育思想 参考试题
  11. 网页设计工资一般多少_理发师工资一般多少钱一个月
  12. 【网络安全工程师面试合集】— 渗透资源 操作系统大合集
  13. 3文字怎么断行_Word闹鬼,行首出现删不掉的空格怎么办?
  14. mysql 字段值保留2位小数
  15. 探索:GHOST分区之后如何找回原分区
  16. 刷掉985/211,年底我却收到字节50W测试开发offer,实名揭露用人标准
  17. Linux安装Axis C构建WebService服务
  18. POP3 SMTP 协议 及 使用
  19. html代码在线高亮美化,代码语法高亮美化显示插件CodeMirror
  20. audio语音播放组件

热门文章

  1. vue项目的一级路由和二级路由的理解
  2. 乐视超级手机的跨界影响
  3. 用python写一个识别仪表读数的AI组件
  4. Logistic函数
  5. 【UDS】ISO14229之0x28服务
  6. MY-HuaWei-1
  7. 【调剂】济南大学机器学习及其应用课题组拟接收计算机硕士(第一志愿及调剂)报考-预宣传...
  8. 企业如何借助码匠,实现员工核酸提醒?
  9. java如何做一个奖牌榜_编写一个成绩统计的java程序。
  10. 有c语言基础学python要多久-C语言是学python的基础吗?