《飞机大战》这是一款经典飞行射击类游戏,为玩家呈现一场不一样射击体验。简单的触屏操作,触屏按住随意一个地方,左右移动,便可自动攻击敌人,上下移动亦可躲避强敌。玩家在游戏中要做的就是驾驶着最新战机,向敌人发起冲击。
今天我就用C++带大家一步步去完成风靡全球的小程序飞机大战小游戏~
PS:要安装easyx图形库哦 #include<easyx.h>
开发工具为VS2013
在此之前呢,和大家说明一下,因为这是一个比较大的项目了,所以展示所有代码会有些困难,所以我裁剪了主要的大部分代码,主要目的是让大家明白实现这个项目的逻辑思路,希望大家可以理解,完整代码/编译器/图形库在文章最下方获取哦
正片开始:
第一步: 打开vs2013,创建一个项目,并将准备好的素材资源放到同级目录下(素材可以在文章最下方领取),如图:
第二步:写出基本框架,看自己背景图片的像素,创建一个相同像素的图形窗口,并把背景图片加上:
第三步:设置音乐,及玩家、敌机、子弹,开启双缓冲绘图:
#include<stdio.h>
#include<graphics.h>//包含图形库头文件 easyx
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")//加载多媒体设备库
#define WIN_WIDTH 591
#define WIN_HEIGHT 864
#define PLAYER_BULLET 15 //玩家子弹数量
#define ENEMYPLANE_NUM 10
//定义变量 int a=666;
//定义一个图片
IMAGE bk;
IMAGE img_player[4];
IMAGE img_bullet[2];
IMAGE img_enemy[2];
struct Plane
{
int x;
int y;
bool flag;//..是否死亡
int width;
int height;
}player, pbull[PLAYER_BULLET], enemy[ENEMYPLANE_NUM];
//时间的变化量
DWORD t1, t2;
//分模块处理,专门的事情,准们的函数做
void GameInit()
{
//1,创建一个图形窗口
initgraph(WIN_WIDTH, WIN_HEIGHT);
//设置随机数种子
srand(GetTickCount());
//2,贴背景图片
//2.1加载图片到bk里面
loadimage(&bk, "./images/background.jpg");
loadimage(&img_player[0], "./images/planeNormal_1.jpg");
loadimage(&img_player[1], "./images/planeNormal_2.jpg");
loadimage(&img_player[2], "./images/planeBoom_1.jpg");
loadimage(&img_player[3], "./images/planeBoom_2.jpg");
loadimage(&img_bullet[0], "./images/bullet1.jpg");
loadimage(&img_bullet[1], "./images/bullet2.jpg");
loadimage(&img_enemy[0], "./images/enemy_1.jpg");
loadimage(&img_enemy[1], "./images/enemy_2.jpg");
//3,播放音乐 首先打开音乐,然后播放音乐
mciSendString("open ./images/game_music.mp3 alias BGM", 0, 0, 0);
mciSendString("play BGM repeat", 0, 0, 0);
//初始化玩家数据
player.height = 120;
player.width = 117;
player.x = WIN_WIDTH / 2 - player.width / 2;
player.y = WIN_HEIGHT - player.height;
player.flag = true;
//初始化子弹
for (int i = 0; i < PLAYER_BULLET; i++)
{
pbull[i].flag = false;
pbull[i].height = 24;
pbull[i].width = 19;
}
//初始化时间变量
t1 = t2 = GetTickCount();
//初始化敌机
for (int i = 0; i < ENEMYPLANE_NUM; i++)
{
enemy[i].flag = false;
enemy[i].width = 52;
enemy[i].height = 39;
}
}
//游戏绘制函数
void GameDarw()
{
//双缓冲绘图,防止画面闪烁
BeginBatchDraw();
//2.2输出背景图片
putimage(0, 0, &bk);
//透明贴图
if (player.flag)
{
putimage(player.x, player.y, &img_player[0], NOTSRCERASE);
putimage(player.x, player.y, &img_player[1], SRCINVERT);
}
//绘制玩家子弹
for (int i = 0; i < PLAYER_BULLET; i++)
{
if (pbull[i].flag)
{
putimage(pbull[i].x, pbull[i].y, &img_bullet[0], NOTSRCERASE);
putimage(pbull[i].x, pbull[i].y, &img_bullet[1], SRCINVERT);
}
}
//绘制敌机
for (int i = 0; i < ENEMYPLANE_NUM; i++)
{
if (enemy[i].flag)
{
putimage(enemy[i].x, enemy[i].y, &img_enemy[0], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &img_enemy[1], SRCINVERT);
}
}
EndBatchDraw();
}
//产生玩家子弹
void CreatBullet()
{
for (int i = 0; i < PLAYER_BULLET; i++)
{
if (!pbull[i].flag)
{
pbull[i].x = player.x+53;
pbull[i].y = player.y;
pbull[i].flag = true;
break;
}
}
}
//生成敌机
void CreateEnemy()
{
for (int i = 0; i < ENEMYPLANE_NUM; i++)
{
if (!enemy[i].flag)
{
enemy[i].x = rand() % (WIN_WIDTH - enemy[i].width);
enemy[i].y =0;
enemy[i].flag = true;
break;
}
}
}
void EnemyMove(int speed)
{
for (int i = 0; i < ENEMYPLANE_NUM; i++)
{
if (enemy[i].flag)
{
enemy[i].y += speed;
if (enemy[i].y>WIN_HEIGHT)
{
enemy[i].flag = false;
}
}
}
}
//操控飞机,开..
void KeyControl(int speed)
{
//按键处理,用getch()
//向上移动 边界处理
if(GetAsyncKeyState(VK_UP) && player.y>=0)
{
player.y -= speed;
}
//向下移动
if (GetAsyncKeyState(VK_DOWN) && player.y+player.height<=WIN_HEIGHT)
{
player.y += speed;
}
//向左移动
if (GetAsyncKeyState(VK_LEFT) && player.x+player.width/2>=0)
{
player.x -= speed;
}
//向右移动
if (GetAsyncKeyState(VK_RIGHT) && player.x+player.width/2<=WIN_WIDTH)
{
player.x += speed;
}
//发射子弹
if (GetAsyncKeyState(VK_SPACE) && t2-t1>200)
{
mciSendString("close gun", 0, 0, 0);
mciSendString("open ./images/f_gun.mp3 alias gun", 0, 0, 0);
mciSendString("play gun", 0, 0, 0);
//产生一个子弹
CreatBullet();
t1 = t2;
}
t2 = GetTickCount();
}
//生成敌机
void CreateEnemy()
{
for (int i = 0; i < ENEMYPLANE_NUM; i++)
{
if (!enemy[i].flag)
{
enemy[i].x = rand() % (WIN_WIDTH - enemy[i].width);
enemy[i].y =0;
enemy[i].flag = true;
break;
}
}
}
void EnemyMove(int speed)
{
for (int i = 0; i < ENEMYPLANE_NUM; i++)
{
if (enemy[i].flag)
{
enemy[i].y += speed;
if (enemy[i].y>WIN_HEIGHT)
{
enemy[i].flag = false;
}
}
}
}
第四步:设置子弹的移动,鼠标操控飞机:
//玩家子弹的移动
void BulletMove(int speed)
{
for (int i = 0; i < PLAYER_BULLET; i++)
{
if (pbull[i].flag)
{
pbull[i].y -= speed ;
if (pbull[i].y < 0)
{
pbull[i].flag = false;
}
}
}
}
//操控飞机,开..
void KeyControl(int speed)
{
//按键处理,用getch()
//向上移动 边界处理
if(GetAsyncKeyState(VK_UP) && player.y>=0)
{
player.y -= speed;
}
//向下移动
if (GetAsyncKeyState(VK_DOWN) && player.y+player.height<=WIN_HEIGHT)
{
player.y += speed;
}
//向左移动
if (GetAsyncKeyState(VK_LEFT) && player.x+player.width/2>=0)
{
player.x -= speed;
}
//向右移动
if (GetAsyncKeyState(VK_RIGHT) && player.x+player.width/2<=WIN_WIDTH)
{
player.x += speed;
}
//发射子弹
if (GetAsyncKeyState(VK_SPACE) && t2-t1>200)
{
mciSendString("close gun", 0, 0, 0);
mciSendString("open ./images/f_gun.mp3 alias gun", 0, 0, 0);
mciSendString("play gun", 0, 0, 0);
//产生一个子弹
CreatBullet();
t1 = t2;
}
t2 = GetTickCount();
}
第五步:设置游戏开始,判断子弹是否击中:
//开始...
void PlayPlane()
{
//每个敌军和每个子弹都要比较
for (int i = 0; i < ENEMYPLANE_NUM; i++)
{
if (!enemy[i].flag)
continue;
//遍历子弹数组
for (int k = 0; k < PLAYER_BULLET; k++)
{
if (!pbull[k].flag)
continue;
//判断子弹是否击中敌机
if (pbull[k].x>enemy[i].x && pbull[k].x<enemy[i].x+enemy[i].width &&
pbull[k].y>enemy[i].y && pbull[k].y<enemy[i].y+enemy[i].height)
{
//击中了,敌机要消失,子弹也要消失
enemy[i].flag = false;
pbull[i].flag = false;
//分数+=10;
}
}
}
}
int main()
{
GameInit();
while (1)
{
GameDarw();
KeyControl(1);
BulletMove(1);
if (rand() % 30 == 1)
{
CreateEnemy();
}
PlayPlane();
EnemyMove(1);
}
getchar();
return 0;
}
好啦,重要的基础代码就这些~需要完整源码对照的同学可以点击文章末链接群领取,飞机大战/雷霆战机教程就到此结束啦,后续我会发布更多的项目源码以及学习资料,希望大家可以持续关注,想要C/C++学习资料以及完整源码素材图形库开发工具等的可以加群【639681529】了解,或者有问题也可以进群提问,希望大家可以在这里得到自己想要的知识,也希望如果对你有所帮助的话可以多多关注点赞评论,有建议也可以在评论区提出,谢谢大家的支持!
点击下方链接进群:
源码素材编译器图形库还有各种学习资料都在这里等你哦~https://jq.qq.com/?_wv=1027&k=ne3yBn5V