请事先下好图片素材和easyX函数库
若加载图片报错,有可能是字符集不对,改为多字符集即可。
#include<stdio.h> //标准输入输出函数库
#include<conio.h> //接收键盘输入输出
#include<time.h> //时间戳
#include<random> //随机数
#include<graphics.h> //图形库,可以帮助我们新手,快速入门图形编程 EasyX
enum My //enum是一种数据类型(枚举类型),用于定义一组有限的整型值集合,列举出所有可能的值,且变量取值不能超过定义的范围
{
WIDTH = 480, //背景大小为 480 x 700 像素
HEIGHT = 700,
Player_WIDTH = 102, //飞机大小
Player_HEIGHT = 126,
Bullet_NUM = 10, //子弹的数量
//子弹的尺寸
Bullet_WIDTH=5,
Bullet_HEIGHT=11,
Enemy_NUM = 10, //敌机的数量
//敌机的尺寸
Enemy0_WIDTH =57,
Enemy0_HEIGHT=43,
Enemy1_WIDTH =69,
Enemy1_HEIGHT=99,
Enemy2_WIDTH =169,
Enemy2_HEIGHT=258
};
struct Plane //飞机模块 struct是一种结构体类型
{
float x;
float y;
bool live; //是否存活
int HP;
int type; //敌机类型
float speed; //敌机速度
}player,bullet[Bullet_NUM],enemy[Enemy_NUM];
//把图片加载进程序
//背景图片
IMAGE background; //image是一种数据类型,用于表示图像数据
//玩家图片
IMAGE image_player[2];
//玩家子弹图片
IMAGE image_bullet;
//敌机图片
IMAGE image_enemy[2][3];
//敌机毁灭图片
IMAGE image_enemy_destroy[3][2][6];
//加载素材函数
void LoadIMAGE()
{
//加载背景图片
loadimage(&background, "./Material/images/background.png");
//可能报错:error c2665:"loadimage":2 个重载中没有一个可以转换所有参数类型
//参数有误,因为字符集不对,Unicode 多字节字符集
//加载玩家
loadimage(&image_player[0], "./Material/images/me1_bw.png");
loadimage(&image_player[1], "./Material/images/me1_w.png");
//加载敌机
loadimage(&image_enemy[0][0], "./Material/images/enemy1_bw.png");
loadimage(&image_enemy[1][0], "./Material/images/enemy1_w.png");
loadimage(&image_enemy[0][1], "./Material/images/enemy2_bw.png");
loadimage(&image_enemy[1][1], "./Material/images/enemy2_w.png");
loadimage(&image_enemy[0][2], "./Material/images/enemy3_n1_bw.png");
loadimage(&image_enemy[1][2], "./Material/images/enemy3_n1_w.png");
//加载敌机毁灭动画
loadimage(&image_enemy_destroy[0][0][0], "./Material/images/enemy1_down1_bw.png");
loadimage(&image_enemy_destroy[0][1][0], "./Material/images/enemy1_down1_w.png");
loadimage(&image_enemy_destroy[0][0][1], "./Material/images/enemy1_down2_bw.png");
loadimage(&image_enemy_destroy[0][1][1], "./Material/images/enemy1_down2_w.png");
loadimage(&image_enemy_destroy[0][0][2], "./Material/images/enemy1_down3_bw.png");
loadimage(&image_enemy_destroy[0][1][2], "./Material/images/enemy1_down3_w.png");
loadimage(&image_enemy_destroy[0][0][3], "./Material/images/enemy1_down4_bw.png");
loadimage(&image_enemy_destroy[0][1][3], "./Material/images/enemy1_down4_w.png");
loadimage(&image_enemy_destroy[1][0][0], "./Material/images/enemy2_down1_bw.png");
loadimage(&image_enemy_destroy[1][1][0], "./Material/images/enemy2_down1_w.png");
loadimage(&image_enemy_destroy[1][0][1], "./Material/images/enemy2_down2_bw.png");
loadimage(&image_enemy_destroy[1][1][1], "./Material/images/enemy2_down2_w.png");
loadimage(&image_enemy_destroy[1][0][2], "./Material/images/enemy2_down3_bw.png");
loadimage(&image_enemy_destroy[1][1][2], "./Material/images/enemy2_down3_w.png");
loadimage(&image_enemy_destroy[1][0][3], "./Material/images/enemy2_down4_bw.png");
loadimage(&image_enemy_destroy[1][1][3], "./Material/images/enemy2_down4_w.png");
loadimage(&image_enemy_destroy[2][0][0], "./Material/images/enemy3_down1_bw.png");
loadimage(&image_enemy_destroy[2][1][0], "./Material/images/enemy3_down1_w.png");
loadimage(&image_enemy_destroy[2][0][1], "./Material/images/enemy3_down2_bw.png");
loadimage(&image_enemy_destroy[2][1][1], "./Material/images/enemy3_down2_w.png");
loadimage(&image_enemy_destroy[2][0][2], "./Material/images/enemy3_down3_bw.png");
loadimage(&image_enemy_destroy[2][1][2], "./Material/images/enemy3_down3_w.png");
loadimage(&image_enemy_destroy[2][0][3], "./Material/images/enemy3_down4_bw.png");
loadimage(&image_enemy_destroy[2][1][3], "./Material/images/enemy3_down4_w.png");
loadimage(&image_enemy_destroy[2][0][4], "./Material/images/enemy3_down5_bw.png");
loadimage(&image_enemy_destroy[2][1][4], "./Material/images/enemy3_down5_w.png");
loadimage(&image_enemy_destroy[2][0][5], "./Material/images/enemy3_down6_bw.png");
loadimage(&image_enemy_destroy[2][1][5], "./Material/images/enemy3_down6_w.png");
//加载子弹
loadimage(&image_bullet, "./Material/images/bullet1.png");
}
//敌机毁灭动画函数
void EnemyDestroy(int i)
{
if (enemy[i].type == 1)
{
putimage(enemy[i].x, enemy[i].y, &image_enemy_destroy[enemy[i].type][0][2], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &image_enemy_destroy[enemy[i].type][1][2], SRCERASE);
}
else if (enemy[i].type == 2)
{
putimage(enemy[i].x, enemy[i].y, &image_enemy_destroy[enemy[i].type][0][4], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &image_enemy_destroy[enemy[i].type][1][4], SRCERASE);
}
else if (enemy[i].type == 0)
{
putimage(enemy[i].x, enemy[i].y, &image_enemy_destroy[enemy[i].type][0][2], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &image_enemy_destroy[enemy[i].type][1][2], SRCERASE);
}
}
//游戏初始化函数
void GameInit()
{
LoadIMAGE(); //调用加载函数
player.x = WIDTH / 2;
player.y = HEIGHT - 120;
player.live = true;
player.HP = 1;
//玩家子弹初始化
for (int i = 0; i < Bullet_NUM; i++)
{
bullet[i].live = false;
}
//敌机初始化
for (int i = 0; i < Enemy_NUM; i++)
{
enemy[i].live = false;
}
}
//产生子弹函数
void CreateBullet()
{
for (int i = 0; i < Bullet_NUM; i++)
{
if (!bullet[i].live)
{
bullet[i].x = (player.x + Player_WIDTH/2);
bullet[i].y = (player.y - Bullet_HEIGHT);
bullet[i].live = true;
break;
}
}
}
//产生敌机函数
void CreateEnemy()
{
int Random_value;
for (int i = 0; i < Enemy_NUM; i++)
{
if (!enemy[i].live)
{
Random_value = rand();
if (Random_value % 10 == 9)
{
enemy[i].type = 2;
enemy[i].HP = 10;
}
else if (Random_value % 10 < 6)
{
enemy[i].type = 0;
enemy[i].HP = 1;
}
else
{
enemy[i].type = 1;
enemy[i].HP = 3;
}
srand(clock());
enemy[i].x = rand() % 4 * 100 + rand() % 10 * 10 + rand() % 10;
enemy[i].y = - 126;
enemy[i].live = true;
break;
}
}
}
//消灭敌机函数
void AttackEnemy()
{
for (int i = 0; i < Bullet_NUM; i++)
{
if (bullet[i].live)
{
for (int j = 0; j < Enemy_NUM; j++)
{
if (enemy[j].live)
{
if (enemy[j].type == 0)
{
if ((bullet[i].x >= enemy[j].x) && ((bullet[i].x + Bullet_WIDTH) <= (enemy[j].x + Enemy0_WIDTH)) && ((bullet[i].y + Bullet_HEIGHT) <= (enemy[j].y + Enemy0_HEIGHT)) && (bullet[i].y >= enemy[j].y))
{
bullet[i].live = false;
enemy[j].HP--;
}
}
if (enemy[j].type == 1)
{
if ((bullet[i].x >= enemy[j].x) && ((bullet[i].x + Bullet_WIDTH) <= (enemy[j].x + Enemy1_WIDTH)) && ((bullet[i].y + Bullet_HEIGHT) <= (enemy[j].y + Enemy1_HEIGHT)) && (bullet[i].y >= enemy[j].y))
{
bullet[i].live = false;
enemy[j].HP--;
}
}
if (enemy[j].type == 2)
{
if ((bullet[i].x >= enemy[j].x) && ((bullet[i].x + Bullet_WIDTH) <= (enemy[j].x + Enemy2_WIDTH)) && ((bullet[i].y + Bullet_HEIGHT) <= (enemy[j].y + Enemy2_HEIGHT)) && (bullet[i].y >= enemy[j].y))
{
bullet[i].live = false;
enemy[j].HP--;
}
}
}
}
}
}
}
//游戏的窗口绘制函数
void GameDraw()
{
//把背景图片贴到窗口
putimage(0, 0, &background);
//飞机图片贴到窗口
putimage(player.x, player.y, &image_player[0], NOTSRCERASE);
putimage(player.x, player.y, &image_player[1], SRCERASE);
//子弹图片
for (int i = 0; i < Bullet_NUM; i++)
{
if (bullet[i].live)
{
putimage(bullet[i].x, bullet[i].y, &image_bullet);
}
}
//敌机图片
for (int i = 0; i < Enemy_NUM; i++)
{
if (enemy[i].HP <= 0)
{
EnemyDestroy(i);
enemy[i].live = false;
}
if (enemy[i].live)
{
putimage(enemy[i].x, enemy[i].y, &image_enemy[0][enemy[i].type], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &image_enemy[1][enemy[i].type], SRCERASE);
}
}
}
//子弹移动,存活判断函数
void BulletMove(float speed)
{
for (int i = 0; i < Bullet_NUM; i++)
{
if (bullet[i].live)
{
bullet[i].y -= speed; //子弹移动速度
if (bullet[i].y < 0) //子弹存活条件判断
{
bullet[i].live = false;
}
}
}
}
//敌机的移动,存活判断函数
void WnemyMove()
{
for (int i = 0; i < Enemy_NUM; i++)
{
if (enemy[i].live)
{
//敌机的移动速度
if (enemy[i].type == 0)
{
enemy[i].y += 0.1;
}
else if (enemy[i].type == 1)
{
enemy[i].y += 0.02;
}
else
{
enemy[i].y += 0.005;
}
//敌机的存活条件判断
if (enemy[i].y > 700)
{
enemy[i].live = false;
}
}
}
}
//玩家的存活判断函数
void PlayerLive()
{
for (int i = 0; i < Enemy_NUM; i++)
{
if (enemy[i].type == 0)
{
if (player.x > (enemy[i].x - Player_WIDTH * 0.7) && player.x < (enemy[i].x + Enemy0_WIDTH * 0.7) && player.y >(enemy[i].y - Player_HEIGHT * 0.8) && player.y < (enemy[i].y + Enemy0_HEIGHT * 0.8))
{
player.HP--;
}
}
if (enemy[i].type == 1)
{
if (player.x > (enemy[i].x - Player_WIDTH * 0.7) && player.x < (enemy[i].x + Enemy1_WIDTH * 0.7) && player.y >(enemy[i].y - Player_HEIGHT * 0.8) && player.y < (enemy[i].y + Enemy1_HEIGHT * 0.8))
{
player.HP--;
}
}
if (enemy[i].type == 2)
{
if (player.x > (enemy[i].x - Player_WIDTH * 0.7) && player.x < (enemy[i].x + Enemy2_WIDTH * 0.7) && player.y >(enemy[i].y - Player_HEIGHT * 0.8) && player.y < (enemy[i].y + Enemy2_HEIGHT * 0.8))
{
player.HP--;
}
}
}
if (player.HP <= 0)
{
player.live = false;
printf("游戏结束");
exit(0);
}
}
//角色移动函数
void PlayerMove(float speed)
{
//使用windows函数获取键盘输入 GetAsyncKeyState 非阻塞函数,较为流畅
if ((GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W')) && player.y > 0) player.y -= speed;
if ((GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A')) && player.x > 0) player.x -= speed;
if ((GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState('S')) && (player.y + Player_HEIGHT) < HEIGHT) player.y += speed;
if ((GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D')) && (player.x + Player_WIDTH) < WIDTH) player.x += speed;
}
//主函数
int main()
{
clock_t start, end;
//创建一个窗口,控制台窗口是自动创建,而图形窗口需要我们自己手动创建
initgraph(WIDTH,HEIGHT,SHOWCONSOLE); //创建绘图窗口
GameInit(); //调用初始化函数
//开始游戏
outtextxy(170, 350, _T("按任意键开始游戏"));
_getch();
//双缓冲绘图(防止图片闪烁)
BeginBatchDraw(); //这个函数用于开始批量绘图。执行后,任何绘图操作都将暂时不输出到屏幕上,直到执行 FlushBatchDraw 或 EndBatchDraw 才将之前的绘图输出。
while (1)
{
start = clock(); //与end搭配,做了一个计时器,来控制子弹发射时间差
while (1)
{
end = clock();
if (end - start > 400)
{
CreateBullet(); //产生子弹函数
CreateEnemy(); //产生敌机函数
break;
}
AttackEnemy(); //调用消灭敌机函数
GameDraw(); //调用绘制函数
FlushBatchDraw(); //这个函数用于执行未完成的绘制任务。
BulletMove(0.15); //调用子弹移动函数
WnemyMove(); //调用敌机移动函数
PlayerMove(0.1); //调用角色移动函数
PlayerLive(); //调用角色存活判断函数
}
}
EndBatchDraw(); //这个函数用于结束批量绘制,并执行未完成的绘制任务。
return 0;
}
#该代码还有很大修改和优化空间。