代码如下:
#include
#include
#include //图形库头文件
#include //多媒体接口
#pragma comment(lib,"winmm.lib")//加载库文件
#define High 580 //窗口长
#define Weight 850 //窗口宽
#define bullet_NUM 100 //设定子弹数量
#define enemy_NUM 15 //设定敌机数量
using namespace std;
struct Image //定义图形变量结构体
{
IMAGE backgrand; //定义背景图片
IMAGE player[2]; //定义player飞机图片
IMAGE bullet[2]; //定义子弹图片
IMAGE enemy[4]; //定义敌机图片
IMAGE explode[2]; //定义坠毁player飞机图片
}ss; //IMAGE 定义一个图形变量
struct make //定义对象数据结构体
{
double x; //x坐标
double y; //y坐标
int hp; //生命值
bool flag; //存货状态
union MyUnion //联合 、使用同一块内存、节省内存
{
int type; //敌机独有属性,类型
int score; //玩家独有属性,得分
}un;
}player,bullet[bullet_NUM],enemy[enemy_NUM],explode;
enum TYPE //将敌机分为两种类型
{
SMALL,
BIG,
};
DWORD t1, t2,t3,t4;
void Init()//----------------------//初始化数据
{
//设定随机数种子
srand(GetTickCount());
t1 = t2=t3=t4 = GetTickCount();//获取系统开机到当前所经过的毫秒数
//音乐播放
mciSendString("open ./PlanePicture/game_music.mp3 alias BGM",0,0,0); //加载音乐地址、导入音乐
mciSendString("play BGM repeat", 0, 0, 0); //播放音乐
//加载图片地址、导入图片
//导入背景
loadimage(&ss.backgrand, "./PlanePicture/background.jpg");
//导入player飞机
loadimage(&ss.player[0], "./PlanePicture/player_2.jpg");
loadimage(&ss.player[1], "./PlanePicture/player_1.jpg");
//导入子弹
loadimage(&ss.bullet[0], "./PlanePicture/bullet_1.jpg");
loadimage(&ss.bullet[1], "./PlanePicture/bullet_2.jpg");
//导入敌机
loadimage(&ss.enemy[0], "./PlanePicture/enemys_1.jpg");//小敌机
loadimage(&ss.enemy[1], "./PlanePicture/enemys_2.jpg");
loadimage(&ss.enemy[2], "./PlanePicture/enemyb_1.jpg");//大敌机
loadimage(&ss.enemy[3], "./PlanePicture/enemyb_2.jpg");
//导入战毁机
loadimage(&ss.explode[0], "./PlanePicture/Explode_1.jpg");
loadimage(&ss.explode[1], "./PlanePicture/Explode_2.jpg");
//初始化玩家
player.flag = true;
player.hp = 15;
player.x = Weight / 2-200;
player.y = High-100;
player.un.score = 0;
//初始化敌机
for (int i = 0; i < enemy_NUM; i++)
{
enemy[i].flag = false;
}
//初始化子弹
for (int i = 0; i < bullet_NUM; i++)
{
bullet[i].flag = false;
}
}
void Show()//-------------------------------//输出数据
{
//输出背景
putimage(0, 0, &ss.backgrand);
//输出分数、输出生命值
settextstyle(20, 0, "华文行楷"); //设置字体样式
settextcolor(BLUE); //设置字体颜色
setbkmode(TRANSPARENT); //设置背景为透明
TCHAR str [50] = {0};
TCHAR sta[50] = { 0 };
_stprintf_s(str, "经验值:%d", player.un.score);
_stprintf_s(sta, "生命值:%d", player.hp);
outtextxy(20, 20, str);
outtextxy(20, 40, sta);
if (explode.flag == true)
{
settextstyle(60, 0, "华文行楷"); //设置字体样式
settextcolor(RED);
outtextxy(160, 300, "您 已 阵 亡");
outtextxy(140, 360, "所得");
outtextxy(250, 360, str);
}
//输出飞机
if (player.flag == true) {
putimage(player.x, player.y, &ss.player[0], NOTSRCERASE);
putimage(player.x, player.y, &ss.player[1], SRCINVERT);
}
//输出战毁机
if (explode.flag == true)
{
putimage(explode.x, explode.y, &ss.explode[0], NOTSRCERASE);
putimage(explode.x, explode.y, &ss.explode[1], SRCINVERT);
}
//输出子弹
for (int i = 0; i < bullet_NUM; i++)
{
if (bullet[i].flag == true)
{
putimage(bullet[i].x, bullet[i].y, &ss.bullet[0], NOTSRCERASE);
putimage(bullet[i].x, bullet[i].y, &ss.bullet[1], SRCINVERT);
}
}
//输出敌机
for (int i = 0; i < enemy_NUM; i++)
{
if (enemy[i].flag == true)
{
if(enemy[i].un.type==TYPE::SMALL){
putimage(enemy[i].x, enemy[i].y, &ss.enemy[0], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &ss.enemy[1], SRCINVERT);
}
else {
putimage(enemy[i].x, enemy[i].y, &ss.enemy[2], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &ss.enemy[3], SRCINVERT);
}
}
}
}
void BulletCreat()//------------------------------生成子弹
{
for (int i = 0; i < bullet_NUM; i++)
{
if (bullet[i].flag == false)
{
bullet[i].flag = true;
bullet[i].x = player.x + 45;
bullet[i].y = player.y-2;
break; //确保每按一下空格键生成一发子弹
}
}
}
void BulletMove(int speed)//----------------------控制子弹移动
{
for (int i = 0; i < bullet_NUM; i++)
{
if (bullet[i].flag == true)
{
bullet[i].y -= speed;
if (bullet[i].y < 0)
{
bullet[i].flag = false;
}
}
}
}
void EnemyType(int i)//------------------------------//给随机生成的敌机分类型
{
if (rand() % 5 == 0) //1/5的概率生成大敌机
{
enemy[i].un.type = TYPE::BIG;
enemy[i].hp = 3;
}
else {
enemy[i].un.type = TYPE::SMALL;
enemy[i].hp = 1;
}
}
void EnemyCreat()//---------------------------------生成敌机
{
for (int i = 0; i < enemy_NUM; i++)
{
if (enemy[i].flag==0)
{
enemy[i].flag = true;
enemy[i].x = rand() % (Weight - 100);
enemy[i].y = 0;
EnemyType(i);
break;
}
}
}
void EnemyMove(double speed)//-------------------------------//控制敌机移动
{
for (int i = 0; i < enemy_NUM; i++)
{
if (enemy[i].flag == true)
{
enemy[i].y += speed;
if (enemy[i].y>=High+130)
{
enemy[i].flag = false;
}
}
}
}
void Move(double speed)//-----------------------------//控制移动
{
//控制player飞机移动
if (GetAsyncKeyState(VK_RIGHT)&&player.x+320<=Weight) //
{
player.x += speed;
}
if (GetAsyncKeyState(VK_LEFT) && player.x + 60 >= 0) //
{
player.x -= speed;
}
if (GetAsyncKeyState(VK_UP) && player.y >= 0) //
{
player.y -= speed;
}
if (GetAsyncKeyState(VK_DOWN) && player.y-20<=High) //
{
player.y += speed;
}
//控制子弹移动
if (GetAsyncKeyState(VK_SPACE)&&t2-t1>=400)
{
BulletCreat(); //生成子弹
//播放射击音乐
mciSendString("close hh",0,0,0); //确保每次都能播放
mciSendString("open ./PlanePicture/f_gun.mp3 alias hh", 0, 0, 0); //导入音乐
mciSendString("play hh",0,0,0); //播放音乐
t1 = t2;
}
t2 = GetTickCount();
BulletMove(speed); //控制子弹移动
//敌机的生成与移动
if (t4 - t3 >= rand() % 600 + 600)
{
EnemyCreat(); //生成敌机
t3 = t4;
}
t4 = GetTickCount();
EnemyMove(0.5); //控制敌机移动
}
void PlayerShot()//----------------------------------------//射中敌机/player飞机摧毁
{
for (int i = 0; i < enemy_NUM; i++)
{
for (int j = 0; j < bullet_NUM; j++)
{
//当player飞机撞到敌机
if (enemy[i].flag == true &&player.flag == true)
{
if (enemy[i].x + 50 >= player.x && enemy[i].x <= player.x + 117 && enemy[i].y + 39 >= player.y && enemy[i].y <= player.y && enemy[i].un.type == TYPE::SMALL)//当player飞机撞到小敌机
{
enemy[i].flag = false;
player.hp -= 1;
}
if (enemy[i].x <= player.x + 117 && enemy[i].x + 148 >= player.x && enemy[i].y + 104 >= player.y && enemy[i].y <= player.y + 120 && enemy[i].un.type == TYPE::BIG)//当player飞机撞到大敌机
{
enemy[i].flag = false;
player.hp -= 3;
}
}
//当子弹射中敌机
if (enemy[i].flag == true && bullet[j].flag == true)
{
if (enemy[i].x + 50 >= bullet[j].x && enemy[i].x <= bullet[j].x + 19 && enemy[i].y + 39 >= bullet[j].y && enemy[i].y <= bullet[j].y && enemy[i].un.type == TYPE::SMALL)//当击中小敌机
{
enemy[i].flag = false; //小敌机消失
bullet[j].flag = false; //子弹消失
player.un.score += 1;
}
if (enemy[i].x + 104 >= bullet[j].x && enemy[i].x <= bullet[j].x + 19 && enemy[i].y + 148 >= bullet[j].y && enemy[i].y <= bullet[j].y && enemy[i].un.type == TYPE::BIG)//当击中小敌机
{
bullet[j].flag = false; //子弹消失
enemy[i].hp -= 1;
if (enemy[i].hp <= 0) {
enemy[i].flag = false; //大敌机消失
player.un.score += 3;
}
}
}
}
}
}
void Search()//-----------------------------//查看player飞机是否阵亡
{
if (player.hp <= 0)
{
explode.flag = true;
explode.x = player.x;
explode.y = player.y;
player.flag = false; //player飞机阵亡
mciSendString("close hhh", 0, 0, 0);
mciSendString("open ./PlanePicture/roledie.mp3 alias hhh", 0, 0, 0); //导入音乐
mciSendString("play hhh", 0, 0, 0);
}
}
int main()
{
initgraph(High,Weight); //设定窗口
Init(); //初始化数据
BeginBatchDraw(); //开启双缓冲、防止图片频闪,在内存中存好
while (1)
{
Show(); //输出数据
//Select();
Move(1); //控制移动
PlayerShot(); //射中敌机/player飞机摧毁
FlushBatchDraw(); //打开图片
Search(); //查看player飞机是否阵亡
}
EndBatchDraw(); //结束图片放映
return 0;
}
头文件以及库函数:
主函数:
各函数所产生的作用:
Initgraph:设定长为Weight,宽为High的窗口
Init():初始化数据,即导入文件中的图片,给各元素赋初值
While():保证该页面不断刷新、不断更改数据,即保证游戏的流畅进行
Show():输出各项数据,如显示背景、输出飞机子弹图片
Move():控制飞机、子弹的移动
PlayerShow():子弹射中敌机/player飞机撞到敌机
Search():判断player飞机是否阵亡
BeginBatchDraw():开启双缓存、防止图片频闪,将其存储在内存中
FlushBatchDraw():打开内存中的图片
EndBatchDraw():结束图片的放映