IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++控制台坦克大战 -> 正文阅读

[C++知识库]C++控制台坦克大战

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();//调用所有角色的update
        collideEnemy();//英雄子弹与敌人碰撞
        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++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-23 16:27:24  更:2021-08-23 16:30:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 6:00:33-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计