C++实现坦克大战(新手思路)
2021/5/7 12:26:34
本文主要是介绍C++实现坦克大战(新手思路),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
C++实现坦克大战(新手思路)
第一次写,写的不好,还请多多包涵,本人也是第一次学习C++,因为在15派学习原因才接触到这个,本文仅仅提供我个人的一个思路。
效果图
项目实现的功能
实现的功能:
坦克可以随意移动 可以发射炮弹 炮弹发射后自己向前移动
坦克移动的时有碰撞检测,可以被建筑物挡住
检测 坦克和障碍物 坦克和炮弹 炮弹和炮弹的碰撞
多种地形(河流,草丛 土墙 铁墙)
炮弹发射可以摧毁一部分地形
有简单的地图 有敌军随机移动
有双人模式 计分系统 自定义地图
多种敌军(在显示要区分) 读档存档 具有关卡概念
项目设计:
1.这个项目我设计了四个类:地图 坦克 游戏 子弹 还有一个所有类都要工具的函数(这里也可以建个类然后继承这个类)
地图 我采用双地图 一张静态地图存储不会动的障碍物 一张静态地图存储子弹和坦克这些会动的
坦克 要用类型区分坦克的属性,移动 碰撞 的方法
子弹 同样也是这样,子弹可以重载两个运算符(=,==)一个是初始化子弹用,一个子弹碰撞坦克使用
游戏类 操作坦克类对象和子弹类对象
上代码
地图类
cpp#pragma once #include"工具.h" class CMap { public: //静态地图 bool SetMapValue(int nPox, int nPoY,int nValue); int GetMapValue(int nPox, int nPoY); //动态地图 bool SetDMapValue(int nPox, int nPoY, int nValue); int GetDMapValue(int nPox, int nPoY); //画边界 bool DrawMap(); //画草 void DRAWgrass(); //画河流 void DrawRiver(); //画墙 void DrawWall(); //画堡垒 void DrawFortress(); private: int m_nMap[Mapx][Mapy] = {}; //静态地图 int m_dMap[Mapx][Mapy] = {}; //动态地图 }; //上面是.h的文件 下面是.cpp的文件 #include "CMap.h" //修改动态地图上的地标 bool CMap::SetDMapValue(int nPox, int nPoY, int nValue) { m_dMap[nPox][nPoY] = nValue; return true; } //修改静态地图上的地标 bool CMap::SetMapValue(int nPox, int nPoY, int nValue) { m_nMap[nPox][nPoY] = nValue; return true; } //获得动态地图上的地标 int CMap::GetDMapValue(int nPox, int nPoY) { return m_dMap[nPox][nPoY]; } //获得静态地图上的地标 int CMap::GetMapValue(int nPox, int nPoY) { return m_nMap[nPox][nPoY]; } //画地图 bool CMap::DrawMap() { for (int i = 0;i < Mapx;i++) { for (int j = 0;j < Mapy;j++) { if (i == 0 || j == 0 || i == Mapx-1 || j == Mapy-1) { SetMapValue(i,j,边界); writeChar(i, j, "■",15); } else { SetMapValue(i, j, 空地); } } } return true; } //画草 void CMap::DRAWgrass() { for (int j = 19;j < 23;j++) { for (int i = 1;i < 11;i++) { SetMapValue(i, j, 丛林); writeChar(i, j, "WW", 2); } for (int i = 30;i < 39;i++) { SetMapValue(i, j, 丛林); writeChar(i, j, "WW", 2); } } } //画河流 void CMap::DrawRiver() { for (int j = 10;j < 13;j++) { for (int i = 1;i < 11;i++) { SetMapValue(i, j, 河流); writeChar(i, j, "~~", 1); } for (int i = 30;i < 39;i++) { SetMapValue(i, j, 河流); writeChar(i, j, "~~", 1); } } } //画墙 void CMap::DrawWall() { for (int j = 16;j < 18;j++) { for (int i = 14;i < 26;i++) { SetMapValue(i, j, 边界); writeChar(i, j, "■", 15); } } } //画堡垒 void CMap::DrawFortress() { for (int j = 36;j < 39;j++) { for (int i = 19;i < 22;i++) { SetMapValue(i, j, 木墙); writeChar(i, j, "□", 6); } } writeChar(20, 38, "◆", 4); SetMapValue(20, 38, 老鹰); }
坦克类
#pragma once #include"CBullet.h" #include"CMap.h" #include<Windows.h> #include<vector> using std::vector; class CMap; enum Dir { UP=119, DOWN=115, LEFT=97, RIGHT=100 }; class CTank { public: CBullet Bullet; public: //初始化玩家坦克 void CTankINFO(int type); //初始化AI坦克 void AICTankINFO(int type,int num); //擦坦克 void ClsTank(CTank Tank, CMap& map); //画坦克 void DrawTank(CTank Tank, CMap& map); //坦克移动 void MoveTank(CTank& Tank, CMap& map, vector<CTank*> CTanklist); //AI坦克移动 void MoveAITank(CTank& Tank, CMap& map); //坦克的碰撞 int TankCollision(CTank Tank,int dir,CMap &map); //坦克的保存 void SaveCTank(vector<CTank*> CTanklist, CMap& map); //坦克接口 Dir GetDIR(); int GetAlignment(); int GetPosX(); int GetPosY(); int Getbool(); int Getlive(); void Setbool(int n); void Setlive(int n); public: bool m_Live; //坦克是否存活 int m_Alignment;//坦克的阵营 int m_PosX; int m_PosY; //坦克坐标 Dir m_Dir; //坦克方向 int m_Type; //坦克类型 int m_Blood; //坦克血量 int m_Scores; //坦克杀敌分数 int m_TSpeed; //坦克速度 int m_TPast; //坦克的时钟 int m_Num; //坦克序号 int m_color; //坦克颜色 }; //上面是.h的文件 下面是.cpp的文件 #include"工具.h" #include "CTank.h" #include<time.h> //TAnk的接口 Dir CTank::GetDIR() { return m_Dir; } int CTank::GetAlignment() { return m_Alignment; } int CTank::GetPosX() { return m_PosX; } int CTank::GetPosY() { return m_PosY; } int CTank::Getbool() { return m_Blood; } int CTank::Getlive() { return m_Live; } void CTank::Setbool(int n) { m_Blood = n; } void CTank::Setlive(int n) { m_Live = n; } //画坦克 void CTank::DrawTank(CTank Tank, CMap& map) { int x = Tank.m_PosX; int y = Tank.m_PosY; switch (Tank.m_Dir) { case UP: { writeChar(x - 1, y - 1, " ■ ", Tank.m_color); writeChar(x - 1, y, "■■■", Tank.m_color); writeChar(x - 1, y + 1, "■ ■", Tank.m_color); }break; case DOWN: writeChar(x - 1, y - 1, "■ ■", Tank.m_color); writeChar(x - 1, y, "■■■", Tank.m_color); writeChar(x - 1, y + 1, " ■ ", Tank.m_color); break; case LEFT: writeChar(x - 1, y - 1, " ■■", Tank.m_color); writeChar(x - 1, y, "■■ ", Tank.m_color); writeChar(x - 1, y + 1, " ■■", Tank.m_color); break; case RIGHT: writeChar(x - 1, y - 1, "■■ ", Tank.m_color); writeChar(x - 1, y, " ■■", Tank.m_color); writeChar(x - 1, y + 1, "■■ ", Tank.m_color); break; } for (int i = 0;i < 3;i++) { for (int i = 0;i < 3;i++) { if (Tank.m_Alignment == 100) { map.SetDMapValue(Tank.m_PosX + i - 1, Tank.m_PosY + i - 1, 100); } else { map.SetDMapValue(Tank.m_PosX + i - 1, Tank.m_PosY + i - 1, 200 + Tank.m_Num); } } } } //我方坦克初始化 void CTank::CTankINFO(int type) { m_Live = 1; m_Alignment = 100; m_Dir = UP; m_Type = type; m_Blood = 3; m_Scores = 0; m_TSpeed = 500; if (type == 0) { m_PosX = 10; m_PosY = 30; m_color = 7; } else { m_PosX = 30; m_PosY = 30; m_color = 7; } } //敌方坦克初始化 void CTank::AICTankINFO(int type, int num) { m_Live = 1; m_Alignment = 200; m_Dir = DOWN; m_Type = type; m_Scores = 0; m_Num = num; if (type == 2) { m_Blood = 1; m_PosX = 3; m_PosY = 3; m_TSpeed = 500; m_color = 3; } else { m_Blood = 2; m_PosX = 30; m_PosY = 3; m_TSpeed = 200; m_color = 0x04; } } //擦除坦克 void CTank::ClsTank(CTank Tank, CMap& map) { int x = Tank.m_PosX; int y = Tank.m_PosY; writeChar(x - 1, y - 1, " "); writeChar(x - 1, y, " "); writeChar(x - 1, y + 1, " "); for (int i = 0;i < 3;i++) { for (int j = 0;j < 3;j++) { map.SetDMapValue(Tank.m_PosX + i - 1, Tank.m_PosY + i - 1, 空地); } } } //坦克的碰撞检测 int CTank::TankCollision(CTank Tank, int dir, CMap& map) { int x = Tank.m_PosX; int y = Tank.m_PosY; switch (dir) { case UP: if ((map.GetMapValue(x - 1, y - 2) == 丛林 || map.GetMapValue(x, y - 2) == 丛林 || map.GetMapValue(x + 1, y - 2) == 丛林) || (map.GetMapValue(x - 1, y + 2) == 丛林 || map.GetMapValue(x, y + 2) == 丛林 || map.GetMapValue(x + 1, y + 2) == 丛林)) { return 2; } else if ((map.GetMapValue(x, y - 2) == 0 && map.GetMapValue(x - 1, y - 2) == 0 && map.GetMapValue(x + 1, y - 2) == 0) && (map.GetDMapValue(x, y - 2) == 0 && map.GetDMapValue(x - 1, y - 2) == 0 && map.GetDMapValue(x + 1, y - 2) == 0)) { return 1; } else { return 0; } case DOWN: if ((map.GetMapValue(x - 1, y + 2) == 丛林 || map.GetMapValue(x, y + 2) == 丛林 || map.GetMapValue(x + 1, y + 2) == 丛林) || (map.GetMapValue(x - 1, y - 2) == 丛林 || map.GetMapValue(x, y - 2) == 丛林 || map.GetMapValue(x - 1, y - 2) == 丛林)) { return 2; } else if ((map.GetMapValue(x, y + 2) == 0 && map.GetMapValue(x - 1, y + 2) == 0 && map.GetMapValue(x + 1, y + 2) == 0) && (map.GetDMapValue(x, y + 2) == 0 && map.GetDMapValue(x - 1, y + 2) == 0 && map.GetDMapValue(x + 1, y + 2) == 0)) { return 1; } else { return 0; } case LEFT: if ((map.GetMapValue(x - 2, y) == 丛林 || map.GetMapValue(x - 2, y - 1) == 丛林 || map.GetMapValue(x - 2, y + 1) == 丛林) || (map.GetMapValue(x + 2, y) == 丛林 || map.GetMapValue(x + 2, y - 1) == 丛林 || map.GetMapValue(x + 2, y + 1) == 丛林)) { return 2; } else if ((map.GetMapValue(x - 2, y) == 0 && map.GetMapValue(x - 2, y - 1) == 0 && map.GetMapValue(x - 2, y + 1) == 0) && (map.GetDMapValue(x - 2, y) == 0 && map.GetDMapValue(x - 2, y - 1) == 0 && map.GetDMapValue(x - 2, y + 1) == 0)) { return 1; } else return 0; case RIGHT: if ((map.GetMapValue(x + 2, y) == 丛林 || map.GetMapValue(x + 2, y - 1) == 丛林 || map.GetMapValue(x + 2, y + 1) == 丛林) || (map.GetMapValue(x - 2, y) == 丛林 || map.GetMapValue(x - 2, y - 1) == 丛林 || map.GetMapValue(x - 2, y + 1) == 丛林)) { return 2; } else if ((map.GetMapValue(x + 2, y) == 0 && map.GetMapValue(x + 2, y - 1) == 0 && map.GetMapValue(x + 2, y + 1) == 0) && (map.GetDMapValue(x + 2, y) == 0 && map.GetDMapValue(x + 2, y - 1) == 0 && map.GetDMapValue(x + 2, y + 1) == 0)) { return 1; } else return 0; default: return 1; } } //坦克移动 void CTank::MoveTank(CTank& Tank, CMap& map,vector<CTank*> CTanklist) { int oper = 0; if (Tank.m_Type == 0) { oper = waitkey(); } else { int oper1 = waitkey(); switch (oper1) { case 'i': oper = 119; break; case 'k': oper = 115; break; case 'j': oper = 97; break; case 'l': oper = 100; break; case 'h': oper = 102; break; } } if (oper != 0) { ClsTank(Tank, map); } if (TankCollision(Tank,oper ,map)) { switch (oper) { case 'w': { if (Tank.m_Dir != UP) { Tank.m_Dir = UP; } else { Tank.m_PosY--; } }break; case 's': { if (Tank.m_Dir != DOWN) { Tank.m_Dir = DOWN; } else { Tank.m_PosY++; } }break; case 'a': { if (Tank.m_Dir != LEFT) { Tank.m_Dir = LEFT; } else { Tank.m_PosX--; } }break; case 'd': { if (Tank.m_Dir != RIGHT) { Tank.m_Dir = RIGHT; } else { Tank.m_PosX++; } }break; case 'f': { if (Bullet.Getm_bIsDie() == 0) { Bullet.CreateBullet(Tank); } }break; case 'p': { SaveCTank(CTanklist,map); }break; } } if (oper != 0) { int a = TankCollision(Tank, oper, map); DrawTank(Tank, map); if (a == 2) { map.DRAWgrass(); } } } //AI坦克移动 void CTank::MoveAITank(CTank& Tank, CMap& map) { if (Tank.m_Live != 0) { if (clock() - Tank.m_TPast > Tank.m_TSpeed) { Tank.m_TPast = clock(); int oper = rand()%5+1; //int oper = 5; if (oper != 0) { ClsTank(Tank, map); } switch (oper) { case 1: oper = 119; break; case 2: oper = 115; break; case 3: oper = 97; break; case 4: oper = 100; break; case 5: oper = 102; break; default: break; } if (TankCollision(Tank, oper, map)) { switch (oper) { case 'w': { if (Tank.m_Dir != UP) { Tank.m_Dir = UP; } else { Tank.m_PosY--; } }break; case 's': { if (Tank.m_Dir != DOWN) { Tank.m_Dir = DOWN; } else { Tank.m_PosY++; } }break; case 'a': { if (Tank.m_Dir != LEFT) { Tank.m_Dir = LEFT; } else { Tank.m_PosX--; } }break; case 'd': { if (Tank.m_Dir != RIGHT) { Tank.m_Dir = RIGHT; } else { Tank.m_PosX++; } }break; case 'f': { if (Bullet.Getm_bIsDie() == 0) { Bullet.CreateBullet(Tank); } } } } if (oper != 0) { DrawTank(Tank, map); } } } } //保存坦克地图 void CTank::SaveCTank( vector<CTank*> CTanklist,CMap& map) { FILE* fp = nullptr; fopen_s(&fp, "CTank.txt", "wb+"); fwrite(&map, sizeof(CMap), 1, fp); int nSize = CTanklist.size(); fwrite(&nSize, sizeof(int), 1, fp); for (int i = 0;i < CTanklist.size();i++) { fwrite(&(CTanklist[i]->m_Alignment), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_Blood), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_Dir), sizeof(Dir), 1, fp); fwrite(&(CTanklist[i]->m_Live), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_Num), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_PosX), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_PosY), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_Scores), sizeof(Dir), 1, fp); fwrite(&(CTanklist[i]->m_TPast), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_TSpeed), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_Type), sizeof(int), 1, fp); fwrite(&(CTanklist[i]->m_color), sizeof(int), 1, fp); } fclose(fp); fp = nullptr; }
子弹类
#pragma once #include<time.h> class CTank; class CMap; #include<vector> using std::vector; class CBullet { public: //接口 int Getm_bIsDie(); int GetbALignment(); //运算符重载 bool operator=(CTank &Tank); bool operator==(CTank& Tank); //生成子弹 CBullet CreateBullet(CTank &Tank); //擦子弹 void ClsBullet(CBullet& Bullet, CMap& map); //画子弹 void DrawBullet(CBullet& Bullet, CMap& map); //移动子弹 void MoveBullet(CBullet& Bullet,CMap &map, vector<CTank*> CTanklist); //子弹碰撞检测 bool BulletColloson(CBullet& Bullet,CMap& map, vector<CTank*> CTanklist); private: bool m_bIsDie=0;//子弹是否存在 int m_bALignment;//子弹所在的阵营 int m_bPosX; int m_bPosY;//子弹坐标 int m_bDir;//子弹方向 int m_bType;//子弹类型 int m_bATK;//子弹攻击力 int m_bSpeed;//子弹的速度 int m_bPast; //子弹的时钟 int m_color; }; //上面是.h的文件 下面是.cpp的文件 #include "CBullet.h" #include"CTank.h" #include"工具.h" //接口 int CBullet::Getm_bIsDie() { return m_bIsDie; } int CBullet::GetbALignment() { return m_bALignment; } //运算符重载 bool CBullet::operator=(CTank &Tank) { m_bDir = Tank.GetDIR(); m_bPosX = Tank.GetPosX(); m_bPosY = Tank.GetPosY(); m_bALignment = Tank.GetAlignment(); m_bIsDie = 0; m_color = Tank.m_color; switch (Tank.GetDIR()) { case UP: m_bPosY -= 2; break; case DOWN: m_bPosY += 2; break; case LEFT: m_bPosX -= 2; break; case RIGHT: m_bPosX += 2; break; } return true; } bool CBullet::operator==(CTank& Tank) { int nTankPosX = Tank.GetPosX(); int nTankPosY = Tank.GetPosY(); if (Tank.GetDIR()) { for (int nposY = nTankPosY - 1;nposY < nTankPosY + 2;nposY++) { for (int nposX = nTankPosX - 1;nposX < nTankPosX + 2;nposX++) { if ((m_bPosX == nposX) && (m_bPosY == nposY)) { return true; } } } } return false; } //生成子弹 CBullet CBullet::CreateBullet(CTank& Tank) { *this = Tank; this->m_bIsDie = 1; this->m_bSpeed = 50; this->m_bPast = clock(); if (Tank.m_Type > 2) { this->m_bATK = 3; } else { this->m_bATK = 1; } return *this; } //擦子弹 void CBullet::ClsBullet(CBullet& Bullet, CMap& map) { writeChar(Bullet.m_bPosX, Bullet.m_bPosY, " "); map.SetDMapValue(Bullet.m_bPosX, Bullet.m_bPosY, 0); } //画子弹 void CBullet::DrawBullet(CBullet& Bullet, CMap& map) { writeChar(Bullet.m_bPosX, Bullet.m_bPosY, "oo",Bullet.m_color); map.SetDMapValue(Bullet.m_bPosX, Bullet.m_bPosY, 10); } //移动子弹 void CBullet::MoveBullet(CBullet& Bullet,CMap& map, vector<CTank*> CTanklist) { if (Bullet.m_bIsDie == 1) { if (clock() - Bullet.m_bPast > Bullet.m_bSpeed) { Bullet.m_bPast = clock(); if (map.GetMapValue(Bullet.m_bPosX, Bullet.m_bPosY) == 河流 || map.GetMapValue(Bullet.m_bPosX, Bullet.m_bPosY) == 丛林) { } else { ClsBullet(Bullet, map); } if (BulletColloson(Bullet, map, CTanklist)) { switch (Bullet.m_bDir) { case UP: Bullet.m_bPosY--; break; case DOWN: Bullet.m_bPosY++; break; case LEFT: Bullet.m_bPosX--; break; case RIGHT: Bullet.m_bPosX++; break; } if (map.GetMapValue(Bullet.m_bPosX, Bullet.m_bPosY) == 河流 || map.GetMapValue(Bullet.m_bPosX, Bullet.m_bPosY) == 丛林) { return; } DrawBullet(Bullet, map); } } } } //子弹碰撞 bool CBullet::BulletColloson(CBullet& Bullet,CMap &map, vector<CTank*> CTanklist) { int nPox = Bullet.m_bPosX; int nPoY = Bullet.m_bPosY; if (map.GetMapValue(nPox, nPoY) == 边界) { writeChar(nPox, nPoY, "■",15); Bullet.m_bIsDie = 0; return false; } if (map.GetMapValue(nPox, nPoY) == 木墙) { writeChar(nPox, nPoY, " "); map.SetMapValue(nPox, nPoY, 0); Bullet.m_bIsDie = 0; return false; } if (map.GetMapValue(nPox, nPoY) == 河流) { return true; } if (map.GetMapValue(nPox, nPoY) == 丛林) { return true; } switch (Bullet.m_bDir) { case UP: nPoY--; break; case DOWN: nPoY++; break; case LEFT: nPox--; break; case RIGHT: nPox++; break; } //子弹和坦克的碰撞检测 for (int i = 0;i < CTanklist.size();i++) { if (Bullet == *CTanklist[i]) { if (Bullet.m_bALignment != CTanklist[i]->GetAlignment()) { Bullet.m_bIsDie = 0; CTanklist[i]->m_Blood-=Bullet.m_bATK; if (CTanklist[i]->m_Blood == 0) { CTanklist[i]->ClsTank(*CTanklist[i], map); CTanklist[i]->m_Live = 0; CTanklist[0]->m_Scores += 50; } return false; } } } //子弹和子弹的碰撞 if (map.GetDMapValue(nPox, nPoY) == 10) { writeChar(Bullet.m_bPosX, Bullet.m_bPosY, " "); map.SetMapValue(Bullet.m_bPosX, Bullet.m_bPosY, 木墙); Bullet.m_bIsDie = 0; return false; } if (map.GetMapValue(nPox, nPoY) == 老鹰) { writeChar(Bullet.m_bPosX, Bullet.m_bPosY, " "); Bullet.m_bIsDie = 0; writeChar(15, 15, "GOOD GAME!!!", 4); getchar(); exit(1); } return true; }
游戏类
#pragma once #include"CBullet.h" #include"CMap.h" #include"CTank.h" #include<vector> using std::vector; class CGame { public: void startGame();//单人开始游戏 void startGame0();//第三关 void startGame2();//双人开始游戏 void startGame3();//编辑地图开始游戏 void startGame4();//读档开始开始游戏 vector<CTank*> CTanklist; //坦克列表 public://自制地图 void KeyEventProc(KEY_EVENT_RECORD ker); int MessageLoop(CMap &map); void MouseEventProc(MOUSE_EVENT_RECORD mer, CMap& map); public: //读取文件 void readCTank(CMap& map); }; //上面是.h的文件 下面是.cpp的文件 #include "CGame.h" #include"工具.h" #include<Windows.h> #include <conio.h> //键盘事件处理函数 void CGame::KeyEventProc(KEY_EVENT_RECORD ker) { } //消息处理函数 int CGame::MessageLoop(CMap& map) { writeChar(40, 7, "按任意键退出设置地图",2); HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD stcRecord = { 0 }; DWORD dwRead; SetConsoleMode(hStdin, ENABLE_WINDOW_INPUT | ENABLE_MOUSE_INPUT); while (1) { //等待事件 ReadConsoleInput(hStdin, &stcRecord, 1, &dwRead); //处理事件 if (stcRecord.EventType == KEY_EVENT) {//键盘事件 KeyEventProc(stcRecord.Event.KeyEvent); return 0; } else if (stcRecord.EventType == MOUSE_EVENT) {//鼠标事件 MouseEventProc(stcRecord.Event.MouseEvent, map); } } } //鼠标事件处理函数 void CGame::MouseEventProc(MOUSE_EVENT_RECORD mer, CMap& map) { switch (mer.dwEventFlags) { case 0: { if (mer.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) { writeChar(mer.dwMousePosition.X / 2, mer.dwMousePosition.Y, "■"); map.SetMapValue(mer.dwMousePosition.X/2, mer.dwMousePosition.Y, 边界); } else if (mer.dwButtonState == RIGHTMOST_BUTTON_PRESSED) { writeChar(mer.dwMousePosition.X / 2, mer.dwMousePosition.Y, "□"); map.SetMapValue(mer.dwMousePosition.X/2, mer.dwMousePosition.Y, 木墙); } break; } } } //读取文件 void CGame::readCTank(CMap &map) { FILE* fp = nullptr; fopen_s(&fp, "CTank.txt", "rb+"); fread(&map, sizeof(CMap), 1, fp); int nSize = 0; fread(&nSize, sizeof(int), 1, fp); //CTanklist.resize(nSize); for (int i = 0;i < nSize;i++) { CTank* tank = new CTank(); int a = 0; fread(&a, sizeof(int), 1, fp); tank->m_Alignment = a; fread(&a, sizeof(int), 1, fp); tank->m_Blood = a; fread(&a, sizeof(Dir), 1, fp); tank->m_Dir =(Dir) a; fread(&a, sizeof(int), 1, fp); tank->m_Live = a; fread(&a, sizeof(int), 1, fp); tank->m_Num = a; fread(&a, sizeof(int), 1, fp); tank->m_PosX = a; fread(&a, sizeof(int), 1, fp); tank->m_PosY = a; fread(&a, sizeof(Dir), 1, fp); tank->m_Scores = a; fread(&a, sizeof(int), 1, fp); tank->m_TPast = a; fread(&a, sizeof(int), 1, fp); tank->m_TSpeed = a; fread(&a, sizeof(int), 1, fp); tank->m_Type = a; fread(&a, sizeof(int), 1, fp); tank->m_color = a; CTanklist.push_back(tank); } fclose(fp); fp = nullptr; } //单人开始游戏 void CGame::startGame() { srand(time(NULL)); CMap map1; map1.DrawMap(); map1.DrawRiver(); map1.DrawWall(); map1.DRAWgrass(); map1.DrawFortress(); //MessageLoop(map1); CTank* Tank0 = new CTank(); //CTank* Tank1 = new CTank(); CTank* Tank2 = new CTank(); CTank* Tank3 = new CTank(); //初始化坦克 Tank0->CTankINFO(0); //Tank1->CTankINFO(1);//玩家B Tank2->AICTankINFO(2,2); Tank3->AICTankINFO(3,3); CTanklist.push_back(Tank0); //CTanklist.push_back(Tank1); CTanklist.push_back(Tank2); CTanklist.push_back(Tank3); for (int i = 0;i < CTanklist.size();i++) { CTanklist[i]->DrawTank(*CTanklist[i], map1); } writeChar(48, 2, "第一关", 12); writeChar(48, 4, "分数:", 13); writeChar(40, 6, "游戏说明:", 11); writeChar(45, 6, "游戏目标:保护堡垒击杀敌方坦克", 9); writeChar(40, 8, "按键说明:", 14); writeChar(45, 8, "玩家A", 1); writeChar(45, 10, "w/上,s/下,a/左,d/右,f/发炮弹", 1); writeChar(45, 12, "P键保存", 2); while (true) { Tank0->MoveTank(*Tank0, map1,CTanklist); //Tank1->MoveTank(*Tank1, map1, CTanklist); Tank2->MoveAITank(*Tank2, map1 ); Tank3->MoveAITank(*Tank3, map1 ); CTanklist.clear(); if (Tank0->Getlive() != 0) { CTanklist.push_back(Tank0); } /*if (Tank1->Getlive() != 0) { CTanklist.push_back(Tank1); }*/ if (Tank2->Getlive() != 0) { CTanklist.push_back(Tank2); } if (Tank3->Getlive() != 0) { CTanklist.push_back(Tank3); } Tank0->Bullet.MoveBullet(Tank0->Bullet, map1, CTanklist); //Tank1->Bullet.MoveBullet(Tank1->Bullet, map1, CTanklist); Tank2->Bullet.MoveBullet(Tank2->Bullet, map1, CTanklist); Tank3->Bullet.MoveBullet(Tank3->Bullet, map1, CTanklist); writeChar2(51, 4, Tank0->m_Scores, 10); if (Tank0->Getbool() == 0) { writeChar(15, 15, "GOOD GAME!!!", 4); getchar(); exit(1); } if (Tank2->m_Live == 0 && Tank3->m_Live == 0) { Tank0->ClsTank(*Tank0, map1); system("cls"); CTanklist.clear(); writeChar(0, 0, "恭喜通关", 4); writeChar(0, 1, "进入下一关", 4); writeChar(0, 2, "加载中....", 4); Sleep(1500); system("cls"); return; } } } //双人开始游戏 void CGame::startGame2() { srand(time(NULL)); CMap map1; map1.DrawMap(); map1.DrawRiver(); map1.DrawWall(); map1.DRAWgrass(); map1.DrawFortress(); //MessageLoop(map1); CTank* Tank0 = new CTank(); CTank* Tank1 = new CTank(); CTank* Tank2 = new CTank(); CTank* Tank3 = new CTank(); //初始化坦克 Tank0->CTankINFO(0); Tank1->CTankINFO(1);//玩家B Tank2->AICTankINFO(2, 2); Tank3->AICTankINFO(3, 3); CTanklist.push_back(Tank0); CTanklist.push_back(Tank1); CTanklist.push_back(Tank2); CTanklist.push_back(Tank3); for (int i = 0;i < CTanklist.size();i++) { CTanklist[i]->DrawTank(*CTanklist[i], map1); } writeChar(48, 2, "第一关", 12); writeChar(48, 4, "分数:", 13); writeChar(40, 6, "游戏说明:", 11); writeChar(45, 6, "游戏目标:保护堡垒击杀敌方坦克", 9); writeChar(40, 8, "按键说明:", 14); writeChar(45, 8, "玩家A", 1); writeChar(45, 10, "w/上,s/下,a/左,d/右,f/发炮弹", 1); writeChar(45, 12, "玩家B", 13); writeChar(45, 14, "i/上,k/下,j/左,l/右,h/发炮弹", 13); writeChar(45, 16, "P键保存", 2); while (true) { CTanklist.clear(); Tank0->MoveTank(*Tank0, map1, CTanklist); Tank1->MoveTank(*Tank1, map1, CTanklist); Tank2->MoveAITank(*Tank2, map1); Tank3->MoveAITank(*Tank3, map1); if (Tank0->Getlive() != 0) { CTanklist.push_back(Tank0); } if (Tank1->Getlive() != 0) { CTanklist.push_back(Tank1); } if (Tank2->Getlive() != 0) { CTanklist.push_back(Tank2); } if (Tank3->Getlive() != 0) { CTanklist.push_back(Tank3); } Tank0->Bullet.MoveBullet(Tank0->Bullet, map1, CTanklist); Tank1->Bullet.MoveBullet(Tank1->Bullet, map1, CTanklist); Tank2->Bullet.MoveBullet(Tank2->Bullet, map1, CTanklist); Tank3->Bullet.MoveBullet(Tank3->Bullet, map1, CTanklist); if (Tank0->Getbool() == 0) { writeChar(15, 15, "GOOD GAME!!!", 4); getchar(); exit(1); } if (Tank2->m_Live == 0 && Tank3->m_Live == 0) { writeChar(15, 15, "GOOD GAME!!!", 4); getchar(); exit(1); } } } //自制地图开始游戏 void CGame::startGame3() { srand(time(NULL)); CMap map1; map1.DrawMap(); MessageLoop(map1); CTank* Tank0 = new CTank(); //CTank* Tank1 = new CTank(); CTank* Tank2 = new CTank(); CTank* Tank3 = new CTank(); //初始化坦克 Tank0->CTankINFO(0); //Tank1->CTankINFO(1);//玩家B Tank2->AICTankINFO(2, 2); Tank3->AICTankINFO(3, 3); CTanklist.push_back(Tank0); //CTanklist.push_back(Tank1); CTanklist.push_back(Tank2); CTanklist.push_back(Tank3); for (int i = 0;i < CTanklist.size();i++) { CTanklist[i]->DrawTank(*CTanklist[i], map1); } writeChar(48, 2, "第一关", 12); writeChar(48, 4, "分数:", 13); writeChar(40, 6, "游戏说明:", 11); writeChar(45, 6, "游戏目标:保护堡垒击杀敌方坦克", 9); writeChar(40, 8, "按键说明:", 14); writeChar(45, 8, "玩家A", 1); writeChar(45, 10, "w/上,s/下,a/左,d/右,f/发炮弹", 1); writeChar(45, 12, "P键保存", 2); while (true) { CTanklist.clear(); Tank0->MoveTank(*Tank0, map1, CTanklist); //Tank1->MoveTank(*Tank1, map1, CTanklist); Tank2->MoveAITank(*Tank2, map1); Tank3->MoveAITank(*Tank3, map1); if (Tank0->Getlive() != 0) { CTanklist.push_back(Tank0); } /*if (Tank1->Getlive() != 0) { CTanklist.push_back(Tank1); }*/ if (Tank2->Getlive() != 0) { CTanklist.push_back(Tank2); } if (Tank3->Getlive() != 0) { CTanklist.push_back(Tank3); } Tank0->Bullet.MoveBullet(Tank0->Bullet, map1, CTanklist); //Tank1->Bullet.MoveBullet(Tank1->Bullet, map1, CTanklist); Tank2->Bullet.MoveBullet(Tank2->Bullet, map1, CTanklist); Tank3->Bullet.MoveBullet(Tank3->Bullet, map1, CTanklist); if (Tank0->Getbool() == 0) { writeChar(15, 15, "GOOD GAME!!!", 4); getchar(); exit(1); } if (Tank2->m_Live == 0 && Tank3->m_Live == 0) { writeChar(15, 15, "GOOD GAME!!!", 4); getchar(); exit(1); } } } //读档开始游戏 void CGame::startGame4() { srand(time(NULL)); CMap map1; readCTank(map1); map1.DrawMap(); map1.DrawRiver(); map1.DrawWall(); map1.DRAWgrass(); map1.DrawFortress(); //MessageLoop(map1); CTank* Tank0 = CTanklist[0]; //CTank* Tank1 = new CTank(); CTank* Tank2 = CTanklist[1]; CTank* Tank3 = CTanklist[2]; //初始化坦克 //Tank0->CTankINFO(0); //Tank1->CTankINFO(1);//玩家B //Tank2->AICTankINFO(2, 2); //Tank3->AICTankINFO(3, 3); //CTanklist.push_back(Tank0); //CTanklist.push_back(Tank1); //CTanklist.push_back(Tank2); //CTanklist.push_back(Tank3); for (int i = 0;i < CTanklist.size();i++) { CTanklist[i]->DrawTank(*CTanklist[i], map1); } writeChar(48, 2, "第一关", 12); writeChar(48, 4, "分数:", 13); writeChar(40, 6, "游戏说明:", 11); writeChar(45, 6, "游戏目标:保护堡垒击杀敌方坦克", 9); writeChar(40, 8, "按键说明:", 14); writeChar(45, 8, "玩家A", 1); writeChar(45, 10, "w/上,s/下,a/左,d/右,f/发炮弹", 1); writeChar(45, 12, "玩家B", 13); writeChar(45, 14, "i/上,k/下,j/左,l/右,h/发炮弹", 13); writeChar(45, 16, "P键保存", 2); while (true) { Tank0->MoveTank(*Tank0, map1,CTanklist); //Tank1->MoveTank(*Tank1, map1,CTanklist); Tank2->MoveAITank(*Tank2, map1); Tank3->MoveAITank(*Tank3, map1); CTanklist.clear(); if (Tank0->Getlive() != 0) { CTanklist.push_back(Tank0); } /*if (Tank1->Getlive() != 0) { CTanklist.push_back(Tank1); }*/ if (Tank2->Getlive() != 0) { CTanklist.push_back(Tank2); } if (Tank3->Getlive() != 0) { CTanklist.push_back(Tank3); } Tank0->Bullet.MoveBullet(Tank0->Bullet, map1, CTanklist); //Tank1->Bullet.MoveBullet(Tank1->Bullet, map1, bulletlist, CTanklist); Tank2->Bullet.MoveBullet(Tank2->Bullet, map1, CTanklist); Tank3->Bullet.MoveBullet(Tank3->Bullet, map1, CTanklist); if (Tank0->Getbool() == 0) { writeChar(15,15,"GOOD GAME!!!",4); getchar(); exit(1); } if (Tank2->m_Live == 0 && Tank3->m_Live == 0) { writeChar(25, 25, "GOOD GAME!!!", 4); getchar(); exit(1); } } } //第二关 void CGame::startGame0() { srand(time(NULL)); CMap map1; map1.DrawMap(); map1.DrawRiver(); //map1.DrawWall(); map1.DRAWgrass(); map1.DrawFortress(); //MessageLoop(map1); CTank* Tank0 = new CTank(); //CTank* Tank1 = new CTank(); CTank* Tank2 = new CTank(); CTank* Tank3 = new CTank(); //初始化坦克 Tank0->CTankINFO(0); //Tank1->CTankINFO(1);//玩家B Tank2->AICTankINFO(2, 2); Tank3->AICTankINFO(3, 3); CTanklist.push_back(Tank0); //CTanklist.push_back(Tank1); CTanklist.push_back(Tank2); CTanklist.push_back(Tank3); for (int i = 0;i < CTanklist.size();i++) { CTanklist[i]->DrawTank(*CTanklist[i], map1); } writeChar(48, 2, "第二关", 12); writeChar(48, 4, "分数:", 13); writeChar(40, 6, "游戏说明:", 11); writeChar(45, 6, "游戏目标:保护堡垒击杀敌方坦克", 9); writeChar(40, 8, "按键说明:", 14); writeChar(45, 8, "玩家A", 1); writeChar(45, 10, "w/上,s/下,a/左,d/右,f/发炮弹", 1); writeChar(45, 12, "P键保存", 2); while (true) { Tank0->MoveTank(*Tank0, map1, CTanklist); //Tank1->MoveTank(*Tank1, map1, CTanklist); Tank2->MoveAITank(*Tank2, map1); Tank3->MoveAITank(*Tank3, map1); CTanklist.clear(); if (Tank0->Getlive() != 0) { CTanklist.push_back(Tank0); } /*if (Tank1->Getlive() != 0) { CTanklist.push_back(Tank1); }*/ if (Tank2->Getlive() != 0) { CTanklist.push_back(Tank2); } if (Tank3->Getlive() != 0) { CTanklist.push_back(Tank3); } Tank0->Bullet.MoveBullet(Tank0->Bullet, map1, CTanklist); //Tank1->Bullet.MoveBullet(Tank1->Bullet, map1, CTanklist); Tank2->Bullet.MoveBullet(Tank2->Bullet, map1, CTanklist); Tank3->Bullet.MoveBullet(Tank3->Bullet, map1, CTanklist); writeChar2(51, 4, Tank0->m_Scores, 10); if (Tank0->Getbool() == 0) { writeChar(15, 15, "GOOD GAME!!!", 4); getchar(); exit(1); } if (Tank2->m_Live == 0 && Tank3->m_Live == 0) { writeChar(15, 15, "恭喜通关", 4); getchar(); exit(1); } } }
工具函数
#pragma once #define Mapx 40 #define Mapy 40 #define 空地 0 #define 边界 1 #define 河流 2 #define 丛林 3 #define 木墙 4 #define 老鹰 5 //打印文字和图形 void writeChar(int x, int y, const char* szBuf, int color=0); //打印变量的值 void writeChar2(int x, int y, int a, int color = 0); //获取按键 int waitkey(); //隐藏光标 void ShouCursor(bool isShow); //上面是.h的文件 下面是.cpp的文件 #include"工具.h" #include<Windows.h> #include <conio.h> #include<iostream> #include<time.h> //打印文字和图形 void writeChar(int x, int y, const char* szBuf, int color) { COORD pos = { x * 2,y }; HANDLE hStout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hStout, pos); SetConsoleTextAttribute(hStout, color); printf(szBuf); } //打印变量的值 void writeChar2(int x, int y, int a , int color) { COORD pos = { x * 2,y }; HANDLE hStout = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(hStout, pos); SetConsoleTextAttribute(hStout, color); printf("%d",a); } //获取按键 int waitkey() { if (_kbhit()) { return _getch(); } return 0; } //隐藏光标 void ShouCursor(bool isShow) { HANDLE hOutStd = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO cci; cci.dwSize = 1; cci.bVisible = isShow; SetConsoleCursorInfo(hOutStd, &cci); }
主函数
#include<iostream> #include<Windows.h> #include <conio.h> #include"CTank.h" #include"CBullet.h" #include"工具.h" #include "CMap.h" #include"CGame.h" #pragma comment(lib,"winmm.lib") int main() { system("mode con cols=120 lines=50"); PlaySoundA("D:/C语言项目/坦克大战C/坦克大战/坦克大战/菊次郎的夏天.wav", NULL, SND_ASYNC | SND_NODEFAULT); ShouCursor(0); while (true) { CGame game1; writeChar(10, 10, "坦克大战",7); writeChar(10, 11, "1.开始游戏",7); writeChar(10, 12, "2.双人游戏",7); writeChar(10, 13, "3.自制地图",7); writeChar(10, 14, "4.继续游戏",7); writeChar(10, 15, "5.退出游戏",7); writeChar(10, 16, "",7); int oper = getchar(); switch (oper) { case '1': { system("cls"); game1.startGame(); game1.startGame0(); } case '2': { system("cls"); game1.startGame2(); } case '3': { system("cls"); game1.startGame3(); } case '4': { system("cls"); game1.startGame4(); } case '5': { system("cls"); writeChar(10, 10, "再来玩哟"); exit(1); } default: break; } } }
项目总结
1 代码过于繁琐 可以精简 。
2.可以使用继承和多态进行优化。
3.注释太少(估计过段时间也就上帝能看得懂我的代码了)。
4.敌方坦克太傻了 可以加入Astart算法让他自行寻路。
5.取名字虽然是个难事 尽量见名知意 或者就多注释。
这篇关于C++实现坦克大战(新手思路)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04安装 Eyoucms详细图文教程-icode9专业技术文章分享
- 2024-07-04ueditor 复制文章时,图片的链接是一个下载图片地址,该如何处理?-icode9专业技术文章分享
- 2024-07-04怎样判断host有没有对wordpress有缓存呢-icode9专业技术文章分享
- 2024-07-04具有编译功能的系统make后,无法ssh连接-icode9专业技术文章分享
- 2024-07-04make后如何升级ssh-icode9专业技术文章分享
- 2024-07-03微信支付提示下单账户与支付账户不一致-icode9专业技术文章分享
- 2024-07-03微信支付提示订单号重复-icode9专业技术文章分享
- 2024-07-02微服务启动nacos注册上去了,但是一直没有收到请求-icode9专业技术文章分享
- 2024-07-02如何检查文件的编码格式-icode9专业技术文章分享
- 2024-07-02sublime 更改编码格式-icode9专业技术文章分享