C语言实现flappy bird(可视化编程)

C语言实现flappy bird(可视化编程)C语言实现flappybird(可视化编程)前言flappybird是一款在2014年爆火的游戏,相信大家都曾听说过或者玩过,今天我们将会采用C语言来写这个游戏的基本玩法,最重要的是从中接触可视化编程。代码效果可视化编程需要一个头文件,需要自己下载,即easyx。贴图技术#include<graphics.h>我选择的开发工具是vs2019,去掉了安全检查以及将字符集换成了多字符集。这个游戏主要运用到了一些贴图技术和利用多线程播放音乐的方法。我们首先需要构建一个

前言

flappy bird是一款在2014年爆火的游戏,相信大家都曾听说过或者玩过,今天我们将会采用C语言来写这个游戏的基本玩法,最重要的是从中接触可视化编程。

代码效果

C语言实现flappy bird(可视化编程)

可视化编程需要图形库,需要自己下载(点击前往下载安装教程),这里我们选择easyx,这个图形库对新手比较友好。
在这里插入图片描述

贴图技术

我选择的开发工具是vs2019,去掉了安全检查以及将字符集换成了多字符集(点击前往教程)
这个游戏主要运用到了一些贴图技术和利用多线程播放音乐的方法。
我们首先需要构建一个窗口并且将我们的背景图片贴上去。

#include <graphics.h>
IMAGE bg[2];// 定义图形变量数组
initgraph(288, 624);// 构建一个宽288,高624的窗口
loadimage(&bj[0], "图片路径");// 将图片赋给图形变量,就相当于给图片起一个名字
loadimage(&bj[1], "图片路径");
putimage(0, 0, &bg[0]);// 在0,0的位置贴上图片
putimage(0, 512, &bg[1]);

因为我使用的素材是天空与地面分开的背景图,所以这里贴了2次。

柱子与鸟

接着便是贴小鸟和柱子的图片了,但是与贴背景图不同的是这里的小鸟和柱子并不是一个规则的图形,所以我们采用透明贴图技术将小鸟和柱子贴上去。具体方法可以参考下面这篇文章。
https://blog.csdn.net/qq969422014/article/details/44536375
因为柱子的高度是随机而且成对出现的,我们需要一个随机数去模拟上面柱子及下面柱子的高度,我们使用结构体的方法去写柱子。

//下面的x,y都指其所在窗口的位置
//定义小鸟的结构体
struct huoyin
{ 
   
	int x;
	int y;
	int speed;//小鸟弹跳的距离
};
struct huoyin hero = { 
    100 , 240 , 70 };
//三对柱子的结构体
struct walls
{ 
   
	int x, y;
	int height;//上面柱子的高
};
struct walls pillar[3];
void pillars(struct walls pillar[],int i)
{ 
   
	pillar[i].height = rand() % 100 + 120;
	pillar[i].x = 288;
	pillar[i].y = 0;
}
//贴柱子
void drawWall(struct walls nowpillar)
{ 
   
	//上面柱子
	putimage(nowpillar.x, 0, 52, nowpillar.height, wall, 0, 320 - nowpillar.height, SRCAND);
	putimage(nowpillar.x, 0, 52, nowpillar.height, wall + 1, 0, 320 - nowpillar.height, SRCPAINT);
	//下面柱子
	putimage(nowpillar.x, 512 - (320 - nowpillar.height), 52, 320 - nowpillar.height, wall + 2, 0, 0, SRCAND);
	putimage(nowpillar.x, 512 - (320 - nowpillar.height), 52, 320 - nowpillar.height, wall + 3, 0, 0, SRCPAINT);
}
//以时间为种子构建随机函数
#include <time.h>//需要的头文件
srand(time(NULL));
//移动柱子
for (int i = 0; i < 3; i++)
{ 
   
	pillar[i].x -= 10;
}
//柱子的初始化
for (int i = 0; i < 3; i++)
{ 
   
	pillars(pillar, i);
	//每对柱子等距离
	pillar[i].x = 288 + i * 150;
}
//不断创造新的柱子
for (int i = 0; i < 3; i++)
{ 
   
	drawWall(pillar[i]);
	if (pillar[i].x <= -158)
	{ 
   
		pillars(pillar, i);
	}
}

介绍一下在贴柱子使用的 putimage(x,y,width,height,&IMAGE,xx,yy)函数,这个函数是从图片(&IMAGE)的 x,y 坐标截取 width 宽与 height 高贴在窗口的 xx,yy 坐标上。

多线程播放音乐

为了不让播放音乐影响画面,我们采用多线程播放音乐。

#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
//播放音乐
DWORD WINAPI playMusic(LPVOID lpvoid)
{ 
   
	mciSendString("open 卡通弹跳.wav alias music", 0, 0, 0);
	mciSendString("play music wait", 0, 0, 0);
	mciSendString("close music", 0, 0, 0);
	return 0;
}

小鸟的弹跳

接着就要实现使用空格让小鸟弹跳了。

//按键响应
void keyDown()
{ 
   
	char keys = _getch();
	
	switch(keys)
	{ 
   
	case ' ':
		hero.y -= hero.speed;
		CreateThread(NULL, NULL, playMusic, NULL, NULL, NULL);
		break;
	default:
		break;
	}
}

判断游戏是否结束

//判断游戏是否结束
int overs()
{ 
   
	if (hero.y < 0 || hero.y > 440 )
		return 1;
	for (int i = 0; i < 3; i++)
	{ 
   
		if (hero.x > pillar[i].x  && hero.x < pillar[i].x + 52 - 12)  
		{ 
   
			if(hero.y < pillar[i].height || hero.y > pillar[i].height + 112 + 38)
			return 1;
		}
		else return 0;
	}
}

判断游戏结束方面还存在一些问题,如有高见可以留言指出来,感谢!

游戏结束动画

//游戏结束动画
void overMovies()
{ 
   
	int x = 42, y = 700;
	while (y >= 200)
	{ 
   
		putimage(0, 0, &bg[0]);
		putimage(0, 512, &bg[1]);
		putimage(x, y, &end[0], SRCAND);
		putimage(x, y, &end[1], SRCPAINT);
		y -= 30;
		Sleep(100);//防止出现掩码图与彩图交替出现
	}
}

完整代码

#include <stdio.h>
#include <conio.h>
#include <graphics.h>
#include <time.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
//背景图\小鸟图\游戏结束图\柱子图
IMAGE bg[2],bird[2][3],end[2],wall[4];
//定义小鸟的结构体
struct huoyin
{ 
   
	int x;
	int y;
	int speed;
};
struct huoyin hero = { 
    100 , 240 , 70 };
//三对柱子的结构体
struct walls
{ 
   
	int x, y;
	int height;
};
struct walls pillar[3];
void pillars(struct walls pillar[],int i)
{ 
   
	pillar[i].height = rand() % 100 + 120;
	pillar[i].x = 288;
	pillar[i].y = 0;
}
//批量加载资源(给文件夹里的图片命名)
void jiazai()
{ 
   

	loadimage(&bg[0], "4.jpg");
	loadimage(&bg[1], "5.jpg");
	loadimage(&bird[0][0], "bird0_0.png");
	loadimage(&bird[1][0], "bird1_0.png");
	loadimage(&bird[0][1], "bird0_1.png");
	loadimage(&bird[1][1], "bird1_1.png");
	loadimage(&bird[0][2], "bird0_2.png");
	loadimage(&bird[1][2], "bird1_2.png");
	loadimage(&end[0], "11.jpg");
	loadimage(&end[1], "8.jpg");
	loadimage(&wall[0], "9.jpg");
	loadimage(&wall[1], "6.jpg");
	loadimage(&wall[2], "10.jpg");
	loadimage(&wall[3], "7.jpg");
}
//透明贴图(掩码图加原图)
/* void drawHero() { putimage(hero.x, hero.y, &bird[0][1], SRCAND); putimage(hero.x, hero.y, &bird[1][1], SRCPAINT); }*/
//贴柱子***** 
void drawWall(struct walls nowpillar)
{ 
   
	//上面柱子
	putimage(nowpillar.x, 0, 52, nowpillar.height, wall, 0, 320 - nowpillar.height, SRCAND);
	putimage(nowpillar.x, 0, 52, nowpillar.height, wall + 1, 0, 320 - nowpillar.height, SRCPAINT);
	//下面柱子
	putimage(nowpillar.x, 512 - (320 - nowpillar.height), 52, 320 - nowpillar.height, wall + 2, 0, 0, SRCAND);
	putimage(nowpillar.x, 512 - (320 - nowpillar.height), 52, 320 - nowpillar.height, wall + 3, 0, 0, SRCPAINT);
}
//播放音乐
DWORD WINAPI playMusic(LPVOID lpvoid)
{ 
   
	mciSendString("open 卡通弹跳.wav alias music", 0, 0, 0);
	mciSendString("play music wait", 0, 0, 0);
	mciSendString("close music", 0, 0, 0);
	return 0;
}
//按键响应
void keyDown()
{ 
   
	char keys = _getch();
	
	switch(keys)
	{ 
   
	case ' ':
		hero.y -= hero.speed;
		CreateThread(NULL, NULL, playMusic, NULL, NULL, NULL);
		break;
	default:
		break;
	}
}
//判断游戏是否结束
int overs()
{ 
   
	if (hero.y < 0 || hero.y > 440 )
		return 1;
	for (int i = 0; i < 3; i++)
	{ 
   
		if (hero.x > pillar[i].x  && hero.x < pillar[i].x + 52 - 12)  
		{ 
   
			if(hero.y < pillar[i].height || hero.y > pillar[i].height + 112 + 38)
			return 1;
		}
		else return 0;
	}
}
//游戏结束动画
void overMovies()
{ 
   
	int x = 42, y = 700;
	while (y >= 200)
	{ 
   
		putimage(0, 0, &bg[0]);
		putimage(0, 512, &bg[1]);
		putimage(x, y, &end[0], SRCAND);
		putimage(x, y, &end[1], SRCPAINT);
		y -= 30;
		Sleep(100);
	}
}


int main()
{ 
   
	srand(time(NULL));
	jiazai();
	//柱子的初始化
	for (int i = 0; i < 3; i++)
	{ 
   
		pillars(pillar, i);
		//每对柱子等距离
		pillar[i].x = 288 + i * 150;
	}
	initgraph(288, 624);
	for (int num = 0; num < 3; num++)
	{ 
   
		putimage(0, 0, &bg[0]);
		putimage(0, 512, &bg[1]);
		putimage(hero.x, hero.y, &bird[1][num], SRCAND);
		putimage(hero.x, hero.y, &bird[0][num], SRCPAINT);
		//移动柱子
		for (int i = 0; i < 3; i++)
		{ 
   
			pillar[i].x -= 10;
		}
		if (overs())
			break;
		//不断创造新的柱子
		for (int i = 0; i < 3; i++)
		{ 
   
			drawWall(pillar[i]);
			if (pillar[i].x <= -158)
			{ 
   
				pillars(pillar, i);
			}
		}
		if (overs())
			break;
		hero.y += 20;
		if (overs())
			break;
		if (_kbhit())
		{ 
   
			keyDown();
			if (overs())
				break;
		}
		if (num == 2)num = 0;
		Sleep(100);
	}
	Sleep(240);
	overMovies();
	_getch();
	closegraph();
	system("pause");
	return 0;
}

因为我还给小鸟做了扇动翅膀的动画,所以这个for (int num = 0; num < 3; num++)循环是加载鸟的三张图片。

用到的素材

由于有小伙伴找反映不到对应的素材,所以我将素材也放在网盘上分享了

链接:https://pan.baidu.com/s/1ovDvFtqIKIhoCfn0Z11PkA
提取码:1234

游戏素材网站

  1. The Spriters Resource
    地址:https://www.spriters-resource.com
    https://www.sounds-resource.com
    介绍:非常丰富齐全的游戏素材网站,并且按照游戏主机分类,包括 NES、PS、GBA 等各大游戏平台的游戏,素材基本都是抠好图的 PNG 格式,非常好用。想做高仿游戏的同学不要错过。

    还有 3D 模型、贴图、音效等素材。就是国外网站,访问速度有点慢。

  2. Open Game Art
    地址:https://opengameart.org

    介绍:很全很好用的游戏资源网站,就是国外网站的访问速度有点慢。

  3. 爱给网
    地址:http://www.aigei.com

    介绍:国内的游戏素材网站,也很好用齐全。不过有个不足:不登录不让下载。

总结

这是第一次在CSDN上写文章,如有不妥之处还请多多包涵。

今天的文章C语言实现flappy bird(可视化编程)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/9255.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注