1.效果图
2.直接上代码:
#include<stdio.h>
#include<graphics.h>//要安装的,图形库头文件easyx
#include<mmsystem.h>//win32 多媒体设备接口
#pragma comment(lib,"winmm.lib")
#define WIN_WIDTH 591
#define WIN_HEIGHT 864
#define BULLET_NUM 15//最大子弹数量
#define ENEMY_NUM 10
/*
int a;
char b;
*/
struct Image
{
IMAGE bakcGround;//背景图片
IMAGE player[2];
IMAGE bullet[2];
IMAGE enemy[4];
}image;
//结构体三兄弟,结构体,枚举,联合
enum TYPE
{
SAMLL,
BIG,
};
struct Plane //我,敌机,子弹
{
int x;
int y;
bool flag;//是否存活 true flase
union
{
int type;//敌机独有属性
int score;//玩家独有属性
}un;
int hp;//血量
}player, bullet[BULLET_NUM], enemy[ENEMY_NUM];
DWORD t1, t2,t3,t4;
//分模块处理,专门的事情,专门的函数做
void EnemyHP(int i)
{
if (rand() % 10 == 0) //十分之一的概率产生一个大飞机
{
enemy[i].un.type = BIG;
enemy[i].hp = 3;
}
else
{
enemy[i].un.type = SAMLL;
enemy[i].hp = 1;
}
}
//加载图片
void GameInit()
{
//设置随机数种子
srand(GetTickCount());
t1 = t2=t3=t4 = GetTickCount();//获取系统开机到当前所经过的毫秒数
//播放音乐
mciSendString("open ./images/game_music.mp3 alias BGM",0,0,0);//向多媒体设备接口发送字符串 media device interface
mciSendString("play BGM repeat", 0, 0, 0);
//加载背景图片
loadimage(&image.bakcGround, "./images/background.jpg");//把图片加载并保存
loadimage(&image.player[0], "./images/planeNormal_1.jpg");
loadimage(&image.player[1], "./images/planeNormal_2.jpg");
loadimage(&image.bullet[0], "./images/bullet1.jpg");
loadimage(&image.bullet[1], "./images/bullet2.jpg");
loadimage(&image.enemy[0], "./images/enemy_1.jpg");
loadimage(&image.enemy[1], "./images/enemy_2.jpg");
loadimage(&image.enemy[2], "./images/enemyPlane1.jpg");
loadimage(&image.enemy[3], "./images/enemyPlane2.jpg");
//初始化玩家数据
player.x = WIN_WIDTH/2;
player.y = WIN_HEIGHT - 120;
player.flag = true;
player.hp = 999;
player.un.score = 0;
//初始化子弹数据
for (int i = 0; i < BULLET_NUM; i++)
{
bullet[i].flag = false;
}
//初始化敌机
for (int i = 0; i < ENEMY_NUM; i++)
{
enemy[i].flag = false;
EnemyHP(i);
}
}
void Gamedraw()
{
//绘制背景
putimage(0, 0, &image.bakcGround);
//绘制玩家
putimage(player.x, player.y, &image.player[0], NOTSRCERASE);
putimage(player.x, player.y, &image.player[1], SRCINVERT);
//绘制子弹
for (int i = 0; i < BULLET_NUM; i++)
{
if (bullet[i].flag == true)
{
putimage(bullet[i].x, bullet[i].y, &image.bullet[0], NOTSRCERASE);
putimage(bullet[i].x, bullet[i].y, &image.bullet[1], SRCINVERT);
}
}
for (int i = 0; i < ENEMY_NUM; i++)
{
if (enemy[i].flag)
{
if (enemy[i].un.type == TYPE::SAMLL)
{
putimage(enemy[i].x, enemy[i].y, &image.enemy[0], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &image.enemy[1], SRCINVERT);
}
else if (enemy[i].un.type == TYPE::BIG)
{
putimage(enemy[i].x, enemy[i].y, &image.enemy[2], NOTSRCERASE);
putimage(enemy[i].x, enemy[i].y, &image.enemy[3], SRCINVERT);
}
}
}
}
void CreateBullet()
{
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;
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 CreateEnemy()
{
for (int i = 0; i < ENEMY_NUM; i++)
{
if (enemy[i].flag == 0)
{
enemy[i].flag = true;
enemy[i].x = rand() % (WIN_WIDTH - 100);
enemy[i].y = 0;
EnemyHP(i);
break;
}
}
}
void EnemyMove(int speed)
{
for (int i = 0; i < ENEMY_NUM; i++)
{
if (enemy[i].flag)
{
enemy[i].y +=speed;
if (enemy[i].y>=WIN_HEIGHT)
{
enemy[i].flag = false;
}
}
}
}
void GameControl(int speed)
{
//_getch();GetAnsyncKeyState();
if (GetAsyncKeyState(VK_UP) && player.y>=0)
{
player.y-=speed;
}
if (GetAsyncKeyState(VK_DOWN) && player.y+120<=WIN_HEIGHT)
{
player.y += speed;
}
if (GetAsyncKeyState(VK_LEFT) && player.x+50>=0)
{
player.x -= speed;
}
if (GetAsyncKeyState(VK_RIGHT)&& player.x+55<=WIN_WIDTH)
{
player.x += speed;
}
//发射子弹
if (GetAsyncKeyState(VK_SPACE) && t2-t1>200)
{
CreateBullet();
mciSendString("close gun", 0, 0, 0);
mciSendString("open ./images/f_gun.mp3 alias gun", 0, 0, 0);
mciSendString("play gun", 0, 0, 0);
t1 = t2;
}
t2 = GetTickCount();
if (t4 - t3 > rand() % 500 + 500)
{
CreateEnemy();
t3 = t4;
}
t4 = GetTickCount();
EnemyMove(1);
BulletMove(1);
}
void PlayEnemy()
{
//1,遍历敌机数组 判断是否存活
//2,遍历子弹数组
//3,判断子弹是否击中敌机
//4,达到了,属性改变,血量--,存活状态,玩家分数++,
//5,如果血量为0,敌机死亡
}
int main()
{
initgraph(WIN_WIDTH, WIN_HEIGHT/*, SHOWCONSOLE*/);//创建一个图形窗口
GameInit();
BeginBatchDraw();//开启双款冲绘图,现在内存里面画好,在现实给你看
while (1)
{
Gamedraw();
FlushBatchDraw();//我想看了
GameControl(1);
}
EndBatchDraw();//结束
return 0;
3.源码获取,完整素材,学习交流:https://jq.qq.com/?_wv=1027&k=zi26CwKxhttps://jq.qq.com/?_wv=1027&k=zi26CwKx