飞机大战简易版

这篇文章像你展示经典游戏飞机大战的简易代码

头文件,宏定义,初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include<stdio.h>
#include<easyx.h> //only for c++
#include<time.h>
#include<stdlib.h>
#include<math.h>
#include<conio.h>
#include<Windows.h>
#pragma comment(lib,"Winmm.lib")

#define SCREEN_WIDTH 400
#define SCREEN_HEIGHT 700

#define PLANE_SIZE 50
#define ENEMY_NUM 8
#define ENEMY_SPEED 1.0 //产生敌机的速度
#define BULLET_NUM 10

typedef struct pos
{
int x;
int y;
}POS;

typedef struct plane
{
POS planePos;
POS planeBullets[BULLET_NUM];
int bulletLen; //子弹剩余数量
int bulletSpeed;

}PLANE;

PLANE myPlane;
PLANE enemyPlanes[ENEMY_NUM];

int enemyPlaneLen;
static time_t startTime, endTime;
IMAGE img[3]; //图片库提供,定义图片类型的变量
int score = 0;

main函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
initGame();
loadimage(&img[0],"img/background1.png",SCREEN_WIDTH, SCREEN_HEIGHT); //装载图片
loadimage(&img[1], "img/enemy1 change.png", PLANE_SIZE, PLANE_SIZE);
loadimage(&img[2], "img/me1change.png", PLANE_SIZE, PLANE_SIZE);

while(1)
{
drawGame();
updataGame();
Sleep(1000 / 60);
}

getchar();
return 0;

}

初始化游戏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void initGame()
{
initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
score = 0;

srand((unsigned)time(NULL)); /*随机数种子:使用 srand(unsigned seed)
设置伪随机序列的起点;常见写法 srand((unsigned)time(NULL)) 以时间作为随机种子(你在 initGame() 已用到)*/
myPlane.bulletLen = 0;
myPlane.bulletSpeed = 3;
myPlane.planePos = { SCREEN_WIDTH / 2 - PLANE_SIZE / 2,SCREEN_HEIGHT - PLANE_SIZE };

enemyPlaneLen = 0;

startTime = time(NULL); //
}

绘制游戏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
void drawGame()
{
BeginBatchDraw(); //开始批量贴图
putimage(0, 0, &img[0]);
putimage(myPlane.planePos.x - PLANE_SIZE / 3, myPlane.planePos.y - PLANE_SIZE / 3, &img[2],SRCAND); //putimage 以左上角为锚点,

for (int i = 0; i < enemyPlaneLen; i++)
{
putimage(enemyPlanes[i].planePos.x - PLANE_SIZE/3, enemyPlanes[i].planePos.y - PLANE_SIZE/3, &img[1], SRCAND);
}

for(int i = 0;i< myPlane.bulletLen;i++)
{
solidcircle(myPlane.planeBullets[i].x, myPlane.planeBullets[i].y, PLANE_SIZE / 4);;
}

RECT rect = {0,PLANE_SIZE,SCREEN_WIDTH,SCREEN_HEIGHT }; //设置一个矩形
setbkmode(TRANSPARENT); //设置矩形为透明
char str[30] = { 0 };
sprintf_s(str, "分数:%d", score); //将分数转变成字符串形式
drawtext(str, &rect, DT_TOP | DT_CENTER); //在哪里绘制
EndBatchDraw(); //结束批量贴图

}

游戏实时更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
void updataGame()
{
if (GetAsyncKeyState('W') & 0x8000)
{
myPlane.planePos.y -= 4;
}
if (GetAsyncKeyState('S') & 0x8000)
{
myPlane.planePos.y += 4;
}
if (GetAsyncKeyState('A') & 0x8000)
{
myPlane.planePos.x -= 4;
}
if (GetAsyncKeyState('D') & 0x8000)
{
myPlane.planePos.x += 4;
}

//获取子弹和子弹位置
if (_kbhit()) //检查键盘缓冲区是否有按键可读,返回非 0 表示有键可读。
{
if (_getch() ==' ')
{
if (myPlane.bulletLen < BULLET_NUM) //修改
{
PlaySound("img/.archivetempboom(1).mp3", NULL, SND_FILENAME | SND_ASYNC | SND_NOWAIT);
myPlane.planeBullets[myPlane.bulletLen] = myPlane.planePos;
myPlane.bulletLen++;
}
}
}

for (int i = 0; i < enemyPlaneLen; i++) //敌机速度
{
enemyPlanes[i].planePos.y += 2;
}

for (int i = 0; i < myPlane.bulletLen; i++) //子弹移动
{
myPlane.planeBullets[i].y -= myPlane.bulletSpeed;
}
initEnemyPlane();
destroyEnemyPlane();
destroyBullet();

}

初始化敌机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void initEnemyPlane()
{
endTime = time(NULL); //读取当前时间(秒)
double elapsedtime = difftime(endTime, startTime); //计算从 startTime 到当前的秒数差。
if (elapsedtime >= ENEMY_SPEED) //如果经过时间 >= 宏 ENEMY_SPEED,则生成一架敌机:
{
// 增加容量检查,防止越界写入 enemyPlanes
if (enemyPlaneLen < ENEMY_NUM)
{
int x = (rand() % (SCREEN_WIDTH - 2 * PLANE_SIZE)) + PLANE_SIZE; //rand范围是 0 到 RAND_MAX
int y = -PLANE_SIZE;

enemyPlanes[enemyPlaneLen].planePos.x = x;
enemyPlanes[enemyPlaneLen].planePos.y = y;
enemyPlaneLen++;
}
// 若达到上限,可选择丢弃、复用槽位或扩容(std::vector)
}
startTime = endTime;
}

销毁敌机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void destroyEnemyPlane()
{
for (int i = 0; i < enemyPlaneLen; i++)
{
if (areInierSecting(myPlane.planePos, enemyPlanes[i].planePos, PLANE_SIZE/3 + PLANE_SIZE / 3)) //碰到飞机
{
if (IDYES == MessageBox(GetHWnd(), "是否重新开始", "提示", MB_YESNO))
{
initGame();
}
else
{
exit(0);
}
}

if (enemyPlanes[i].planePos.y > SCREEN_HEIGHT) //判断敌机出界
{
for (int j = i; j < enemyPlaneLen; j++)
{
enemyPlanes[j] = enemyPlanes[j + 1];
}
enemyPlaneLen--;
i--; //如果飞机同时飞出屏幕,都要删除
}
}

}

检测碰撞函数

1
2
3
4
int areInierSecting(POS c1, POS c2, int radius)
{
return abs(c1.x - c2.x) <= radius && abs(c1.y - c2.y) <= radius;
}

销毁子弹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void destroyBullet()
{
for (int i = 0; i < myPlane.bulletLen; i++)
{
for (int j = 0; j < enemyPlaneLen; j++)
{
if (areInierSecting(myPlane.planeBullets[i], enemyPlanes[j].planePos, PLANE_SIZE / 4 + PLANE_SIZE / 2))
{
for (int x = i; x < myPlane.bulletLen; x++)
{
myPlane.planeBullets[x] = myPlane.planeBullets[x + 1];
}
for (int x = i; x < enemyPlaneLen; x++)
{
enemyPlanes[x] = enemyPlanes[x + 1];
}
enemyPlaneLen--;
myPlane.bulletLen--;
j--;
score += 100;
}
}
if (myPlane.planeBullets[i].y < 0)
{
for (int x = i; x < myPlane.bulletLen; x++)
{
myPlane.planeBullets[x] = myPlane.planeBullets[x + 1];
}
myPlane.bulletLen--;
i--;
}

}
}

希望对你能有所帮助