C语言/C++实战项目雷霆飞机(代码改进)

简介: C语言/C++实战项目雷霆飞机(代码改进)

上代码

#include <stdio.h>
#include <easyx.h>
#include <time.h>
#include <Mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define WIDTH   600
#define HEIGHT  850
#define bullet_max  5000      //我方飞机子弹最大量
#define enemy_bul_max 150  //敌方飞机子弹最大量
#define enemy1_hp 30          //敌方飞机生命值
#define enemy2_hp 50
#define enemy3_hp 30
#define enemy4_hp 10000
#define enemy5_hp 12000
IMAGE bgimg;                                //主界面图片
IMAGE bkimg0;                               
IMAGE bkimg1;
IMAGE bkimg2;
IMAGE bkimg3;
IMAGE Myplane[2];                           //飞机图片个数
IMAGE Enemy1[2];                            //小飞机
IMAGE Enemy2[2];                            //中飞机
IMAGE Enemy2Bullet[2];                      //中飞机子弹
IMAGE Enemy3[2];                            //横行飞机
IMAGE Enemy3Bullet[2];                      //横行飞机子弹
IMAGE Enemy4[2];                            //第二关boss
IMAGE Enemy4Bullet[2];                      //第二关boss子弹
IMAGE Enemy5[2];                            //第三关boss
IMAGE Enemy5Bullet[2];                      //第三关boss子弹
IMAGE Lighter[2];                            //飞机大招
//加载图片
void loadimg();
//初始化游戏
void initGame();
//加载主界面
void DrawInterface();
//绘制游戏
void DrawGame();
//更新背景
void UpdateBack();
//更新飞机
void UpdatePlane();
//绘制子弹
void DrawBullet();
//绘制雷霆
void DrawLighter();
//子弹移动
void MoveBullet();
//雷霆移动
void MoveLighter();
//关卡转换
void level_change();
//失败界面
void FailMenu();
//结束界面
void EndMenu();
//进入每一关的初始分数
void Judge();
//敌机移动机制
void EnemyMove();
//判定子弹碰撞敌机
void Bulletcrush();
//判定大招攻击敌机
void LghterCrush();
//创建敌机
void EnemyCreat_L1();
void EnemyCreat_L2();
void EnemyCreat_L3();
//敌机清除
void EnemyClean();
//子弹清除
void BulletClean();
//敌机产生子弹
void Enemy_Bullet_Creat();
//敌机子弹移动
void Enemy_Bullet_Move();
//敌机子弹打击
void Enemy_Bullet_Crush();
//碰撞敌机
void EnemyCrush();
//显示分数血量
void Print();
//定义我方飞机类
struct Myplane
{
  int   x;
  int   y;
  int   hp;
  int   width = 95;
  int   height = 90;
  bool  isExit;                            //飞机是否存在
}myplane[1]; 
IMAGE Bullet[2];                             //子弹图片个数
//定义我方飞机子弹类
struct Bullet
{
  int   x1;
  int   y1;
  int   x2;
  int   y2;
  bool  isExit;                             //是否存在
} bullet[bullet_max], lighter[1];                         //子弹个数
//定义敌方飞机类
struct Enemyplane
{
  double   x;
  double   y;
  int   hp;
  int   width;
  int   height;
  bool  isExit;
}enemy1[10], enemy2[5], enemy3[5], enemy4[1], enemy5[1];
//定义敌方飞机子弹类
struct Enemybullet
{
  int   x;
  int   y;
  int   hp;
  int   atk;                                //用于后面判断打击
  int   width;
  int   height;
  bool  isExit;
} enemy2_bullet[enemy_bul_max], enemy3_bullet[enemy_bul_max], enemy4_bullet[enemy_bul_max], enemy5_bullet[enemy_bul_max];
int   bky0, bky1,bk1y0,bk1y1,bk2y0,bk2y1;
int score = 0;                                //5000通过第一关,8000分第二关boss出现,12000分进入第三关
int enemy2_direct0 = 1;//用于下面判断敌机向左向右移动
int enemy2_direct1 = 1;
int enemy2_direct2 = 1;
int enemy3_direct0 = 1;
int enemy3_direct1 = 1;
int enemy3_direct2 = 1;
int enemy4_direct0 = 1;
int level_change_count = 1;
int main();
int level()
{
  if (score > 5000 && score < 12000)
  {
    return 2;//第二关
  }
  else if (score < 5000)
  {
    return 1;//返回第一关
  }
  else if (score > 12000)
  {
    return 3;//第三关
  }
  if (score > 17000)
  {
    return 4;//结束界面
  }
}
void loadimg()
{
  //主界面图片
  loadimage(&bgimg, L"bg.jpg");
  //关卡背景图片
  if (level() == 1)
  {
    loadimage(&bkimg0, L"bk.jpg");
  }
  else if (level() == 2)
  {
    loadimage(&bkimg1, L"bk1.jpg");
  }
  else {
    loadimage(&bkimg2, L"bk2.jpg");
  }
  //我方飞机图片
  loadimage(&Myplane[0], L"uiPlane0.jpg");
  loadimage(&Myplane[1], L"uiPlane1.jpg");
  //加载子弹
  loadimage(&Bullet[0], L"bullet0.jpg");
  loadimage(&Bullet[1], L"bullet1.jpg");
  //敌机1
  loadimage(&Enemy1[0], L"enemy10.jpg");
  loadimage(&Enemy1[1], L"enemy11.jpg");
  //敌机2
  loadimage(&Enemy2[0], L"enemy20.jpg");
  loadimage(&Enemy2[1], L"enemy21.jpg");
  loadimage(&Enemy2Bullet[0], L"enemybullet10.jpg");
  loadimage(&Enemy2Bullet[1], L"enemybullet11.jpg");
  //敌机3
  loadimage(&Enemy3[0], L"enemy10.jpg");
  loadimage(&Enemy3[1], L"enemy11.jpg");
  loadimage(&Enemy3Bullet[0], L"enemybullet20.jpg");
  loadimage(&Enemy3Bullet[1], L"enemybullet21.jpg");
  //敌机4
  loadimage(&Enemy4[0], L"enemy30.jpg");
  loadimage(&Enemy4[1], L"enemy31.jpg");
  loadimage(&Enemy4Bullet[0], L"enemybullet40.jpg");
  loadimage(&Enemy4Bullet[1], L"enemybullet41.jpg");
  //敌机5
  loadimage(&Enemy5[0], L"enemy50.jpg");
  loadimage(&Enemy5[1], L"enemy51.jpg");
  loadimage(&Enemy5Bullet[0], L"enemybullet50.jpg");
  loadimage(&Enemy5Bullet[1], L"enemybullet51.jpg");
  //飞机大招
  loadimage(&Lighter[0], L"lighter0.jpg");
  loadimage(&Lighter[1], L"lighter1.jpg");
}
bool Timer(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;//申请静态变量,DWORD实质就是一个无符号长整型类型
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
bool Timer1(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
void DrawGame()
{
  //双缓冲绘图,防止闪屏
  BeginBatchDraw();
  loadimg();
  //绘制关卡背景
  if (level() == 1)
  {
    putimage(0, bky0, &bkimg0);
    putimage(0, bky1, &bkimg0);
  }
  else if (level() == 2)
  {
    putimage(0, bk1y0, &bkimg1);
    putimage(0, bk1y1, &bkimg1);
  }
  else
  {
    putimage(0, bk2y0, &bkimg2);
    putimage(0, bk2y1, &bkimg2);
  }
  //绘制我方飞机子弹(透明贴图)
  int i;
  for (i = 0; i < 1; i++)
  {
    if (myplane[i].isExit)                       //如果飞机存在,则绘制飞机
    {
      putimage(myplane[i].x, myplane[i].y, &Myplane[0], SRCPAINT);
      putimage(myplane[i].x, myplane[i].y, &Myplane[1], SRCAND);
    }
  }
  for (int i = 0; i < bullet_max; i++)
  {                                           //遍历所有子弹,若子弹存在则贴图
    if (bullet[i].isExit)
    {                                       //SRCPAINT三元光栅操作码(用于实现透明贴图)
      putimage(bullet[i].x1, bullet[i].y1, &Bullet[0], SRCPAINT);
      putimage(bullet[i].x1, bullet[i].y1, &Bullet[1], SRCAND);
      putimage(bullet[i].x2, bullet[i].y2, &Bullet[0], SRCPAINT);
      putimage(bullet[i].x2, bullet[i].y2, &Bullet[1], SRCAND);
    }
  }
  for (i = 0; i < 10; i++)//敌机1
  {
    if (enemy1[i].isExit)
    {
      putimage(enemy1[i].x, enemy1[i].y, &Enemy1[0], SRCPAINT);
      putimage(enemy1[i].x, enemy1[i].y, &Enemy1[1], SRCAND);
    }
  }
  for (i = 0; i < 5; i++)//敌机2
  {
    if (enemy2[i].isExit)
    {
      putimage(enemy2[i].x, enemy2[i].y, &Enemy2[0], SRCPAINT);
      putimage(enemy2[i].x, enemy2[i].y, &Enemy2[1], SRCAND);
    }
  }
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy2_bullet[i].isExit)
    {
      putimage(enemy2_bullet[i].x, enemy2_bullet[i].y, &Enemy2Bullet[0], SRCPAINT);
      putimage(enemy2_bullet[i].x, enemy2_bullet[i].y, &Enemy2Bullet[1], SRCAND);
    }
  }
  for (i = 0; i < 5; i++)//敌机3
  {
    if (enemy3[i].isExit)
    {
      putimage(enemy3[i].x, enemy3[i].y, &Enemy3[0], SRCPAINT);
      putimage(enemy3[i].x, enemy3[i].y, &Enemy3[1], SRCAND);
    }
  }
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy3_bullet[i].isExit)
    {
      putimage(enemy3_bullet[i].x, enemy3_bullet[i].y, &Enemy3Bullet[0], SRCPAINT);
      putimage(enemy3_bullet[i].x, enemy3_bullet[i].y, &Enemy3Bullet[1], SRCAND);
    }
  }
  for (i = 0; i < 1; i++)
  {
    if (enemy4[i].isExit)
    {
      putimage(enemy4[i].x, enemy4[i].y, &Enemy4[0], SRCPAINT);
      putimage(enemy4[i].x, enemy4[i].y, &Enemy4[1], SRCAND);
    }
  }
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy4_bullet[i].isExit)
    {
      putimage(enemy4_bullet[i].x, enemy4_bullet[i].y, &Enemy4Bullet[0], SRCPAINT);
      putimage(enemy4_bullet[i].x, enemy4_bullet[i].y, &Enemy4Bullet[1], SRCAND);
    }
  }
  for (i = 0; i < 1; i++)
  {
    if (enemy5[i].isExit)
    {
      putimage(enemy5[i].x, enemy5[i].y, &Enemy5[0], SRCPAINT);
      putimage(enemy5[i].x, enemy5[i].y, &Enemy5[1], SRCAND);
    }
  }
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy5_bullet[i].isExit)
    {
      putimage(enemy5_bullet[i].x, enemy5_bullet[i].y, &Enemy5Bullet[0], SRCPAINT);
      putimage(enemy5_bullet[i].x, enemy5_bullet[i].y, &Enemy5Bullet[1], SRCAND);
    }
  }
  for (i = 0; i < 1; i++)
  {
    if (lighter[i].isExit)
    {
      putimage(lighter[i].x1, lighter[i].y1, &Lighter[0], SRCPAINT);
      putimage(lighter[i].x1, lighter[i].y1, &Lighter[1], SRCAND);
    }
  }
  EndBatchDraw();
}
bool Timer_enemycreat(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
bool Timer2(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
bool Timer_enemy2_bullet_creat(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
bool Timer_enemy3_bullet_creat(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
bool Timer_enemy4_bullet_creat(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
bool Timer_enemy5_bullet_creat(int ms)//定时器
{
  static DWORD t1 = 0, t2 = 0;
  if (t2 - t1 > ms)
  {
    t1 = t2;
    return true;
  }
  t2 = clock();
  return false;
}
void EnemyMove()
{
  int i;
  for (i = 0; i < 10; i++)//最小敌机前进,不发射子弹
  {
    if (enemy1[i].isExit == true)//如果敌机1存在
    {
      enemy1[i].y += 0.5;
      if (enemy1[i].y > HEIGHT)
      {
        enemy1[i].isExit = false;//如果敌机1出界则判定为不存在
      }
    }
  }
  for (i = 0; i < 5; i++)//中飞机,缓慢前进,并发射子弹
  {
    if (enemy2[i].isExit == true)
    {
      enemy2[i].y += 0.7;
      if (enemy2[i].y > HEIGHT)
      {
        enemy2[i].isExit = false;
      }
    }
  }
  for (i = 0; i < 5; i++)//横行飞机,左右移动,偶尔前进,并发射子弹
  {
    if (enemy3[i].isExit == true)
    {
      if (i == 0)//型号为0的飞机,奇数向左,偶数向右,且先向左
      {
        if (enemy3[i].y < HEIGHT / 2)
        {
          enemy3[i].y += 10;
        }
        else
        {
          if (enemy3_direct0 % 2 == 1)
          {
            enemy3[i].x -= 2;
            if (enemy3[i].x < 0)
            {
              enemy3_direct0++;
            }
          }
          if (enemy3_direct0 % 2 == 0)
          {
            enemy3[i].x += 2;
            if (enemy3[i].x + enemy3[i].width > WIDTH)
            {
              enemy3_direct0++;
            }
          }
        }
      }
      if (i == 1)//型号为1的飞机,奇数向右,偶数向左,且先向右边
      {
        if (enemy3[i].y < HEIGHT / 2)//先移动到画面中
        {
          enemy3[i].y += 10;
        }
        else
        {
          if (enemy3_direct1 % 2 == 0)
          {
            enemy3[i].x -= 2;
            if (enemy3[i].x < 0)
            {
              enemy3_direct1++;
            }
          }
          if (enemy3_direct1 % 2 == 1)
          {
            enemy3[i].x += 2;
            if (enemy3[i].x + enemy3[i].width > WIDTH)
            {
              enemy3_direct1++;
            }
          }
        }
      }
      if (i == 2)//型号为2的飞机,奇数向左,偶数向右,且先向左
      {
        if (enemy3[i].y < HEIGHT / 2)//先移动到画面中
        {
          enemy3[i].y += 10;
        }
        else
        {
          if (enemy3_direct2 % 2 == 1)
          {
            enemy3[i].x -= 2;
            if (enemy3[i].x < 0)
            {
              enemy3_direct2++;
            }
          }
          if (enemy3_direct2 % 2 == 0)
          {
            enemy3[i].x += 2;
            if (enemy3[i].x + enemy3[i].width > WIDTH)
            {
              enemy3_direct2++;
            }
          }
        }
      }
      if (enemy3[i].y < -3)
      {
        enemy3[i].isExit = false;
      }
    }
  }
  for (i = 0; i < 1; i++)
  {
    if (enemy4[i].isExit)
    {
      if (enemy4_direct0 % 2 == 1)//奇数向左,偶数向右且先向左
      {
        enemy4[i].x -= 1;
        if (enemy4[i].x < 0)
        {
          enemy4_direct0++;
        }
      }
      if (enemy4_direct0 % 2 == 0)
      {
        enemy4[i].x += 1;
        if (enemy4[i].x + enemy4[i].width > WIDTH)
        {
          enemy4_direct0++;
        }
      }
    }
  }
}
void EnemyClean()
{
  //主要用于产生BOSS前,将其他飞机和子弹清除
  int i, j;
  for (i = 0; i < 10; i++)//敌机1,遍历所有敌机位,若敌机存在则清除
  {
    if (enemy1[i].isExit == true)
    {
      enemy1[i].isExit = false;
    }
  }
  for (j = 0; j < 5; j++)//敌机2
  {
    if (enemy2[j].isExit == true)
    {
      enemy2[j].isExit = false;
    }
  }
  for (j = 0; j < 10; j++)//敌机3
  {
    if (enemy3[j].isExit == true)
    {
      enemy3[j].isExit = false;
    }
  }
  for (i = 0; i < enemy_bul_max; i++)//遍历所有子弹位,若子弹存在则清除
  {
    if (enemy2_bullet[i].isExit == true)
    {
      enemy2_bullet[i].isExit = false;
    }
    if (enemy3_bullet[i].isExit == true)
    {
      enemy3_bullet[i].isExit = false;
    }
    if (enemy4_bullet[i].isExit == true)
    {
      enemy4_bullet[i].isExit = false;
    }
  }
  for (i = 0; i < 1; i++)
  {
    if (lighter[i].isExit == true)
      lighter[i].isExit = false;
  }
}
void BulletClean()
{
  for (int i = 0; i < 1; i++)
  {
    if (!lighter[i].isExit)
      continue;
    for (int j = 0; j < bullet_max; j++)
    {
      if (bullet[j].isExit == true)
        bullet[j].isExit = false;
    }
  }
}
void EnemyCreat_L1()
{
  int i, j;
  int count1 = 0, count2 = 0;
  if (Timer_enemycreat(3000))
  {
    for (i = 0; i < 10; i++)//敌机1
    {
      if (enemy1[i].isExit == false)
      {
        enemy1[i].isExit = true;
        enemy1[i].x = rand() % (WIDTH - 60);
        enemy1[i].y = 0;
        enemy1[i].hp = 30;
        count1++;
        if (count1 == 2)//每个循环产生3次敌机
        {
          count1 = 0;
          break;
        }
      }
    }
    for (j = 0; j < 5; j++)//敌机2
    {
      if (enemy2[j].isExit == false)
      {
        enemy2[j].isExit = true;
        enemy2[i].hp = 50;
        enemy2[j].x = rand() % (WIDTH - 60);
        enemy2[j].y = 0;
        count2++;
        if (count2 == 1)//每个循环产生2次敌机
        {
          count2 = 0;
          break;
        }
      }
    }
    if (score > 2500)
    {
      for (j = 0; j < 10; j++)//敌机3
      {
        if (enemy3[j].isExit == false)
        {
          enemy3[j].isExit = true;
          enemy3[j].hp = 30;
          enemy3[j].x = rand() % (WIDTH - 60);
          enemy3[j].y = 0;
          break;//每个循环只产生1次敌机
        }
      }
    }
  }
}
void EnemyCreat_L2()
{
  int i, j;
  if (Timer_enemycreat(3000))
  {
    if (score > 5000 && score <= 8000)
    {
      for (i = 0; i < 10; i++)//敌机1
      {
        if (enemy1[i].isExit == false)
        {
          enemy1[i].isExit = true;
          enemy1[i].x = rand() % (WIDTH - 60);
          enemy1[i].y = 0;
          enemy1[i].hp = 30;
          break;
        }
      }
      for (j = 0; j < 5; j++)//敌机2
      {
        if (enemy2[j].isExit == false)
        {
          enemy2[j].isExit = true;
          enemy2[j].hp = 50;
          enemy2[j].x = rand() % (WIDTH - 60);
          enemy2[j].y = 0;
          break;
        }
      }
      for (j = 0; j < 5; j++)//敌机3
      {
        if (enemy3[j].isExit == false)
        {
          enemy3[j].isExit = true;
          enemy3[j].hp = 50;
          enemy3[j].x = -enemy3[i].width * 1.5;
          enemy3[j].y = 0;
          break;
        }
      }
    }
    if (score > 8000)
    {
      EnemyClean();//boss出现时清理其他的所有的飞机
      for (j = 0; j < 1; j++)
      {
        if (enemy4[j].isExit == false)
        {
          enemy4[j].isExit = true;
          enemy4[j].hp = 10000;
          enemy4[j].x = WIDTH / 2 - enemy4[j].width / 2;
          enemy4[j].y = 0;
          break;
        }
      }
    }
  }
}
void EnemyCreat_L3()
{
  EnemyClean();
  int j;
  if (score < 17000);
  {
    for (j = 0; j < 1; j++)
    {
      if (enemy5[j].isExit == false)
      {
        enemy5[j].isExit = true;
        enemy5[j].hp = 12000;
        enemy5[j].x = WIDTH / 2 - enemy5[j].width / 2;
        enemy5[j].y = 0;
        break;
      }
    }
  }
}
void Enemy_Bullet_Creat()
{
  int i, j;
  if (Timer_enemy2_bullet_creat(3000))//子弹发射频率
  {
    for (j = 0; j < 5; j++)
    {
      for (i = 0; i < enemy_bul_max; i++)
      {
        if (enemy2_bullet[i].isExit == false && enemy2[j].isExit == true)
        {
          enemy2_bullet[i].isExit = true;
          enemy2_bullet[i].x = enemy2[j].x + enemy2[j].width / 2 ;
          enemy2_bullet[i].y = enemy2[j].y;
          break;
        }
      }
    }
  }
  if (Timer_enemy3_bullet_creat(2000))
  {
    for (j = 0; j < 3; j++)
    {
      for (i = 0; i < enemy_bul_max; i++)
      {
        if (enemy3_bullet[i].isExit == false && enemy3[j].isExit == true)
        {
          enemy3_bullet[i].isExit = true;
          enemy3_bullet[i].x = enemy3[j].x + enemy3[j].width / 2;
          enemy3_bullet[i].y = enemy3[j].y;
          break;
        }
      }
    }
  }
  int count4 = 1;//boss两侧发射子弹
  if (Timer_enemy4_bullet_creat(100))
  {
    for (j = 0; j < 1; j++)
    {
      for (i = 0; i < enemy_bul_max; i++)
      {
        if (enemy4_bullet[i].isExit == false && enemy4[j].isExit == true)
        {
          enemy4_bullet[i].isExit = true;
          if (count4 == 1)//每次循环先左侧发射一次
          {
            enemy4_bullet[i].x = enemy4[j].x + 38;
            enemy4_bullet[i].y = enemy4[j].y + 37;
            count4 += 1;
            continue;
          }
          if (count4 == 2)//再右侧发射一次
          {
            count4 = 1;
            enemy4_bullet[i].x = enemy4[j].x + enemy4[j].width - 73;
            enemy4_bullet[i].y = enemy4[j].y + 37;
            break;
          }
        }
      }
    }
  }
  int count5 = 1;
  if (Timer_enemy5_bullet_creat(100))
  {
    for (j = 0; j < 1; j++)
    {
      for (i = 0; i < enemy_bul_max; i++)
      {
        if (enemy5_bullet[i].isExit == false && enemy5[j].isExit == true)
        {
          enemy5_bullet[i].isExit = true;
          if (count5 == 1)
          {
            enemy5_bullet[i].x = enemy5[j].x + 155;
            enemy5_bullet[i].y = enemy5[j].y + 360;
            count5 += 1;
            continue;
          }
          if (count5 == 2)
          {
            count5 = 1;
            enemy5_bullet[i].x = enemy5[j].x + enemy5[j].width - 175;
            enemy5_bullet[i].y = enemy5[j].y + 360;
            break;
          }
        }
      }
    }
  }
}
void Enemy_Bullet_Move()
{
  int i;
  //敌机2
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy2_bullet[i].isExit == true)
    {
      enemy2_bullet[i].y += rand() % 2 + 2;
      if (enemy2_bullet[i].y < 0)
      {
        enemy2_bullet[i].isExit = false;
      }
    }
  }
  //敌机3
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy3_bullet[i].isExit == true)
    {
      enemy3_bullet[i].y += rand() % 3 + 3;
      if (enemy3_bullet[i].y < 0)
      {
        enemy3_bullet[i].isExit = false;
      }
    }
  }
  //敌机4
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy4_bullet[i].isExit == true)
    {
      enemy4_bullet[i].y += 8;
      if (enemy4_bullet[i].y < 0)
      {
        enemy4_bullet[i].isExit = false;
      }
    }
  }
  //敌机5
  for (i = 0; i < enemy_bul_max; i++)
  {
    if (enemy5_bullet[i].isExit == true)
    {
      enemy5_bullet[i].y += 8;
      if (enemy5_bullet[i].y < 0)
      {
        enemy5_bullet[i].isExit = false;
      }
    }
  }
}
void Enemy_Bullet_Crush()
{
  for (int i = 0; i < 1; i++)
  {
    if (!myplane[i].isExit)//如果我方飞机不存在,则跳出本次循环
      continue;
    for (int j = 0; j < enemy_bul_max; j++)
    {
      if (!enemy2_bullet[j].isExit)
        continue;
      if (enemy2_bullet[j].x > myplane[i].x && enemy2_bullet[j].x < myplane[i].x + myplane[i].width && enemy2_bullet[j].y < myplane[i].y + myplane[i].height && enemy2_bullet[j].y > myplane[i].y)
      {
        myplane[i].hp -= 10;
        setbkmode(TRANSPARENT);//如果飞机扣血,则输出扣血量
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          outtextxy(myplane[i].x, myplane[i].y + rand() % (myplane[i].height), _T("-10"));
        }
      }
      if (myplane[i].hp <= 0)
      {
        Judge();
      }
    }
  }
  for (int i = 0; i < 1; i++)
  {
    if (!myplane[i].isExit)
      continue;
    for (int j = 0; j < enemy_bul_max; j++)
    {
      if (!enemy3_bullet[j].isExit)
        continue;
      if (enemy3_bullet[j].x > myplane[i].x && enemy3_bullet[j].x < myplane[i].x + myplane[i].width && enemy3_bullet[j].y < myplane[i].y + myplane[i].height && enemy3_bullet[j].y > myplane[i].y)
      {
        myplane[i].hp -= 10;
        setbkmode(TRANSPARENT);
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          outtextxy(myplane[i].x, myplane[i].y + rand() % (myplane[i].height), _T("-10"));
        }
      }
      if (myplane[i].hp <= 0)
      {
        Judge();
      }
    }
  }
  for (int i = 0; i < 1; i++)
  {
    if (!myplane[i].isExit)
      continue;
    for (int j = 0; j < enemy_bul_max; j++)
    {
      if (!enemy4_bullet[j].isExit)
        continue;
      if (enemy4_bullet[j].x > myplane[i].x && enemy4_bullet[j].x < myplane[i].x + myplane[i].width && enemy4_bullet[j].y < myplane[i].y + myplane[i].height && enemy4_bullet[j].y > myplane[i].y)
      {
        myplane[i].hp -= 10;
        setbkmode(TRANSPARENT);
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          outtextxy(myplane[i].x, myplane[i].y + rand() % (myplane[i].height), _T("-10"));
        }
      }
      if (myplane[i].hp <= 0)
      {
        Judge();
      }
    }
  }
  for (int i = 0; i < 1; i++)
  {
    if (!myplane[i].isExit)
      continue;
    for (int j = 0; j < enemy_bul_max; j++)
    {
      if (!enemy5_bullet[j].isExit)
        continue;
      if (enemy5_bullet[j].x > myplane[i].x && enemy5_bullet[j].x < myplane[i].x + myplane[i].width && enemy5_bullet[j].y < myplane[i].y + myplane[i].height && enemy5_bullet[j].y > myplane[i].y)
      {
        myplane[i].hp -= 10;
        setbkmode(TRANSPARENT);
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          outtextxy(myplane[i].x, myplane[i].y + rand() % (myplane[i].height), _T("-10"));
        }
      }
      if (myplane[i].hp <= 0)
      {
        Judge();
      }
    }
  }
}
void EnemyCrush()
{
  for (int i = 0; i < 1; i++)
  {
    if (!myplane[i].isExit)
      continue;
    for (int j = 0; j < 10; j++)
    {
      if (!enemy1[j].isExit)
        continue;
      if (enemy1[j].x > myplane[i].x && enemy1[j].x < myplane[i].x + myplane[i].width && enemy1[j].y > myplane[i].y && enemy1[j].y < myplane[i].y + myplane[i].height)
      {
        myplane[i].hp -= 100;
        enemy1[j].isExit = false;
      }
      if (myplane[i].hp <= 0)
        Judge();
    }
  }
  for (int i = 0; i < 1; i++)
  {
    if (!myplane[i].isExit)
      continue;
    for (int j = 0; j < 5; j++)
    {
      if (!enemy2[j].isExit)
        continue;
      if (enemy2[j].x > myplane[i].x && enemy2[j].x<myplane[i].x + myplane[i].width && enemy2[j].y>myplane[i].y && enemy2[j].y < myplane[i].y + myplane[i].height)
      {
        myplane[i].hp -= 100;
        enemy2[j].isExit = false;
      }
      if (myplane[i].hp <= 0)
        Judge();
    }
  }
  for (int i = 0; i < 1; i++)
  {
    if (!myplane[i].isExit)
      continue;
    for (int j = 0; j < 5; j++)
    {
      if (!enemy3[j].isExit)
        continue;
      if (enemy3[j].x > myplane[i].x && enemy3[j].x<myplane[i].x + myplane[i].width && enemy3[j].y>myplane[i].y && enemy3[j].y < myplane[i].y + myplane[i].height)
      {
        myplane[i].hp -= 100;
        enemy3[j].isExit = false;
      }
      if (myplane[i].hp <= 0)
        Judge();
    }
  }
}
void UpdatePlane()
{
  //GetAsyncKeyState非阻塞获取键盘信息函数
  //飞机移动
  if (GetAsyncKeyState(VK_UP))                //按UP键
  {
    for (int i = 0; i < 1; i++)
    {
      if (myplane[i].y > 0)//如果没有超过边界再执行
        myplane[i].y -= 8;
    }
  }
  if (GetAsyncKeyState(VK_DOWN))              //按DOWN键
  {
    for (int i = 0; i < 1; i++)
    {
      if (myplane[i].y < HEIGHT - myplane[i].height)
        myplane[i].y += 8;
    }
  }
  if (GetAsyncKeyState(VK_LEFT))              //按LEFT键
  {
    for (int i = 0; i < 1; i++)
    {
      if (myplane[i].x > -(myplane[i].width) / 2)
      {
        myplane[i].x -= 8;
      }
    }
  }
  if (GetAsyncKeyState(VK_RIGHT))              //按RIGHT键
  {
    for (int i = 0; i < 1; i++)
    {
      if (myplane[i].x < WIDTH - (myplane[i].width) / 2)
      {
        myplane[i].x += 8;
      }
    }
  }
  if (GetAsyncKeyState('J') || GetAsyncKeyState('j'))
  {
    DrawBullet();
  }
  if (GetAsyncKeyState('L') || GetAsyncKeyState('l'))
  {
    if (Timer1(30000))
    {
      for (int i = 0; i < 1; i++)
      {
        DrawLighter();
        BulletClean();
      }
    }
  }
}
void initGame()
{
  int i;
  //初始化背景地图Y轴坐标(为了后续移动背景地图)
  bky0 = -HEIGHT;
  bky1 = 0;
  bk1y0 = -HEIGHT;
  bk1y1 = 0;
  bk2y0 = -HEIGHT;
  bk2y1 = 0;
  //初始化我方飞机
  for (i = 0; i < 1; i++)
  {
    myplane[i].x = (WIDTH - myplane[i].width) / 2;
    myplane[i].y = (HEIGHT - myplane[i].height);
    myplane[i].hp = 500;
    myplane[i].isExit = true;
  }
  //初始化敌机
  for (i = 0; i < 10; i++)
  {
    enemy1[i].isExit = false;
    enemy1[i].hp = 30;
    enemy1[i].width = 70;
    enemy1[i].height = 70;
  }
  for (i = 0; i < 5; i++)
  {
    enemy2[i].isExit = false;
    enemy2[i].hp = 50;
    enemy2[i].width = 85;
    enemy2[i].height = 90;
  }
  for (i = 0; i < 5; i++)
  {
    enemy3[i].isExit = false;
    enemy3[i].hp = 30;
    enemy3[i].width = 70;
    enemy3[i].height = 70;
  }
  for (i = 0; i < 1; i++)
  {
    enemy4[i].isExit = false;
    enemy4[i].hp = 10000;
    enemy4[i].width = 450;
    enemy4[i].height = 300;
  }
  for (i = 0; i < 1; i++)
  {
    enemy5[i].isExit = false;
    enemy5[i].hp = 12000;
    enemy5[i].width = 500;
    enemy5[i].height = 375;
  }
  //初始化子弹
  bullet[i].x1; bullet[i].y1; bullet[i].x2; bullet[i].y2;
  for (int i = 0; i < bullet_max; i++)
  {
    bullet[i].isExit = false;
  }
  //初始化敌机子弹
  for (i = 0; i < enemy_bul_max; i++)
  {   
    enemy2_bullet[i].isExit = false;
  }
  for (i = 0; i < enemy_bul_max; i++)
  {   
    enemy3_bullet[i].isExit = false;
  }
  for (i = 0; i < enemy_bul_max; i++)
  {   
    enemy4_bullet[i].isExit = false;
  }
  for (i = 0; i < enemy_bul_max; i++)
  {   
    enemy5_bullet[i].isExit = false;
  }
  for (i = 0; i < 1; i++)
  {
    lighter[i].isExit = false;
  }
  //加载背景音乐
  mciSendString(L"open level.mp3", 0, 0, 0);
  mciSendString(L"play level.mp3", 0, 0, 0);
}
void level_change()
{
  int ret = level(),i=0;
  if (level_change_count == 1 && score > 5000)
  {
    level_change_count += 1;
    myplane[i].hp = 500;
    EnemyClean();//切换关卡时清除所有飞机
  }
  if (level_change_count == 2 && score > 12000)
  {
    score = 12001;
    level_change_count += 1;
    myplane[i].hp = 500;
    EnemyClean();
  }
}
void FailMenu()
{
    initgraph(800, 240);
    setbkmode(TRANSPARENT);
    settextstyle(30, 0, L"宋体");
    outtextxy(10, 20, _T("游戏失败"));
    outtextxy(10, 70, _T("按Delete键退出"));
    outtextxy(10, 120, _T("按Space(空格键)复活并继续游戏"));
    while (1)
    {
      if (GetAsyncKeyState(VK_DELETE)) exit(0);//如果按下DELETE键则直接结束程序
      if (GetAsyncKeyState(VK_SPACE)) break;//如果按下空格键则继续游戏
    }
      main();
}
void Judge()
{
  if (myplane->hp <= 0)
  {
    if (level() == 1)
    {
      score = 0;//第一关初始分数为0
    }
    if (level() == 2 && score < 8000)
    {
      score = 5001;//进入第二关,且第二关boss出现前,初始分数为5001
    }
    if (level() == 2 && score > 8000)
    {
      score = 8001;//第二关boss出现后,初始分数
    }
    if (level() == 3)
    {
      score = 12001;//进入第三关,初始分数
    }
    FailMenu();
  }
  if (score > 17000)
  {
    EndMenu();
  }
}
void DrawInterface()
{
  int   bgy=0;                                //主界面图片坐标
  while (1)
  {
    putimage(0, bgy, &bgimg);               //绘制主界面 
    ExMessage msg;
    if (peekmessage(&msg))
    {
      if (msg.message == WM_LBUTTONDOWN)  //按左键退出主界面循环
      break;
    }
  }
}
void UpdateBack()
{
  //背景移动
  bky0++;    
  bky1++;
  if (bky0 > HEIGHT)
    (bky0 = -HEIGHT);                       //如果背景移出初始界面,则放到下面
  if (bky1 > HEIGHT)
    (bky1 = -HEIGHT);
  bk1y0++;
  bk1y1++;
  if (bk1y0 > HEIGHT)
    (bk1y0 = -HEIGHT);                       //如果背景移出初始界面,则放到下面
  if (bk1y1 > HEIGHT)
    (bk1y1 = -HEIGHT);
  bk2y0++;
  bk2y1++;
  if (bk2y0 > HEIGHT)
    (bk2y0 = -HEIGHT);                       //如果背景移出初始界面,则放到下面
  if (bk2y1 > HEIGHT)
    (bk2y1 = -HEIGHT);
}
void DrawBullet()
{
  if (Timer(140))
  {
    //绘制子弹
    for (int i = 0; i < bullet_max; i++)
    {
      if (!bullet[i].isExit)                  //遍历所有子弹位,找到一个空位存放子弹
      {
        bullet[i].x1 = myplane->x + 18;   //若子弹存在初始化子弹坐标
        bullet[i].y1 = myplane->y + 25;
        bullet[i].x2 = myplane->x + 65;
        bullet[i].y2 = myplane->y + 25;
        bullet[i].isExit = true;
        break;                              //发射一次子弹
      }
    }
  }
}
void DrawLighter()
{
  for (int i = 0; i < 1; i++)
  {
    if (!lighter[i].isExit)
    {
      lighter[i].x1 = myplane->x - (305 - myplane->width) / 2;
      lighter[i].y1 = myplane->y - 200;
      lighter[i].isExit = true;
      break;
    }
  }
}
void MoveBullet()
{
  //子弹移动
  for (int i = 0; i < bullet_max; i++)
  {
    if (bullet[i].isExit)
    {
      bullet[i].y1 -= 10;
      bullet[i].y2 -= 10;
      if (bullet[i].y1 > HEIGHT , bullet[i].y2 > HEIGHT )
        bullet[i].isExit = false;  //若子弹飞出则腾出一个子弹位 
    }
  }
}
void MoveLighter()
{
  for (int i = 0; i < 1; i++)
  {
    if (lighter[i].isExit)
    {
      lighter[i].y1 -= 5;
      if (lighter[i].y1 < -200)
        lighter[i].isExit = false;
    }
  }
}
void Bulletcrush()
{
  for (int i = 0; i < 10; i++)
  {
    if (!enemy1[i].isExit)
      continue;
    for (int j = 0; j < bullet_max; j++)
    {
      if (!bullet[j].isExit)
        continue;
      if ((bullet[j].x1 > enemy1[i].x && bullet[j].x1<enemy1[i].x + enemy1[i].width && bullet[j].y1>enemy1[i].y && bullet[j].y1 < enemy1[i].y + enemy1[i].height) || (bullet[j].x2>enemy1[i].x && bullet[j].x2<enemy1[i].x + enemy1[i].width
        && bullet[j].y2>enemy1[i].y && bullet[j].y2 < enemy1[i].y + enemy1[i].height))
      {
        enemy1[i].hp -= 1;
        if (Timer2(1))
        {
          setbkmode(TRANSPARENT);
          settextstyle(60, 0, L"华文行楷");
          outtextxy(enemy1[i].x, enemy1[i].y + rand() % (enemy1[i].height), _T("-1"));
        }
      }
    }
    if (enemy1[i].hp <= 0)
    {
      enemy1[i].isExit = false;
      score += rand() % 10 + 20;
      enemy1[i].hp = 30;
    }
  }//小飞机
  for (int i = 0; i < 5; i++)
  {
    if (!enemy2[i].isExit)
      continue;
    for (int j = 0; j < bullet_max; j++)
    {
      if (!bullet[j].isExit)
        continue;
      if ((bullet[j].x1 > enemy2[i].x && bullet[j].x1<enemy2[i].x + enemy2[i].width && bullet[j].y1>enemy2[i].y && bullet[j].y1 < enemy2[i].y + enemy2[i].height) || (bullet[j].x2>enemy2[i].x && bullet[j].x2<enemy2[i].x + enemy2[i].width && bullet[j].y2>enemy2[i].y && bullet[j].y2 < enemy2[i].y + enemy2[i].height))
      {
        enemy2[i].hp -= 1;
        if (Timer2(1))
        {
          setbkmode(TRANSPARENT);
          settextstyle(60, 0, L"华文行楷");
          outtextxy(enemy2[i].x, enemy2[i].y + rand() % (enemy2[i].height), _T("-1"));
        }
      }
    }
    if (enemy2[i].hp <= 0)
    {
      enemy2[i].isExit = false;
      score += rand() % 50 + 100;
      enemy2[i].hp = 50;
    }
  }//中飞机
  for (int i = 0; i < 5; i++)
  {
    if (!enemy3[i].isExit)
      continue;
    for (int j = 0; j < bullet_max; j++)
    {
      if (!bullet[j].isExit)
        continue;
      if ((bullet[j].x1 > enemy3[i].x && bullet[j].x1<enemy3[i].x + enemy3[i].width && bullet[j].y1>enemy3[i].y && bullet[j].y1 < enemy3[i].y + enemy3[i].height) || (bullet[j].x2>enemy3[i].x && bullet[j].x2<enemy3[i].x + enemy3[i].width && bullet[j].y2>enemy3[i].y && bullet[j].y2 < enemy3[i].y + enemy3[i].height))
      {
        enemy3[i].hp -= 1;
        setbkmode(TRANSPARENT);
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          outtextxy(enemy3[i].x, enemy3[i].y + rand() % (enemy3[i].height), _T("-1"));
        }
      }
    }
    if (enemy3[i].hp <= 0)
    {
      enemy3[i].isExit = false;
      score += rand() % 50 + 100;
      enemy3[i].hp = 30;
    }
  }//横行飞机
  for (int i = 0; i < 1; i++)
  {
    if (!enemy4[i].isExit)
      continue;
      for (int j = 0; j < bullet_max; j++)
      {
        if(!bullet[j].isExit)
          continue;
        if ((bullet[j].x1 > enemy4[i].x && bullet[j].x1<enemy4[i].x + enemy4[i].width && bullet[j].y1>enemy4[i].y && bullet[j].y1 < enemy4[i].y + enemy4[i].height) || (bullet[j].x2 > enemy4[i].x && bullet[j].x2<enemy4[i].x + enemy4[i].width && bullet[j].y2>enemy4[i].y && bullet[j].y2 < enemy4[i].y + enemy4[i].height))
        {
          enemy4[i].hp -= rand() % 4 + 1;
          setbkmode(TRANSPARENT);
          settextstyle(60, 0, L"华文行楷");
          if (Timer2(1))
          {
            if (enemy4[i].hp -= 1)
            {
              outtextxy(enemy4[i].x + rand() % (enemy4[i].width), enemy4[i].y + rand() % (enemy4[i].height), _T("-1"));
            }
            if (enemy4[i].hp -= 2)
            {
              outtextxy(enemy4[i].x + rand() % (enemy4[i].width), enemy4[i].y + rand() % (enemy4[i].height), _T("-2"));
            }
            if (enemy4[i].hp -= 3)
            {
              outtextxy(enemy4[i].x + rand() % (enemy4[i].width), enemy4[i].y + rand() % (enemy4[i].height), _T("-3"));
            }
            if (enemy4[i].hp -= 4)
            {
              outtextxy(enemy4[i].x + rand() % (enemy4[i].width), enemy4[i].y + rand() % (enemy4[i].height), _T("暴击 -4"));
            }
            if (enemy4[i].hp -= 5)
            {
              outtextxy(enemy4[i].x + rand() % (enemy4[i].width), enemy4[i].y + rand() % (enemy4[i].height), _T("暴击 -5"));
            }
          }
        }
        if (enemy4[i].hp <= 0)
        {
          enemy4[i].isExit = false;
          score += 4000;
        }
      }
  }
  //第二关BOSS
  for (int i = 0; i < 1; i++)
  {
    if (!enemy5[i].isExit)
      continue;
    for (int j = 0; j < bullet_max; j++)
    {
      if (!bullet[j].isExit)
        continue;
      if ((bullet[j].x1 > enemy5[i].x && bullet[j].x1<enemy5[i].x + enemy5[i].width && bullet[j].y1>enemy5[i].y && bullet[j].y1 < enemy5[i].y + enemy5[i].height && bullet[j].x2>enemy5[i].x) || (bullet[j].x2<enemy5[i].x + enemy5[i].width && bullet[j].y2>enemy5[i].y && bullet[j].y2 < enemy5[i].y + enemy5[i].height))
      {
        enemy5[i].hp -= rand() % 5 + 1;
        setbkmode(TRANSPARENT);
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          if (enemy5[i].hp -= 1)
          {
            outtextxy(enemy5[i].x + rand() % (enemy5[i].width), enemy5[i].y + rand() % (enemy5[i].height), _T("-1"));
          }
          if (enemy5[i].hp -= 2)
          {
            outtextxy(enemy5[i].x + rand() % (enemy5[i].width), enemy5[i].y + rand() % (enemy5[i].height), _T("-2"));
          }
          if (enemy5[i].hp -= 3)
          {
            outtextxy(enemy5[i].x + rand() % (enemy5[i].width), enemy5[i].y + rand() % (enemy5[i].height), _T("-3"));
          }
          if (enemy5[i].hp -= 4)
          {
            outtextxy(enemy5[i].x + rand() % (enemy5[i].width), enemy5[i].y + rand() % (enemy5[i].height), _T("暴击 -4"));
          }
          if (enemy5[i].hp -= 5)
          {
            outtextxy(enemy5[i].x + rand() % (enemy5[i].width), enemy5[i].y + rand() % (enemy5[i].height), _T("暴击 -5"));
          }
          if (enemy5[i].hp -= 6)
          {
            outtextxy(enemy5[i].x + rand() % (enemy5[i].width), enemy5[i].y + rand() % (enemy5[i].height), _T("暴击 -6"));
          }
        }
      }
      if (enemy5[i].hp <= 0)
      {
        enemy5[i].isExit = false;
        score += 5000;
        Judge();
      }
    }
  }
  //第三关BOSS
}
void LghterCrush()
{
  for (int j = 0; j < 1; j++)
  {
    if (!lighter[j].isExit)
      continue;
    for (int i = 0; i < 10; i++)
    {
      if (!enemy1[i].isExit)
        continue;
      if (enemy1[i].x > lighter[j].x1 - 20 && enemy1[i].x < lighter[j].x1 + 305 && enemy1[i].y > lighter[j].y1 && enemy1[i].y < lighter[j].y1 + 200)
      {
        enemy1[i].hp -= 100;
        if (Timer2(1))
        {
          setbkmode(TRANSPARENT);
          settextstyle(60, 0, L"华文行楷");
          outtextxy(enemy1[i].x, enemy1[i].y + rand() % (enemy1[i].height), _T("-100"));
        }
      }
    }
    if (enemy1[j].hp <= 0)
    {
      enemy1[j].isExit = false;
      score += rand() % 10 + 20;
      enemy1[j].hp = 30;
    }
  }//小飞机
  for (int j = 0; j < 1; j++)
  {
    if (!lighter[j].isExit)
      continue;
    for (int i = 0; i < 5; i++)
    {
      if (!enemy2[i].isExit)
        continue;
      if (enemy2[i].x > lighter[j].x1 - 20 && enemy2[i].x < lighter[j].x1 + 305 && enemy2[i].y > lighter[j].y1 && enemy2[i].y < lighter[j].y1 + 200)
      {
        enemy2[i].hp -= 100;
        if (Timer2(1))
        {
          setbkmode(TRANSPARENT);
          settextstyle(60, 0, L"华文行楷");
          outtextxy(enemy2[i].x, enemy2[i].y + rand() % (enemy2[i].height), _T("-100"));
        }
      }
    }
    if (enemy2[j].hp <= 0)
    {
      enemy2[j].isExit = false;
      score += rand() % 50 + 100;
      enemy2[j].hp = 50;
    }
  }//大飞机
  for (int j = 0; j < 1; j++)
  {
    if (!lighter[j].isExit)
      continue;
    for (int i = 0; i < 5; i++)
    {
      if (!enemy3[i].isExit)
        continue;
      if (enemy3[i].x > lighter[j].x1 - 20 && enemy3[i].x < lighter[j].x1 + 305 && enemy3[i].y > lighter[j].y1 && enemy3[i].y < lighter[j].y1 + 200)
      {
        enemy3[i].hp -= 100;
        if (Timer2(1))
        {
          setbkmode(TRANSPARENT);
          settextstyle(60, 0, L"华文行楷");
          outtextxy(enemy3[i].x, enemy3[i].y + rand() % (enemy3[i].height), _T("-100"));
        }
      }
    }
    if (enemy1[j].hp <= 0)
    {
      enemy1[j].isExit = false;
      score += rand() % 50 + 100;
      enemy1[j].hp = 30;
    }
  }//横行飞机
  for (int i = 0; i < 1; i++)
  {
    if (!enemy4[i].isExit)
      continue;
    for (int j = 0; j < 1; j++)
    {
      if (!lighter[j].isExit)
        continue;
      if (lighter[j].x1 + 20 > enemy4[i].x && lighter[j].x1 - 20 < enemy4[i].x + enemy4[i].width && lighter[j].y1 > enemy4[i].y && lighter[j].y1 < enemy4[i].y + enemy4[i].height)
      {
        enemy4[i].hp -= 100;
        setbkmode(TRANSPARENT);
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          outtextxy(enemy4[i].x + rand() % (enemy4[i].width), enemy4[i].y + rand() % (enemy4[i].height), _T("-100"));
        }
      }
      if (enemy4[i].hp <= 0)
      {
        enemy4[i].isExit = false;
        score += 4000;
      }
    }
  }
  //第二关BOSS
  for (int i = 0; i < 1; i++)
  {
    if (!enemy5[i].isExit)
      continue;
    for (int j = 0; j < 1; j++)
    {
      if (!lighter[j].isExit)
        continue;
      if (lighter[j].x1 + 20 > enemy5[i].x && lighter[j].x1 - 20 < enemy5[i].x + enemy5[i].width && lighter[j].y1 > enemy5[i].y && lighter[j].y1 < enemy5[i].y + enemy5[i].height)
      {
        enemy5[i].hp -= 100;
        setbkmode(TRANSPARENT);
        settextstyle(60, 0, L"华文行楷");
        if (Timer2(1))
        {
          outtextxy(enemy5[i].x + rand() % (enemy5[i].width), enemy5[i].y + rand() % (enemy5[i].height), _T("-100"));
        }
      }
      if (enemy5[i].hp <= 0)
      {
        enemy5[i].isExit = false;
        score += 5000;
        Judge();
      }
    }
  }
}
void Print()
{
  setbkmode(TRANSPARENT);
  settextstyle(40, 0, L"华文行楷");
  TCHAR ScorePrint[100];
  _stprintf(ScorePrint, L"当前分数:%d", score);
  outtextxy(0, 750, ScorePrint);
  setbkmode(TRANSPARENT);
  settextstyle(40, 0, L"华文行楷");
  TCHAR HPPrint[100];
  _stprintf(HPPrint, L"当前血量:%d", myplane->hp);
  outtextxy(0, 800,HPPrint);
  setbkmode(TRANSPARENT);
  settextstyle(30, 0, L"华文行楷");
  outtextxy(0, 0, L"按J / j键攻击");
  outtextxy(0, 30, L"按L / l键释放雷霆千钧");
  outtextxy(0, 60, L"CD时间30秒");
}
void EndMenu()
{
  EnemyClean();
  enemy5[0].isExit = false;
  loadimage(&bkimg3, L"bk3.jpg");
  int x = 10;
  int y = 20;
  Sleep(1000);
  initgraph(WIDTH, HEIGHT);
  putimage(0, 0, &bkimg3);
  TCHAR time_test1[50];
  TCHAR time_test2[50];
  TCHAR time_test3[50];
  _stprintf(time_test1, _T("许多年以后,"));
  _stprintf(time_test2, _T("当我再次仰望那片星空"));
  _stprintf(time_test3, _T("战机的轰鸣声依旧回荡在耳畔..."));
  setbkmode(TRANSPARENT);
  settextstyle(40, 0, L"华文行楷");
  Sleep(1000);
  outtextxy(x, y, time_test1);
  Sleep(2000);
  outtextxy(x, y + 50, time_test2);
  Sleep(3000);
  outtextxy(x, y + 100, time_test3);
  Sleep(4000);
  exit(0);
}
#include "雷霆飞机.h"
#include <conio.h>
#include <stdio.h>
#include <graphics.h>
#include <windows.h>
#include <conio.h>
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
#define WIDTH 600
#define HEIGHT 850
#define bullet_max 5000//屏幕上同时出现的子弹上限、
#define enemy_bul_max 150  //敌方飞机子弹最大量
//将所有封装函数放入主函数进行调用
int main()
{
  HWND hwnd = initgraph(WIDTH, HEIGHT);
  SetWindowText(hwnd, L"雷霆战机");
  initGame();
  loadimg();
  DrawInterface();
  BeginBatchDraw();//双缓冲绘图
  while (1)
  {
    UpdateBack();
    level_change();
    if (level() == 1)
    {
      EnemyCreat_L1();
    }
    if (level() == 2)
    {
      EnemyCreat_L2();
    }
    if (level() == 3)
    {
      EnemyCreat_L3();
    }
    EnemyMove();
    Enemy_Bullet_Creat();
    Enemy_Bullet_Move();
    DrawGame();
    UpdatePlane();
    MoveBullet();
    MoveLighter();
    Bulletcrush();
    LghterCrush();
    Enemy_Bullet_Crush();
    EnemyCrush();
    Print();
    FlushBatchDraw();
    Sleep(1);
  }
  EndBatchDraw();
  return 0;
}

一. 游戏概述

- 游戏类型和玩法

属于一款机战类具有挑战性和娱乐性的游戏

通过获取用户鼠标及键盘消息来控制界面转换和飞机移动以及释放子弹和技能

- 游戏目标和规则

普通模式:

通关最终BOSS,我方飞机受到敌机以及敌机子弹碰撞,则持续扣血,如果飞机血量为0,则返回失败界面(由用户选择复活继续游戏或退出游戏)

挑战模式:

采用无尽模式积分制,并且禁止实用技能,新增漏击判定(即敌机飞出画面认为被击毁,则我方飞机扣血),除非飞机血量为0或用户选择退出游戏,否则游戏持续进行,飞机血量为0,游戏结束并显示最终得分

二. 游戏设计

- 游戏界面设计

选用炫酷的飞机大战图片并且采取菜单模式,可以进行界面转换重复进行游戏

- 游戏关卡和难度设计

普通模式分为三关,分数达到则自动进入下一关卡,难度较小

挑战模式采用无尽模式积分,敌机创建频率增大,难度递增

三. 技术实现

- 游戏开发工具

采用VS2022,Easyx图形库,C语言/C++

- 游戏代码结构和模块划分

1.初始化游戏窗口

2.初始化游戏数据

3.循环游戏事件

编写玩家控制模块,碰撞模块,子弹发射模块,技能发射模块,关卡转换模块,界面转换模块

4.设置游戏结束标志

四. 测试和调试

- 游戏测试计划和用例

玩家控制模块:测试飞机移动边界以及按键响应时间

碰撞模块:测试敌机与子弹,敌机与技能,我方飞机与子弹,我方飞机与敌机碰撞会不会正常扣血与消失,会不会影响下一次敌机创建

子弹发射模块:检测子弹创建后能否按预定轨迹,并且从预定起始位置发射,子弹消失判定以及是否会影响下一次子弹创建

技能发射模块:检测技能创建后能否按预定轨迹,并且从预定起始位置发射,技能消失判定以及碰撞判定

关卡转换模块:分数达到后是否会正常切换关卡背景图,是否会按预定的方式和时间创建敌机和子弹,每次关卡转换之间是否会上一关的敌机和子弹,是否会初始化飞机血量

界面转换模块:检测获取鼠标消息后是否会转换界面以及响应时间,界面转换是否会影响游戏逻辑,如何通过界面转换将不同的模式联系在一起

- 游戏调试工具和方法

VS2022,先对各个模块单独调试,再对整个游戏逻辑(包括关卡转换,界面转换,计分等)进行调试

- 游戏修复和更新流程

1.0:未加入界面转换模块,未加入挑战模式,敌机子弹创建后不移动就消失,未加入暂停界面,未加入子弹发射,飞机移动,爆炸音效

2.0:修复1.0的bug,加入界面转换模块,加入子弹发射,飞机移动,爆炸音效

3.0:加入暂停界面,且通过暂停界面用户可选择继续游戏(保存之前的游戏数据),退出游戏,开启/关闭音效

五. 优化

- 游戏后续更新和改进计划

1.界面转换模块

问题:响应时间较长,且一次游戏结束后,用户选择返回菜单继续游戏,游戏画面会出现偶尔卡顿

猜想:游戏数据处理不当,内存无法及时释放导致卡顿

改进计划:引入数据结构,适当优化及存储游戏数据,增加游戏运行时间,流畅性

2.问题:持续按住攻击键不放,一段时间偶尔会出现卡顿

猜想:由按下攻击键后的音效引发,因为音效采用多线程,频繁调用多线程,且线程得不到及时释放会造成线程死锁,从而使程序卡顿

改进方法:设定线程存在时间,到达一定时间自动释放

六. 总结和展望

- 游戏开发过程中的经验和教训

增加我对C语言的使用熟练度,更好的掌握条件控制与循环控制程序运行

接触到一部分C++知识如IMAGE变量,MySQL数据库,多线程使用(基础版),有利于我之后进一步接触C++

对bug的调试更加熟练,同时掌握开发游戏最基础的逻辑,锻炼自己的逻辑思维

增加团队合作,增长团队合作精神

相关文章
|
16天前
|
存储 算法 Linux
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
40 6
|
16天前
|
C语言 C++ 数据格式
【C++对于C语言的扩充】C++与C语言的联系,命名空间、C++中的输入输出以及缺省参数
【C++对于C语言的扩充】C++与C语言的联系,命名空间、C++中的输入输出以及缺省参数
|
2天前
|
设计模式 编译器 数据安全/隐私保护
C++ 多级继承与多重继承:代码组织与灵活性的平衡
C++的多级和多重继承允许类从多个基类继承,促进代码重用和组织。优点包括代码效率和灵活性,但复杂性、菱形继承问题(导致命名冲突和歧义)以及对基类修改的脆弱性是潜在缺点。建议使用接口继承或组合来避免菱形继承。访问控制规则遵循公有、私有和受保护继承的原则。在使用这些继承形式时,需谨慎权衡优缺点。
14 1
|
2天前
|
C++
C++:深度解析与实战应用
C++:深度解析与实战应用
7 1
|
2天前
|
存储 算法 C语言
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
C语言进阶:顺序表(数据结构基础) (以通讯录项目为代码练习)
|
3天前
|
设计模式 存储 Java
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
C++从入门到精通:3.5设计模式——提升代码可维护性与可扩展性的关键
|
4天前
|
C++
【C++】在使用代码组装URL时,一定要注意的坑......
【C++】在使用代码组装URL时,一定要注意的坑......
10 0
|
20天前
|
开发框架 .NET 编译器
【C++】C++对C语言的关系,拓展及命名空间的使用
【C++】C++对C语言的关系,拓展及命名空间的使用
|
25天前
|
人工智能 机器人 测试技术
【C/C++】C语言 21点桌牌游戏 (源码) 【独一无二】
【C/C++】C语言 21点桌牌游戏 (源码) 【独一无二】
|
25天前
C/C++test两步完成CMake项目静态分析
通过将C/C++test集成到CMake项目中,并根据项目的需要进行配置,可以在两步内完成CMake项目的静态分析。这样可以帮助开发人员及时发现并修复潜在的代码问题,提高代码质量和可靠性。
8 0

相关实验场景

更多