用C++语言实现坦克大战游戏
用C++语言实现坦克大战游戏
在小霸王游戏机上玩坦克大战是我们大多数90后的一个美好记忆,现在我们就来介绍如何使用C++语言将其实现,下面只介绍了第一关的实现,其实后面关卡也是同样道理,只要明白了其中的思想,就很容易了。在实现坦克大战的代码上,我使用了结构体,没有使用面向对象,也就是没有使用类。最下方有完整的代码,图片、音频资源的链接。
1、项目准备
我所要介绍的坦克大战游戏使用的IDE是VS2015 ,当然VS 2010及以上都可以,还需要安装 easyX 图形库,大家可以去官网下载:https://www.easyx.cn/
2、模块划分
1、游戏开始界面
2、游戏场景
3、游戏结束
3、项目实现
1、游戏开始界面
“搭建游戏开始界面” 要素:
1、 “界面” - 绘图环境
2、 Logo - 美工图片,游戏标志
3、 按钮 - 实现“说明”和“开始”导航
4、 说明 - 美工图片,操作说明
其实游戏开始界面的原理就是在650×650的界面中在指定位置放置图片以及输出文本,然后通过检测鼠标的移动以及按键
来检测,如果鼠标移动到说明的矩形框中就在下方放置说明的图片,移开后就用黑色填充矩形进行覆盖。如果鼠标移入开
始的矩形框中,并按下左键就返回主函数,调用游戏场景的函数。
游戏开始界面代码如下:
void outputPage1()
{initgraph(650, 650); //初始化图形界面,大小为650×650 像素IMAGE logoImg; loadimage(&logoImg, _T("logo.bmp"), 433, 147); //将图片加载入logoImg中putimage(113, 40, &logoImg); //在坐标(113,40) 的地方放置图片IMAGE illustrate;loadimage(&illustrate, _T("illustrate.jpg"), 300, 300);settextcolor(RGB(255, 255, 255));settextstyle(30, 0, _T("微软雅黑")); //设置文本样式 高度30像素 宽度默认 字体 微软雅黑rectangle(195, 200, 275, 240); //创建矩形框 位置 左上角(195,200) 右下角(275,240)rectangle(375, 200, 455, 240);outtextxy(210, 205, _T("说 明")); //在(210,205)位置输出 文本内容outtextxy(390, 205, _T("开 始"));//**************** 检测鼠标事件 *********************MOUSEMSG m;while (1){m = GetMouseMsg();switch (m.uMsg){case WM_MOUSEMOVE: //鼠标移动if ((m.x >= 195 && m.x <= 275) && (m.y >= 200 && m.y <= 240)){putimage(150, 250, &illustrate);}else{setfillcolor(BLACK);solidrectangle(150, 250, 450, 550);}break;case WM_LBUTTONDOWN: //鼠标左键按下if ((m.x >= 375 && m.x <= 455) && (m.y >= 200 && m.y <= 240)){cleardevice();return;}break;}}}
2、游戏场景以及坦克移动、射击实现
1、地图表示
使用二维数组
1、 游戏道具显示(墙、老鹰、我方坦克、敌方坦克、子弹)
2、 便于程序控制敌方坦克前进,控制子弹移动和判断子弹击中目标等
道具表示:
0为游戏中黑色区域,坦克可以移动,可消除墙为1,不可消除墙为2,老鹰(3,4),敌方坦克 100 - 109,我方坦克200
代码实现:
int map[26][26] = {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,2,2,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,2,2,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },{ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1 },{ 2,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2 },{ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,3,4,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,4,4,1,0,0,0,0,0,0,0,0,0,0,0 }
};
void outputPage2()
{IMAGE brick1;IMAGE brick2;IMAGE home;loadimage(&home, _T("home.jpg"), 50, 50);loadimage(&brick1, _T("wall1.jpg"), 25, 25);loadimage(&brick2, _T("wall2.jpg"), 25, 25);for (int i=0; i < 26; i++){ for(int j=0;j<26;j++){switch (map[i][j]){case 1:putimage(25 * j, 25 * i, &brick1); break;case 2:putimage(25 * j, 25 * i, &brick2); break;case 3:putimage(25 * j, 25 * i, &home); map[i][j] = 4;break;}}}return;
}
2、坦克实现
1、绘制坦克
定义结构体
其中包括 坦克的坐标x,y 坦克的状态(是死还是活) 坦克朝向的方向
在指定位置按照坦克的朝向来放置不同坦克图片,并且将坦克所在位置的四个二维数组进行赋值,如果是我方坦克
赋值为200,敌方十辆坦克 100~109
2、坦克移动
坦克移动一个位置后需要将原来的坦克图片用黑色填充矩形进行覆盖,然后在移动后的位置按照坦克方向放置坦克
对应方向的图片,同时改变坦克的x,y坐标,并原来的坦克位置的四个二维数组赋值为0,将移动后的坦克位置的数组改为200,敌方的为
100~109.
3、坦克射击
同时也要定义 子弹的结构体,其中包括子弹的x,y坐标,状态 以及移动的方向。
子弹的移动跟坦克基本一样,但是这里的子弹是绘制的一个白色圆点,向前移动的时候用黑色填充圆进行覆盖原来的位置,
然后在新的位置绘制白色填充圆,并改变子弹的x,y坐标,以便进行碰撞检测。
4、碰撞检测
检测子弹在飞行中的位置,如果子弹碰到可消除的墙,则将此位置的数组赋值为0,同时让墙消失,如果碰到不可消除的墙
则子弹消失,如果我方子弹碰到敌方坦克,则让子弹和敌方坦克都消失,如果打到老鹰游戏失败。
3、游戏结束
游戏结束跟游戏开始界面是一样的道理。
下面是整个游戏的代码,以及其中所使用到的音频
#include <graphics.h> //引用easyX图形库
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <MMSystem.h>
#pragma comment(lib,"winmm.lib") //导入声音库#define ENENMY_TANK_NUMBER 10
bool flag = 1;
enum DIRECTION {UP,DOWN,LEFT,RIGHT}; //坦克的方向//坦克结构体struct TANK
{int tank_x;int tank_y;int direction; //判断坦克方向,从而确定子弹的飞行轨迹 1 为上 ,2为下 , 3为左, 4为右bool state;
};//子弹结构体
struct BULLET
{int bullet_x;int bullet_y;DIRECTION direction;bool state;
};
//0 为空 1为可消除墙 2为不可消除墙 3,4为老家
int map[26][26] = {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,2,2,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,2,2,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },{ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,1,1 },{ 2,2,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,2,2 },{ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,1,1,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,1,1,0,0,1,1,0,0,0,1,1,1,1,0,0,0,1,1,0,0,1,1,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,3,4,1,0,0,0,0,0,0,0,0,0,0,0 },{ 0,0,0,0,0,0,0,0,0,0,0,1,4,4,1,0,0,0,0,0,0,0,0,0,0,0 }
};//******************* 游戏首界面 **********************
void outputPage1()
{IMAGE logoImg;loadimage(&logoImg, _T("logo.bmp"), 433, 147);putimage(113, 40, &logoImg);IMAGE illustrate;loadimage(&illustrate, _T("illustrate.jpg"), 300, 300);settextcolor(RGB(255, 255, 255));settextstyle(30, 0, _T("微软雅黑"));rectangle(195, 200, 275, 240);rectangle(375, 200, 455, 240);outtextxy(210, 205, _T("说 明"));outtextxy(390, 205, _T("开 始"));//**************** 检测鼠标事件 *********************MOUSEMSG m;while (1){m = GetMouseMsg();switch (m.uMsg){case WM_MOUSEMOVE:if ((m.x >= 195 && m.x <= 275) && (m.y >= 200 && m.y <= 240)){putimage(150, 250, &illustrate);}else{setfillcolor(BLACK);solidrectangle(150, 250, 450, 550);}break;case WM_LBUTTONDOWN:if ((m.x >= 375 && m.x <= 455) && (m.y >= 200 && m.y <= 240)){cleardevice();return;}break;}}}//***************** 游戏初始化界面 ****************
void outputPage2()
{IMAGE brick1;IMAGE brick2;IMAGE home;loadimage(&home, _T("home.jpg"), 50, 50);loadimage(&brick1, _T("wall1.jpg"), 25, 25);loadimage(&brick2, _T("wall2.jpg"), 25, 25);for (int i=0; i < 26; i++){ for(int j=0;j<26;j++){switch (map[i][j]){case 1:putimage(25 * j, 25 * i, &brick1); break;case 2:putimage(25 * j, 25 * i, &brick2); break;case 3:putimage(25 * j, 25 * i, &home); map[i][j] = 4;break;}}}return;
}
//********** 修改地图数组参数函数 ************
void map_par(TANK *tank,int n)
{map[tank->tank_y][tank->tank_x] = n;map[tank->tank_y + 1][tank->tank_x] = n;map[tank->tank_y][tank->tank_x + 1] = n;map[tank->tank_y + 1][tank->tank_x + 1] = n;
}
//*************** 坦克移动 *****************
int tankMove(TANK *tank, DIRECTION direction, IMAGE *img,int n)
{map_par(tank,0);setfillcolor(BLACK);solidrectangle(tank->tank_x * 25, tank->tank_y * 25, tank->tank_x * 25 + 50, tank->tank_y * 25 + 50); //覆盖坦克原来位置if (direction == UP){tank->tank_y --;}else if (direction == DOWN){tank->tank_y ++;}else if (direction == LEFT){tank->tank_x --;}else if (direction == RIGHT){tank->tank_x ++;}else{return 0;}map_par(tank, n);putimage(tank->tank_x * 25, tank->tank_y * 25, img); //输出坦克移动后位置}// ***************************** 使敌方坦克朝着目标的方向前进 *********************
DIRECTION enemyMove(TANK *Etank, int x, int y)
{int r = rand() % 100;if (y < Etank->tank_y ){if (x < Etank->tank_x){if(r<50)return UP;elsereturn LEFT;}else if(x > Etank->tank_x){if (r<50)return UP;elsereturn RIGHT;}else if(x == Etank->tank_x){if (map[Etank->tank_y - 1][Etank->tank_x] == 2){if (r < 50)return LEFT;elsereturn RIGHT;}return UP;}}else if (y > Etank->tank_y){if (x < Etank->tank_x){if (r<50)return DOWN;elsereturn LEFT;}else if(x > Etank->tank_x){if (r<50)return DOWN;elsereturn RIGHT;}else if (x == Etank->tank_x){if (map[Etank->tank_y + 2][Etank->tank_x] == 2){if (r < 50)return LEFT;elsereturn RIGHT;}return DOWN;}}else if (y == Etank->tank_y){if (x < Etank->tank_x)return LEFT;elsereturn RIGHT;}
}//********************** 游戏结束 ********************
void putGameOver()
{IMAGE gameOver;loadimage(&gameOver,_T("gameover.jpg"), 600, 400);for (int i = 0; i < 130; i++){cleardevice();putimage(25, i, &gameOver);Sleep(15);}system("pause");}
void victory()
{cleardevice();settextcolor(RED);settextstyle(300, 70, _T("微软雅黑"));outtextxy(80, 150, _T("Victory"));
}
void tankFire(TANK *tank, BULLET *bullet,bool need)
{if (bullet->state == 0) //坦克状态为0(即子弹已不存在)方可再次射击{if (need){PlaySound(_T("boom.wav"), NULL, SND_FILENAME | SND_ASYNC);}switch (tank->direction){case UP:bullet->bullet_x = tank->tank_x * 25 + 25;bullet->bullet_y = tank->tank_y * 25 - 3;break;case DOWN:bullet->bullet_x = tank->tank_x * 25 + 25;bullet->bullet_y = tank->tank_y * 25 + 53;break;case LEFT:bullet->bullet_x = tank->tank_x * 25 - 3;bullet->bullet_y = tank->tank_y * 25 + 25;break;case RIGHT:bullet->bullet_x = tank->tank_x * 25 + 53;bullet->bullet_y = tank->tank_y * 25 + 25;break;}bullet->state = 1;bullet->direction = DIRECTION(tank->direction);}
}
void putTankBoom(int x,int y)
{IMAGE img[8];/* char name[32];for (int i = 0; i < 8; i++){sprintf_s(name, 32, "blast%d.gif", i + i);loadimage(&img[i], name, 50, 50);} */loadimage(&img[0], _T("blast1.gif"), 50, 50);loadimage(&img[1], _T("blast2.gif"), 50, 50);loadimage(&img[2], _T("blast3.gif"), 50, 50);loadimage(&img[3], _T("blast4.gif"), 50, 50);loadimage(&img[4], _T("blast5.gif"), 50, 50);loadimage(&img[5], _T("blast6.gif"), 50, 50);loadimage(&img[6], _T("blast7.gif"), 50, 50);loadimage(&img[7], _T("blast8.gif"), 50, 50);for (int i = 0; i < 8; i++){putimage(x*25, y*25, &img[i]);Sleep(10);}
}
// *************************** 对子弹进行碰撞检测 **************************
void bulletMove(BULLET *bullet,bool &flag,int tell,TANK *tank,int &enemyAlive)
{IMAGE Wall2;loadimage(&Wall2, _T("wall2.jpg"), 25, 25);setfillcolor(BLACK);solidcircle(bullet->bullet_x, bullet->bullet_y, 2);int x1, y1, x2, y2;x1 = bullet->bullet_x / 25;y1 = bullet->bullet_y / 25;switch (bullet->direction) //判断子弹方向{case UP:bullet->bullet_y -= 3;x2 = x1 - 1;y2 = y1;break;case DOWN:bullet->bullet_y += 3;x2 = x1 - 1;y2 = y1;break;case LEFT:bullet->bullet_x -= 3;x2 = x1;y2 = y1 - 1;break;case RIGHT:bullet->bullet_x += 3;x2 = x1;y2 = y1 - 1;break;}if (bullet->bullet_x < 0 || bullet->bullet_x>650 || bullet->bullet_y < 0 || bullet->bullet_y>650){bullet->state = 0;return ;}
//*************** 子弹碰到可消除墙,消除墙,同时让子弹的状态变为 0 if (map[y1][x1] == 1 && map[y2][x2]==1){setfillcolor(BLACK);solidrectangle(x1 * 25, y1 * 25, x1 * 25 + 25, y1 * 25 + 25);solidrectangle(x2 * 25, y2 * 25, x2 * 25 + 25, y2 * 25 + 25);map[y1][x1] = 0;map[y2][x2] = 0;bullet->state = 0;return ;}else if (map[y1][x1] == 1 && map[y2][x2] == 0){setfillcolor(BLACK);solidrectangle(x1 * 25, y1 * 25, x1 * 25 + 25, y1 * 25 + 25);map[y1][x1] = 0;bullet->state = 0;return ;}else if (map[y1][x1] == 0 && map[y2][x2] == 1){setfillcolor(BLACK);solidrectangle(x2 * 25, y2 * 25, x2 * 25 + 25, y2 * 25 + 25);map[y2][x2] = 0;bullet->state = 0;return ;}else if (map[y1][x1] == 2 && map[y2][x2]==2) //子弹碰到不可消除墙,重新绘制白墙图片,否则墙上会有弹坑,并且令子弹状态为0{putimage(x1 * 25, y1 * 25, &Wall2);putimage(x2 * 25, y2 * 25, &Wall2);bullet->state = 0;return ;}else if (map[y1][x1] == 2 && map[y2][x2] != 2){putimage(x1 * 25, y1 * 25, &Wall2);bullet->state = 0;return ;}else if (map[y1][x1] != 2 && map[y2][x2] == 2){putimage(x2 * 25, y2 * 25, &Wall2);bullet->state = 0;return ;}if (map[y1][x1] == 4 && map[y2][x2] == 4){flag = 0;}if (tell) //如果tell 不为0 为我方坦克子弹碰撞检测{if ((map[y1][x1] >= 100 && map[y1][x1] <= 109) || (map[y2][x2] >= 100 && map[y2][x2] <= 109)){PlaySound(_T("hit.wav"), NULL, SND_FILENAME | SND_ASYNC);setfillcolor(BLACK);TANK *Tank = NULL;bullet->state = 0;if (map[y1][x1] >= 100 && map[y1][x1] <= 109){Tank = map[y1][x1] - 100 + tank;}else if(map[y2][x2] >= 100 && map[y2][x2] <= 109){Tank = map[y2][x2] - 100 + tank;}Tank->state = 0;map_par(Tank , 0);enemyAlive--;putTankBoom(Tank->tank_x, Tank->tank_y);solidrectangle(Tank->tank_x * 25, Tank->tank_y * 25, Tank->tank_x * 25 + 50, Tank->tank_y * 25 + 50);}}else //如果tell为0 为敌方坦克检测{if ((map[y1][x1] == 200 && map[y1][x1] == 200) || (map[y2][x2] == 200 && map[y2][x2] == 200)){bullet->state = 0;map_par(tank, 0);enemyAlive--;tank->state = 0;putTankBoom(tank->tank_x, tank->tank_y);flag = 0;return;}else if ((map[y1][x1] >= 100 && map[y1][x1] <= 109) || (map[y2][x2] >= 100 && map[y2][x2] <= 109)){bullet->state = 0;}}if (bullet->state == 1){setfillcolor(WHITE);solidcircle(bullet->bullet_x, bullet->bullet_y, 2);}
}// ******************************* 坦克移动控制 *****************************
void allTankMove(TANK *tank, DIRECTION direction, IMAGE *img,int n)
{switch (direction){ //坦克向前case UP:if (tank->direction == UP && (tank->tank_y - 1) >= 0 && map[tank->tank_y - 1][tank->tank_x] == 0 && map[tank->tank_y - 1][tank->tank_x + 1] == 0){tankMove(tank, UP, img,n);}else if (tank->direction != UP){tank->direction = UP;putimage(tank->tank_x * 25, tank->tank_y * 25, img);}break; //坦克向后case DOWN:if (tank->direction == DOWN && (tank->tank_y + 2) <= 25 && map[tank->tank_y + 2][tank->tank_x] == 0 && map[tank->tank_y + 2][tank->tank_x + 1] == 0){tankMove(tank, DOWN, img,n);}else if (tank->direction != DOWN){tank->direction = DOWN;putimage(tank->tank_x * 25, tank->tank_y * 25, img);}break; //坦克向左case LEFT:if (tank->direction == LEFT && (tank->tank_x - 1) >= 0 && map[tank->tank_y][tank->tank_x - 1] == 0 && map[tank->tank_y + 1][tank->tank_x - 1] == 0){tankMove(tank, LEFT, img,n);}else if (tank->direction != LEFT){tank->direction = LEFT;putimage(tank->tank_x * 25, tank->tank_y * 25, img);}break; //坦克向右case RIGHT:if (tank->direction == RIGHT && (tank->tank_x + 2) <= 25 && map[tank->tank_y][tank->tank_x + 2] == 0 && map[tank->tank_y + 1][tank->tank_x + 2] == 0){tankMove(tank, RIGHT, img,n);}else if (tank->direction != RIGHT){tank->direction = RIGHT;putimage(tank->tank_x * 25, tank->tank_y * 25, img);}break;}
}
//********************* 游戏开始控制我方坦克 ********************
void gameStart()
{srand((unsigned)time(NULL));int times = 0; //记录当前程序的休眠次数int enemyTotal = 0;int enemyAlive = 10;//PlaySound(TEXT("background.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//*********************** 我方坦克 ********************TANK myTankMove; //己方坦克BULLET myBulletMove; //己方子弹IMAGE myTank_img[4];loadimage(&myTank_img[UP], _T("tank_up.jpg"), 50, 50);loadimage(&myTank_img[DOWN], _T("tank_down.jpg"), 50, 50);loadimage(&myTank_img[LEFT], _T("tank_left.jpg"), 50, 50);loadimage(&myTank_img[RIGHT], _T("tank_right.jpg"), 50, 50);myTankMove.tank_x = 8; //初始化己方坦克位置myTankMove.tank_y = 24;myTankMove.direction = UP;myTankMove.state = true;map_par(&myTankMove, 200);putimage(myTankMove.tank_x*25, myTankMove.tank_y*25, &myTank_img[myTankMove.direction]); //初始化己方坦克方向myBulletMove.direction =DIRECTION (myTankMove.direction);myBulletMove.state = 0;//*************************** 敌方坦克 *********************TANK enemyTank[ENENMY_TANK_NUMBER];BULLET enemyBUllet[ENENMY_TANK_NUMBER];IMAGE enemyTank_img[4];loadimage(&enemyTank_img[UP], _T("enemy_tank_up.gif"), 50, 50);loadimage(&enemyTank_img[DOWN], _T("enemy_tank_down.gif"), 50, 50);loadimage(&enemyTank_img[LEFT], _T("enemy_tank_left.gif"), 50, 50);loadimage(&enemyTank_img[RIGHT], _T("enemy_tank_right.gif"), 50, 50);for (int i = 0; i < ENENMY_TANK_NUMBER; i++){enemyTank[i].tank_y = 0;if (i % 3 == 0){enemyTank[i].tank_x = 0;}else if (i % 3 == 1){enemyTank[i].tank_x = 12;}else if (i % 3 == 2){enemyTank[i].tank_x = 24;}enemyTank[i].state = true;enemyTank[i].direction = DOWN;enemyBUllet[i].direction = DIRECTION(enemyTank[i].direction);enemyBUllet[i].state = 0;}for (int i = 0; i < 3; i++){map_par(&enemyTank[i], 100 + i);putimage(enemyTank[i].tank_x * 25, enemyTank[i].tank_y * 25, &enemyTank_img[DOWN]);}enemyTotal = 3;// *************** 检测键盘事件 *******************bool Flag = 1;while (1){//其他坦克出场if (times % 400 == 0 && times != 0&&enemyTotal<= ENENMY_TANK_NUMBER){ //increase++;map_par(&enemyTank[enemyTotal], 100 + enemyTotal);putimage(enemyTank[enemyTotal].tank_x * 25, enemyTank[enemyTotal].tank_y * 25, &enemyTank_img[DOWN]);enemyTotal++;}// 控制地方坦克改变方向 if (times % 200 == 0){for (int i = 0; i < enemyTotal; i++){if (enemyTank[i].state){DIRECTION NowDirection;if (i % 2 == 0) //双数坦克攻击我方老巢{NowDirection = enemyMove(&enemyTank[i], 12, 24);allTankMove(&enemyTank[i], NowDirection, &enemyTank_img[NowDirection], 100 + i);}else //单数坦克攻击我方坦克{NowDirection = enemyMove(&enemyTank[i], myTankMove.tank_x, myTankMove.tank_y);allTankMove(&enemyTank[i], NowDirection, &enemyTank_img[NowDirection], 100 + i);}tankFire(&enemyTank[i], &enemyBUllet[i],false);}}}else if (times % 50 == 0) //控制敌方坦克移动{for (int i = 0; i < enemyTotal; i++){if (enemyTank[i].state){allTankMove(&enemyTank[i], DIRECTION(enemyTank[i].direction), &enemyTank_img[enemyTank[i].direction], 100 + i);}}}// ********************************* 我方坦克移动、射击控制 ****************************if (_kbhit()){char key = _getch(); //获取键盘输入值switch (key){case 'w': //坦克向前case 'W':allTankMove(&myTankMove, UP, &myTank_img[UP],200);break;case 's': //坦克向后case 'S':allTankMove(&myTankMove, DOWN, &myTank_img[DOWN],200);break;case 'a': //坦克向左case 'A':allTankMove(&myTankMove, LEFT, &myTank_img[LEFT],200);break;case 'd': //坦克向右case 'D':allTankMove(&myTankMove, RIGHT, &myTank_img[RIGHT],200);break;case 'p': //暂停游戏,按任意键开始case 'P':system("pause");break;case 'j': //射击case 'J':tankFire(&myTankMove, &myBulletMove,true);break;}}for (int i = 0; i < enemyTotal; i++){if (enemyBUllet[i].state == 1) //子弹存在时,更新敌方子弹飞行位置{bulletMove(&enemyBUllet[i], flag,0,&myTankMove,enemyAlive);if (!flag){Flag = 0;}}}if (!Flag)break;if (myBulletMove.state == 1) //子弹存在时,更新我方子弹飞行位置{bulletMove(&myBulletMove,flag,1,enemyTank,enemyAlive);if (!flag){break;}}if (enemyAlive == 0)break;times++;Sleep(15);}
}
int main()
{initgraph(650, 650); //初始化界面outputPage1();outputPage2();gameStart();if (!flag){putGameOver();}else{victory();}system("pause");closegraph();return 0;
}
下面为图片以及音频资源的百度网盘链接:
链接:https://pan.baidu.com/s/1oVby950ePiM0vF49DZPqnw
提取码:s5tt
将图片以及音频保存在生成的.cpp 所在的文件中即可
用C++语言实现坦克大战游戏相关推荐
- win10使用C语言运行坦克大战游戏(转载)
转自:C语言坦克大战 运行效果 注:本游戏win7可完美运行,win10的话,小坦克和子弹的打印会略有鬼畜(变形,只打印半边等).win10完美运行方案:点击屏幕左下角"开始"界面 ...
- 【java毕业设计】基于java+Socket+Eclipse的坦克大战游戏设计与实现(毕业论文+程序源码)——坦克大战游戏
基于java+Socket+Eclipse的坦克大战游戏设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+Socket+Eclipse的坦克大战游戏设计与实现,文章末尾附有本毕业设 ...
- 《Java语言程序设计——坦克大战单机游戏》源码以及实验报告
一.引言 游戏本身是一种娱乐方式,带给人无尽的乐趣,而且游戏行业的发展前景也将会是是带动周边相关行业的发展.为了去满足不同的游戏爱好者的要求,对做游戏开发的人的要求也会越来越高.本次Java语言程序设 ...
- 一文教你使用java开发一款坦克大战游戏
导读:随着人们对生活质量的要求一天比一天高,为了让人们更好地开掘自身的智慧,游戏就此进入了大众的视野,在人们的生活中有着重要的位置,已然变得必不可少.游戏产业推动高新技术不断升级,极大地促进了经济的增 ...
- c语言坦克大战程序设计,用纯C语言实现坦克大战
好久没给大家看有意思的C语言实现的代码了,今天给大家分享一个C语言实现坦克大战的游戏源码,依旧是纯C语言,点c文件,但是是在TC的环境下,运行效果截图如下: 上下左右控制方向,空格为发射炮弹,还带声音 ...
- c语言编写坦克大战设计报告,c语言编写坦克大战源代码
<c语言编写坦克大战源代码>由会员分享,可在线阅读,更多相关<c语言编写坦克大战源代码(10页珍藏版)>请在人人文库网上搜索. 1.include tank.h#include ...
- 基于Java的坦克大战游戏的设计与实现(论文+PPT+源码)
幻灯片1 基于Java的坦克大战游戏的设计与实现 幻灯片2 CONTENTS 1 4 设计工具与相关技术 详细设计 2 5 系统分析 结论 3 总体设计 幻灯片3 PPT模板下载:http://www ...
- 基于java的坦克大战游戏-计算机毕业设计
项目介绍 坦克游戏是在Eclipse环境下使用java编程.它的主要功能有:坦克能够四处移动,能够发射子弹打击敌人,敌人的坦克能够自由移动,能够产生模拟爆炸效果,能够产生障碍物,能够增长生命.本游戏有 ...
- Java练手项目2:基于Java的坦克大战游戏(学习Java必备!!!)
1.引言 随着社会和时代的进步,来自各个方面的压力让人没精打采,为了分解人们的压力,休养那变得疲顿的头脑和劳累的身心,特设计了坦克大战小游戏,游戏操作非常容易,只要将手指放在键盘上敲击相关的游戏键就可 ...
最新文章
- proc文件系统编程
- Leetcode 96. 不同的二叉搜索树 解题思路及C++实现
- 数学差、物理差、英语又烂的放牛娃,后来竟成了清华校长,还做出了诺奖级的研究成果!...
- div旋转45度_为什么不要买旋转式电动牙刷:欧乐B电动牙刷D12开箱与体验
- C++引用和指针区别
- Java — InputStream.read(),response.getOutputStream(),OutputStream().write【IO流】
- 元器件封装形式对照表_二三极管封装形式图表
- 常见并发工具的使用和原理解析——Condition(重点在第五节)
- 压力测试 - Apache JMeter使用教程
- JAVA毕业设计河南口腔医疗机构线上服务系统计算机源码+lw文档+系统+调试部署+数据库
- RINEX3.05格式中的主要更新
- MMA算法的推导及3D简支梁拓扑优化代码详解
- Arduino 传感器: 使用FSR402压力传感器检测压力
- MySQL Join 优化
- FPGA:实现快速傅里叶变换(FFT)算法
- 五、从命令行管理文件
- 工具类批量修改照片的名字
- csdn竟然还有这种神器!后悔没有早点知道!超好用的csdn插件,别再犹豫了,赶快入手吧!
- 简述同步和异步的区别
- 低代码,拯救“疯狂”的程序员
热门文章
- 防热服的设计数学建模_高温作业专用服装设计各位厂家提供点解题思路 2018年全国大学生数学建模A题...
- caxa图文档服务器未启动,05_CAXA图文档2013(实施指南)剖析.pptx
- 达梦数据库 图形化界面安装详细教程
- GHOSTXPSP3电脑爱好者V9.9装机版
- 双目摄像头(CSI-IMX219)的标定
- 微信小程序最全搜索功能
- 使不知宽高的元素水平垂直居中的方法
- 迟到的80后(程序人生与人生感悟)
- synchronized使用场景及区别
- 【转】对于HttpClient和HtmlUnit的理解