C语言写愤怒的小鸟(带有图片和背景音乐)

大家好 , 我是逼哥 , 记得每天好好学习 , 天天向上 , 尤其是大学生 . 不要荒废学业.

首先说明 , 我使用的开发环境是  vs2017  , 有些函数方法可能不通用 ,大家可以百度下其他方法. 向童老师致敬

 

第一步:先读取本地的背景图片

 

1 . 这第一步就非常简单 , 只需要先读取背景图 , 并且显示出来就可以. 

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

void main()
{
	initgraph(350,600);
	IMAGE bird_bg; // 小鸟图片背景
	loadimage(&bird_bg ,  _T("D:\\桌面\\super_bird\\background.jpg") );
	putimage(0, 0, &bird_bg); // 在坐标(0 , 0 )位置显示IMAGE 对象
	_getch(); //防止窗口关闭
	closegraph();
}

2 . 处理小鸟

如果直接显示小鸟 

因为我们显示的小鸟图片是矩形 , 这样的小鸟是留有白色区域棱角就不好看了 ,此时就需要用函数去处理 , 是白色区域透明化

拿到小鸟的遮罩和原图

可以利用美图秀秀进行抠图 ,扣出原图和遮罩.

NOTSRCERASE 先对遮罩进行处理 , 使得遮罩白色变黑 ,黑色区域变透明

SRCINVERT 在对小鸟原图处理

 一定要遮罩在前 ,作为背景 , 小鸟在后

 

让两张处理过的图片在同一区域进行效果叠加  , 看小效果

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

void main()
{
	initgraph(350,600);
	IMAGE bird_bg; // 小鸟图片背景
	loadimage(&bird_bg ,  _T("D:\\桌面\\super_bird\\background.jpg") );
	putimage(0, 0, &bird_bg); // 在坐标(0 , 0 )位置显示IMAGE 对象

	IMAGE im_bird_shade; //遮罩
	IMAGE im_bird;
	loadimage(&im_bird_shade, _T("D:\\桌面\\super_bird\\bird1.jpg"));
	loadimage(&im_bird, _T("D:\\桌面\\super_bird\\bird2.jpg"));
	// 一定要遮罩在前 ,作为背景 , 小鸟在后
	putimage(100, 200, &im_bird_shade, NOTSRCERASE); //NOTSRCERASE -->目标图像 = NOT (目标图像 OR 源图像)  //遮罩的黑色进行透明处理 , 白色区域显黑色
	putimage(100, 200, &im_bird , SRCINVERT); //SRCINVERT---> 目标图像 = 目标图像 XOR 源图像   (三原色进行系列取反运算)

	_getch(); //防止窗口关闭
	closegraph(); //
}

 

版本升级处理 , 对 显示数据 进行 模块化 , 用函数来封装 . 修改后的代码.

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

// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")

//全局变量
IMAGE img_bk, img_bd1, img_bd2, img_bar_up1, img_bar_up2, img_bar_down1, img_bar_down2; int bird_x;
int bird_y;

void startup()
{
	initgraph(350, 600);
	loadimage(&img_bk, _T("D:\\桌面\\super_bird\\background.jpg") );
	loadimage(&img_bd1, _T("D:\\桌面\\super_bird\\bird1.jpg"));
	loadimage(&img_bd2, _T("D:\\桌面\\super_bird\\bird2.jpg"));
	bird_x = 50;
	bird_y = 200;


	BeginBatchDraw();
}

void show()
{
	putimage(0, 0, &img_bk);	// 显示背景	
	putimage(bird_x, bird_y, &img_bd1, NOTSRCERASE);  // 遮罩透明处理
	putimage(bird_x, bird_y, &img_bd2, SRCINVERT);// 显示小鸟	

	FlushBatchDraw();
	Sleep(50);
}

void updateWithoutInput()
{
	
}

void updateWithInput()
{
	
}

void gameover()
{
	EndBatchDraw();
	_getch();
	closegraph();
}

int main()
{
	startup();  // 数据初始化	
	while (1)  //  游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();     // 与用户输入有关的更新
	}
	gameover();     // 游戏结束、后续处理
	return 0;
}

 

第三步: 显示障碍物 ,并且让小鸟自由下落

1. 障碍物 ,和处理小鸟一致 , 只要读取图片 , 处理遮罩  , 处理障碍物原图 , 叠加显示即可

2. 小鸟自由下落 , 就是 改变 小鸟图片的左上角的起始绘画点的坐标.  只能上下自自由下落 ,改变小鸟的Y轴坐标即可 . 

3. 移动障碍物

4.障碍物 随机生成 , 并且随机高度

5.小鸟越过障碍物 , 并计算得分  ,  撞上柱子则死亡

 

看下效果

 

 

最后, 贴出所有的代码 , 环境是 : VS2017

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

// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")

#define width 350
#define high 600

//全局变量
IMAGE img_bk, img_bd1, img_bd2, img_bar_up1, img_bar_up2, img_bar_down1, img_bar_down2; 
int bird_x , bird_y;
int bar1_x, bar1_xDown, bar1_xTop; // 障碍物1的相关坐标
int score; // 得分,经过障碍物的个数
void startup()
{
	initgraph(width, high);
	loadimage(&img_bk, _T("D:\\桌面\\super_bird\\background.jpg") );
	loadimage(&img_bd1, _T("D:\\桌面\\super_bird\\bird1.jpg"));
	loadimage(&img_bd2, _T("D:\\桌面\\super_bird\\bird2.jpg"));

	//显示上下障碍物
	loadimage(&img_bar_up1, _T("D:\\桌面\\super_bird\\bar_up1.gif"));
	loadimage(&img_bar_up2, _T("D:\\桌面\\super_bird\\bar_up2.gif"));
	loadimage(&img_bar_down1, _T("D:\\桌面\\super_bird\\bar_down1.gif"));
	loadimage(&img_bar_down2, _T("D:\\桌面\\super_bird\\bar_down2.gif"));

	//小鸟
	bird_x = width / 7; // 50
	bird_y = high / 3; //200

	score = 0;

	//障碍物
	bar1_x = width;

	int randPosition = rand() % (high - 400) +50;  // 随机数就只在 50-250
	//注意这是上障碍物的起始坐标
	bar1_xTop = randPosition - high; // top 的范围就在 -550 ------  -350 之间   
	// 上障碍物画完 , 画下障碍物 , 间隔100
	bar1_xDown = bar1_xTop +high + 100; 

	BeginBatchDraw();
}

void show()
{
	putimage(0, 0, &img_bk);	// 显示背景	
	putimage(bird_x, bird_y, &img_bd1, NOTSRCERASE);  // 遮罩透明处理
	putimage(bird_x, bird_y, &img_bd2, SRCINVERT);// 显示小鸟	

	//显示 障碍物
	putimage(bar1_x, bar1_xTop, &img_bar_up1, NOTSRCERASE);  // 遮罩透明处理
	putimage(bar1_x, bar1_xTop, &img_bar_up2, SRCINVERT);// 显示上障碍物
	putimage(bar1_x, bar1_xDown, &img_bar_down1, NOTSRCERASE);  // 遮罩透明处理
	putimage(bar1_x, bar1_xDown, &img_bar_down2, SRCINVERT);// 显示下障碍物

	FlushBatchDraw();
	Sleep(50);
}

void updateWithoutInput()
{
	// 输入空格进行控制小鸟
	char input;
	if (_kbhit())
	{
		input = _getch();
		if (input == ' ' && bird_y > 20)
			bird_y -= 25;
	}
}

// 图形更新
void updateWithInput()
{
	// 小鸟不能飞出界面
	if (bird_y < 0 || bird_y > 556)
		_exit(0); // 结束

	// 小鸟的坐标不能出框 , Y轴不能小于0 , 不能大于580
	if (0 < bird_y && bird_y < 580)
		bird_y += 3;

	// 障碍物的移动
	if (bar1_x > -140)
		bar1_x -= 2; 
	else 
	{
		// 重新生成
		bar1_x = width;
		//障碍物
		int randPosition = rand() % (high - 400) + 50;  // 随机数就只在 50-250
														//注意这是上障碍物的起始坐标
		bar1_xTop = randPosition - high; // top 的范围就在 -550 ------  -350 之间   
										 // 上障碍物画完 , 画下障碍物 , 间隔100
		bar1_xDown = bar1_xTop + high + 100;
	}

	//得分计算 小鸟的宽度为34 , 柱子宽度为140
	if ( (bar1_x < bird_x + 34) && (bar1_x +140 > bird_x + 34) )  
	{
		if ((bird_y > bar1_xTop +600) && (bird_y < bar1_xDown))
		{
			score++;
		}
		else
		{
			_exit(0);
		}
	}
}

void gameover()
{

	EndBatchDraw();
	_getch();
	closegraph();
}

int main()
{
	startup();  // 数据初始化	
	while (1)  //  游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 界面的更新
		updateWithInput();     // 与用户输入有关的更新
	}
	gameover();     // 游戏结束、后续处理
	return 0;
}

 

到这里,我们可以配上音乐

可以引用 Windows Multimedia API
使用  #pragma comment(lib,"Winmm.lib")

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

// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")

#define width 350
#define high 600

//全局变量
IMAGE img_bk, img_bd1, img_bd2, img_bar_up1, img_bar_up2, img_bar_down1, img_bar_down2; 
int bird_x , bird_y;
int bar1_x, bar1_xDown, bar1_xTop; // 障碍物1的相关坐标
int score; // 得分,经过障碍物的个数
void startup()
{
	initgraph(width, high);
	loadimage(&img_bk, _T("D:\\桌面\\super_bird\\background.jpg") );
	loadimage(&img_bd1, _T("D:\\桌面\\super_bird\\bird1.jpg"));
	loadimage(&img_bd2, _T("D:\\桌面\\super_bird\\bird2.jpg"));

	//显示上下障碍物
	loadimage(&img_bar_up1, _T("D:\\桌面\\super_bird\\bar_up1.gif"));
	loadimage(&img_bar_up2, _T("D:\\桌面\\super_bird\\bar_up2.gif"));
	loadimage(&img_bar_down1, _T("D:\\桌面\\super_bird\\bar_down1.gif"));
	loadimage(&img_bar_down2, _T("D:\\桌面\\super_bird\\bar_down2.gif"));

	//小鸟
	bird_x = width / 7; // 50
	bird_y = high / 3; //200

	score = 0;

	//障碍物
	bar1_x = width;

	int randPosition = rand() % (high - 400) +50;  // 随机数就只在 50-250
	//注意这是上障碍物的起始坐标
	bar1_xTop = randPosition - high; // top 的范围就在 -550 ------  -350 之间   
	// 上障碍物画完 , 画下障碍物 , 间隔100
	bar1_xDown = bar1_xTop +high + 100; 

	BeginBatchDraw();


	mciSendString(_T("open D:\\桌面\\super_bird\\background.mp3 alias bkmusic"), NULL, 0, NULL);//打开背景音乐
	mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL);  // 循环播放
}

void show()
{
	putimage(0, 0, &img_bk);	// 显示背景	
	putimage(bird_x, bird_y, &img_bd1, NOTSRCERASE);  // 遮罩透明处理
	putimage(bird_x, bird_y, &img_bd2, SRCINVERT);// 显示小鸟	

	//显示 障碍物
	putimage(bar1_x, bar1_xTop, &img_bar_up1, NOTSRCERASE);  // 遮罩透明处理
	putimage(bar1_x, bar1_xTop, &img_bar_up2, SRCINVERT);// 显示上障碍物
	putimage(bar1_x, bar1_xDown, &img_bar_down1, NOTSRCERASE);  // 遮罩透明处理
	putimage(bar1_x, bar1_xDown, &img_bar_down2, SRCINVERT);// 显示下障碍物

	FlushBatchDraw();
	Sleep(50);
}

void updateWithoutInput()
{
	// 输入空格进行控制小鸟
	char input;
	if (_kbhit())
	{
		input = _getch();
		if (input == ' ' && bird_y > 20)
		{
			bird_y -= 25;
			mciSendString(_T("close jpmusic"), NULL, 0, NULL);  // 先把前面一次的音乐关闭
			mciSendString(_T("open D:\\Jump.mp3 alias jpmusic"), NULL, 0, NULL);// 打开跳动音乐
			mciSendString(_T("play jpmusic"), NULL, 0, NULL);   // 仅播放一次
		}
	}
}

// 图形更新
void updateWithInput()
{
	// 小鸟不能飞出界面
	if (bird_y < 0 || bird_y > 556)
		_exit(0); // 结束

	// 小鸟的坐标不能出框 , Y轴不能小于0 , 不能大于580
	if (0 < bird_y && bird_y < 580)
		bird_y += 3;

	// 障碍物的移动
	if (bar1_x > -140)
		bar1_x -= 2; 
	else 
	{
		// 重新生成
		bar1_x = width;
		//障碍物
		int randPosition = rand() % (high - 400) + 50;  // 随机数就只在 50-250
														//注意这是上障碍物的起始坐标
		bar1_xTop = randPosition - high; // top 的范围就在 -550 ------  -350 之间   
										 // 上障碍物画完 , 画下障碍物 , 间隔100
		bar1_xDown = bar1_xTop + high + 100;
	}

	//得分计算 小鸟的宽度为34 , 柱子宽度为140
	if ( (bar1_x < bird_x + 34) && (bar1_x +140 > bird_x + 34) )  
	{
		if ((bird_y > bar1_xTop +600) && (bird_y < bar1_xDown))
		{
			score++;
		}
		else
		{
			_exit(0);
		}
	}
}

void gameover()
{

	EndBatchDraw();
	_getch();
	closegraph();
}

int main()
{
	startup();  // 数据初始化	
	while (1)  //  游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 界面的更新
		updateWithInput();     // 与用户输入有关的更新
	}
	gameover();     // 游戏结束、后续处理
	return 0;
}

好了 , 到此结束 . 大家记得每天提醒自己 , 好好学习 , 天天向上

  • 13
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

逼哥很疯狂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值