C语言飞机大战小游戏

本文档详细介绍了使用C语言和EasyX图形库创建的一个飞行射击游戏的设计过程。游戏包括玩家飞机、敌机和子弹的创建、移动、碰撞检测等功能,并提供了完整的代码实现。代码已在VS2019环境下测试通过,适合初学者学习。
摘要由CSDN通过智能技术生成

说明

此设计可以作为C语言课程设计,主要用的是easyx图形库;

在VS2019成功运行,注释比较全面,对没有C语言基础的小白也很友好;

若有些地方还可以完善,请指正。

设计游戏的思路主要从以下几个当面:
1.游戏图片的保存及绘制;其中主要包括玩家、子弹、敌机图片;
2.封装的函数包括玩家的移动、子弹的创建、
  子弹的移动、敌机的创建、敌机的移动;
3.使用的逻辑主要有边界的处理,子弹击中敌机;
4.在主函数运行所有的功能函数
下面开始介绍主要功能函数吧

枚举出设计中所需要的常量

enum TYPE
{
	WIDTH = 480,		//窗口的宽度
	HEIGHT = 600,		//窗口的高度
	PLAYERHEIGHT = 60,		//玩家飞机的高度
	PLAYYERWIDTH = 90,			//玩家飞机的宽度
	BULLET_NUM = 15,			//玩家子弹的数量
	ENEMY_NUM=6,			//敌机的数量
	BIG,
	SMALL,					
	ENEMY_1_WIDTH=70,			//Boss的宽度
	ENEMY_1_HEIGHT=78,		//Boss的高度
	ENEMY_2_WIDTH=60,
	ENEMY_2_HEIGHT=60
};

创建结构体,其中包括的成员有玩家、敌机、玩家

struct Plane
{
	int x;
	int y;
	bool live;
	int width;
	int hegiht;
	int hp;			//敌机的血量
	int type;		//敌机的类别
}player,bullet[BULLET_NUM],enemy[ENEMY_NUM];

主要的功能函数

图片加载

	void LoadIm()

游戏绘制

	void gameDraw();
	//游戏初始化
	void initGanme();

数据的创建

	void creatEnemy();
	/*这里创建的敌机判断敌机的类型及生命状态*/
	void creatBullet();
	/*子弹是通过获取键盘信息创建的*/

逻辑处理

 1.void playerMove();
 /*主要的对玩家的坐标处理:
 *左边界坐标要大于玩家宽度的1/2,
 *右边界的坐标要小于主界面的宽度减去玩家宽度的1/2;
 *上边界的坐标要大于玩家的高度;
 *下边界的坐标应该小于主界面的高度减去玩家高度1/2;
 */
 2.void playPlane();
 /*这里的逻辑是子弹的坐标应该在敌机区域内
 *主要实现的代码如下
 */
 if (bullet[k].x > enemy[i].x 
	&& bullet[k].x<enemy[i].x + enemy[i].width
	&& bullet[k].y>enemy[i].y
	&& bullet[k].y < enemy[i].y + enemy[i].hegiht)
	{
		bullet[k].live = false;		//事件发生,消除子弹
		enemy[i].hp--;			//敌机的血量-1
	}

程序所用代码(已测试)

#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<time.h>

enum My
{
	WIDTH = 480,		//窗口的宽度
	HEIGHT = 600,		//窗口的高度
	PLAYERHEIGHT = 60,		//玩家飞机的高度
	PLAYYERWIDTH = 90,			//玩家飞机的宽度
	BULLET_NUM = 15,			//玩家子弹的数量
	ENEMY_NUM=6,			//敌机的数量
	BIG,
	SMALL,					
	ENEMY_1_WIDTH=70,			//Boss的宽度
	ENEMY_1_HEIGHT=78,		//Boss的高度
	ENEMY_2_WIDTH=60,
	ENEMY_2_HEIGHT=60
};
struct Plane
{
	int x;
	int y;
	bool live;
	int width;
	int hegiht;
	int hp;
	int type;		//敌机的类别
}player,bullet[BULLET_NUM],enemy[ENEMY_NUM];

//保存背景图片
IMAGE bk;

//保存玩家图片
IMAGE img_role[2];

//保存子弹图片
IMAGE img_bullet[2];

//保存敌机图片
IMAGE img_enemy[2][2];

//保存继续
IMAGE img_continue;

//保存退出
IMAGE img_exit;

//把图片加载到程序中
void LoadIm()
{
	//加载背景图片
	loadimage(&bk, "./images/background.jpg");
	//加载玩家图片
	loadimage(&img_role[0], "./images/planeNormal_1.jpg");
	loadimage(&img_role[1], "./images/planeNormal_2.jpg");
	//加载子弹图片
	loadimage(&img_bullet[0], "./images/bullet_1.jpg");
	loadimage(&img_bullet[1], "./images/bullet_2.jpg");
	//加载敌机图片
	loadimage(&img_enemy[0][0], "./images/enemy_1.jpg");
	loadimage(&img_enemy[0][1], "./images/enemy_2.jpg");
	loadimage(&img_enemy[1][0], "./images/enemy_3.jpg");
	loadimage(&img_enemy[1][1], "./images/enemy_4.jpg");
	//加载游戏结束图片
	loadimage(&img_continue, "./images/continue.jpg");
	//加载退出图片
	loadimage(&img_exit, "./images/exit.jpg");

}
//敌机的类型
void enemyHp(int i)
{
	int flag = rand() % 10;
	if (flag>=0&&flag<=2)	//0~9 这里是有3/10的几率生成大飞机
	{
		enemy[i].type = BIG;
		enemy[i].hp = 3;
		enemy[i].width = ENEMY_1_WIDTH;
		enemy[i].hegiht = ENEMY_1_HEIGHT;
	}
	else
	{
		enemy[i].type = SMALL;
		enemy[i].hp = 1;
		enemy[i].width = ENEMY_2_WIDTH;
		enemy[i].hegiht = ENEMY_2_HEIGHT;
	}
}
//初始化游戏数据
void gameInit()
{
	//初始化玩家数据
	player.x = WIDTH / 2 - PLAYYERWIDTH/2;
	player.y = HEIGHT - PLAYERHEIGHT;
	player.hp = 4;
	player.live = true;
	//初始化子弹
	for (int i = 0; i < BULLET_NUM; i++)
	{
		bullet[i].x = 0;
		bullet[i].y = 0;
		bullet[i].live = false;	//设置为false可以让子弹不在画面中展示
	}
	//初始化敌机
	for (int i = 0; i < ENEMY_NUM; i++)
	{
		enemy[i].live = false;
		enemyHp(i);
	}

}
//游戏的绘制函数
void gameDraw()
{
	LoadIm();
	//贴窗口文件
	putimage(0, 0, &bk);
	//绘制玩家图片
	if (player.live)
	{

		putimage(player.x, player.y, &img_role[0], NOTSRCERASE);
		putimage(player.x, player.y, &img_role[1], SRCINVERT);
	}
	for (int i = 0; i < BULLET_NUM; i++)
	{
		if (bullet[i].live)
		{
			//绘制子弹图片
			putimage(bullet[i].x, bullet[i].y, &img_bullet[0], NOTSRCERASE);
			putimage(bullet[i].x, bullet[i].y, &img_bullet[1], SRCINVERT);
		}
	}
	//绘制敌机
	for (int i = 0; i < ENEMY_NUM; i++)
	{
		if (enemy[i].live)
		{
			if (enemy[i].type == SMALL)
			{
				putimage(enemy[i].x, enemy[i].y, &img_enemy[1][0], NOTSRCERASE);
				putimage(enemy[i].x, enemy[i].y, &img_enemy[1][1], SRCINVERT);
			}
			else
			{
				putimage(enemy[i].x, enemy[i].y, &img_enemy[0][0], NOTSRCERASE);
				putimage(enemy[i].x, enemy[i].y, &img_enemy[0][1], SRCINVERT);
			}
		}
	}

	//游戏结束界面
	if (player.live == false)
	{
		putimage(40, 220, &img_continue);
		putimage(290, 220, &img_exit);
	}
	//播放音乐
	//mciSendString(TEXT("open music.mp3 alias music"), 0, 0, 0);
	//mciSendString(TEXT(" play music"), 0, 0, 0);
}
//定时器
bool Timer(int ms, int id)
{
	static DWORD t[10];
	if (clock()-t[id]>ms)
	{
		t[id] = clock();
		return true;
	}
	return false;
}

//创建子弹
void creatBullet()
{
	for (int i = 0; i < BULLET_NUM; i++)
	{
		if (!bullet[i].live)
		{

			bullet[i].x = player.x + 35;
			bullet[i].y = player.y;
			bullet[i].live = true;
			break;
		}
	}
}
//敌机的移动
void enemyMove(int speed)
{
	for (int i = 0; i < ENEMY_NUM; i++)
	{
		if (enemy[i].live)
		{
			enemy[i].y += speed;
			if (enemy[i].y > HEIGHT)
			{
				enemy[i].live = false;
			}
		}
	}
}
//产生敌机
void creatEnemy()
{
	for (int i = 0; i < ENEMY_NUM; i++)
	{
		if (!enemy[i].live)
		{
			enemy[i].live = true;
			enemy[i].x = rand() % (WIDTH - ENEMY_1_WIDTH/2);
			enemy[i].y = 0;
			enemyHp(i);
			break;
		}
	}
	enemyMove(3);
}


//玩家移动,判断键盘消息
void playerMove(int speed)
{

#if 0

	//如果有键盘按下,则返回真
	if (_kbhit)
	{
		//1.方式一 _getch() 阻塞函数,和scanf一样,如果没有输入,就会卡在主程序,一直等待输入,且不是标准C的函数
		char key = _getch();
		switch (key)
		{
		case 'w':
		case 'W':
			player.y -= speed;
			break;
		case 's':
		case 'S':
			player.y += speed;
			break;
		case 'a':
		case 'A':
			player.x -= speed;
			break;
		case 'd':
		case 'D':
			player.x += speed;
			break;
		default:
			break;
		}
	}
#elif 1
	//2.使用Windows函数获取键盘的输入	GetAsyncKeyState  非阻塞函数
	//如果用字母,可以用大写;则键盘的大小写都可以被检测到
	if (GetAsyncKeyState(VK_UP)||GetAsyncKeyState('W'))
	{
		if (player.y > 0-PLAYERHEIGHT/2)
		{
			player.y -= speed;
		}
		printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);
	}
	if (GetAsyncKeyState(VK_DOWN)||GetAsyncKeyState('S'))
	{
		if (player.y < HEIGHT - PLAYERHEIGHT/2)
		{
			player.y += speed;
		}
		printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);
	}	
	if (GetAsyncKeyState(VK_LEFT)||GetAsyncKeyState('A'))
	{
		if (player.x > 0-PLAYYERWIDTH/2)
		{
			player.x -= speed;
		}
		printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);
	}	
	if (GetAsyncKeyState(VK_RIGHT)||GetAsyncKeyState('D'))
	{
		if (player.x < WIDTH - PLAYYERWIDTH/2)
		{
			player.x += speed;
		}
		printf("(%d,%d),Live:%d,Hp:%d\n", player.x, player.y, player.live, player.hp);
	}
#endif // 0

	if (GetAsyncKeyState(VK_SPACE)&& Timer(200, 1) ||GetAsyncKeyState('J')&&Timer(200,1))	//延时时间,毫秒
	{
		if (player.live)
		{
			creatBullet();
		}
	}
}
//子弹的移动
void bulletMove()
{
	for (int i = 0; i < BULLET_NUM; i++)
	{
		if (bullet[i].live)
		{
			bullet[i].y -= 2;
			//bullet[i].x -= 1;
			if (bullet[i].y < 0)
			{
				bullet[i].live = false;
			}
		}
	}
}


//击中飞机,碰撞算法
void playPlane()
{
	for (int i = 0; i < ENEMY_NUM; i++)
	{
		if (!enemy[i].live)
		{
			continue;
		}
		for (int k = 0; k < BULLET_NUM; k++)
		{
			if (!bullet[i].live)
			{
				continue;
			}
			if (bullet[k].x > enemy[i].x && bullet[k].x<enemy[i].x + enemy[i].width
				&& bullet[k].y>enemy[i].y && bullet[k].y < enemy[i].y + enemy[i].hegiht)
			{
				bullet[k].live = false;
				enemy[i].hp--;
			}
		}
		if (enemy[i].hp<=0)
		{
			enemy[i].live = false;
		}
	}
}


int main()
{
	//创建一个窗口
	initgraph(WIDTH, HEIGHT,SHOWCONSOLE);
	gameInit();
	//双缓冲绘图
	BeginBatchDraw();
	while (1)
	{
		gameDraw();
		FlushBatchDraw();
		playerMove(5);
		bulletMove();
		if (Timer(100,0))
		{
			creatEnemy();
		}
		if (Timer(200, 2))
		{

			enemyMove(2);
		}
		playPlane();
	}
	EndBatchDraw();
	return 0;
}

程序运行截图

在这里插入图片描述

问题处理

图片

1.在项目里面创建images文件夹;
2.加入原图和掩码图,黑白的为掩码图;
在这里插入图片描述

字符集

在这里插入图片描述打开-“项目”-“属性”,按照上图将“字符集”改成上图模式然后可以运行了;

  • 4
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
C语言飞机大战小游戏是一个基于控制台的游戏,源代码中引用了plane.h头文件来定义游戏所需的函数和常量。main函数调用了game函数开始游戏,并在游戏结束后使用system("pause")来暂停程序。 在plane.h中,定义了Showmap函数用于打印地图,game函数用于调用开始游戏,Move函数用于控制飞机的移动,Buttle函数用于生成子弹,FadeButtle函数用于消除子弹,Plan函数用于生成敌机,FeoButtle函数用于生成敌机的子弹,Judge函数用于判断游戏的胜负。 在Plan函数中,使用了随机数种子srand((unsigned)time(NULL))来生成随机数,然后根据随机数来确定敌机的坐标。敌机的坐标不能与墙壁重合,也不能与我方飞机碰撞。当找到合适的坐标后,将地方飞机的数据设置为4,并打破循环。 通过调用这些函数和利用随机数生成敌机的坐标,可以实现一个简单的C语言飞机大战小游戏。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C语言编写飞机大战游戏项目](https://blog.csdn.net/B85951005/article/details/126037896)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十九.19

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值