C++控制台坦克大战
C++控制台坦克大战
最近接了一个企业的C++定制培训班,在语法阶段结束后要求带学生做一个项目。思来想去就做一个控制台的坦克大战吧,在这里分享给大家。
工具类
- 坐标点类
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;
};
类的继承关系
- 继承关系图
- 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;
};
- 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;//帧数计数
};
- Barrier类
class Barrier : public Sprite
{public:Barrier(char type);void draw();void clearDraw();void update();private:int status;string body[3][2] = {{"# #","# #"}, //静态物体样式{"@ @","@ @"}, //动态物体样式{"$ $","$ $"} //老家样式};
};
- 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;//开火冷却计时
};
- 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类主要是负责游戏主逻辑。也是观察者模式的接受者,处理各种信号。
- 游戏主逻辑:主要函数run在main函数中调用
int Scene::run()
{draw();//绘制整个游戏界面while(isRun){createEnemy();//创建敌人keyboard();//键盘输入监听rolesUpdate();//调用所有角色的updatecollideEnemy();//英雄子弹与敌人碰撞collideHero();//英雄与敌人子弹碰撞gameWin();//判定胜利Sleep(50);//每秒20帧}getchar();//输入任意键继续return overFlag;
}
draw函数
draw函数没有在循环中调用,因为控制台打印信息很多,刷新屏幕会闪,所以采用局部刷新,每个移动物体在移动时自行刷新。获得按键信息
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操作
- 关卡信息
//# 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];
- 控制台移动光标
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++控制台坦克大战相关推荐
- C++程序设计作业--坦克大战[分享]
C++程序设计作业--坦克大战[分享] 1.设计目的 2.设计目标 1.基本目标 2.额外目标 3 程序设计思路 3.1 类的设计 3.1.1 CData 3.1.2 class Draw 3.1.3 ...
- C++坦克大战(新手)
程序流程图 根据流程图我把程序分位四部分: 第一部分:游戏设置初始化 :设置窗口名称,大小 :隐藏光标,切换输入法(控制台赶紧去输入法是中文的) :背景音乐设置 第二部分:游戏菜单设计,选择游戏模式 ...
- win10使用C语言运行坦克大战游戏(转载)
转自:C语言坦克大战 运行效果 注:本游戏win7可完美运行,win10的话,小坦克和子弹的打印会略有鬼畜(变形,只打印半边等).win10完美运行方案:点击屏幕左下角"开始"界面 ...
- 关于c语言坦克大战的
这次我决定试试用思维导图的方式将C语言控制台版坦克大战的逻辑及流程写下了. ** 实现逻辑** 1.在此项目中需要什么函数? 2.它们之间有什么联系,怎样联系? 3.这些函数及联系又该怎样实现? 根据 ...
- 帧同步坦克大战匹配系统
在介绍匹配系统之前,先说一下项目的整体结构. 项目主要有四个场景: start --> home --> choose --> game start_scene: 是游戏的开始场景, ...
- C/C++ 手写“90坦克大战游戏”
今天给大家分享使用C语言配合easy-x图形库开发的一款控制台桌面小游戏.(IDE:请使用vs2010或者vs2019) 资源下载链接: 百度网盘 链接:https://pan.baidu.com/s ...
- c++实现坦克大战(开源)无bug
用c++实现简易坦克大战源码 代旁边有注释: #include <stdio.h> #include <windows.h> #include <time.h> # ...
- C语言(C++)复刻《坦克大战2.0》
本人代码的编写基于以下博主的代码之上,进行编写. C语言坦克大战_Rivival_S 的博客-CSDN博客_c语言坦克大战r 基于这位博主还原的红白游戏机的经典内容,我在此基础上,又进行了一系列的改进 ...
- Java坦克大战 跟学韩顺平老师视频开发
这里写目录标题 TankBigWarGame 介绍 界面展示 项目架构 安装教程 游戏说明 项目涉及技术功能 游戏结束判断 项目不足与优化空间 相关代码展示 主方法Main 绘图界面 MyPanelF ...
最新文章
- 在Ubuntu 16.04.1 LTS上安装ats 5.3.2
- 大规模1.4亿中文知识图谱数据,我把它开源了
- 一步一步使用Ext JS MVC与Asp.Net MVC 3开发简单的CMS后台管理系统之登录窗口调试...
- Linq中两种更新操作
- 几百个Android开源个性化控件、工具库、项目、开发工具快快收藏
- Oracle数据库升级与补丁
- SAP CRM文本配置里的Continue标签,到底控制了什么行为
- 如何实现下拉框的绑定
- =空值返回空值_@ParameterizedTest在@CvsSource中具有空值
- 【渝粤教育】国家开放大学2019年春季 2080现代教育思想 参考试题
- 网页设计工资一般多少_理发师工资一般多少钱一个月
- 【网络安全工程师面试合集】— 渗透资源 操作系统大合集
- 3文字怎么断行_Word闹鬼,行首出现删不掉的空格怎么办?
- mysql 字段值保留2位小数
- 探索:GHOST分区之后如何找回原分区
- 刷掉985/211,年底我却收到字节50W测试开发offer,实名揭露用人标准
- Linux安装Axis C构建WebService服务
- POP3 SMTP 协议 及 使用
- html代码在线高亮美化,代码语法高亮美化显示插件CodeMirror
- audio语音播放组件