C语言小游戏:飞翔的小鸟(完整版)

每天一个c语言小项目,提升你的编程能力! 
《flappy bird》是曾经一款流行的一款手机游戏,你只要让小鸟保持飞行,不要碰到绿色的管道就可以啦。操作虽然简单,但是非常具有挑战!本次我们也是自己动手来实现这样一款游戏的高仿版,大家不妨自己先读一遍代码然后动手试试!
该程序是用 c 语言实现的 flappybird 的电脑版,玩法和手机版的相同。
程序通过 alpha 域实现透明贴图,并且通过双缓冲绘图防止刷新闪屏。
程序执行效果如下:
本程序设计了三种不同颜色的小鸟(可以实现三人对战)另外也有白天模式和夜晚模式,不同模式和不同小鸟是在上次死亡后随机刷新,避免产生视觉疲劳。
简单了解游戏后我们就来试试吧!
本项目编译环境:visual studio 2019/2022,easyx插件
必备素材:
网盘链接:https://pan.baidu.com/s/10alp-qdctu0uv4p8alte4w?pwd=3p3s   提取码:3p3s 
代码展示:(有五百多行代码,每一个功能实现都会给出对应注释)
#include #include #include #include #include #include // 初始背景图 白天、黑夜image bk[2];// 全局画板image bk;// 飞鸟资源 橘、蓝、红image bird[3][3];// 管道资源 绿、红image pipe[2][2];// 三种数字字体image number[3][10];// 奖牌资源image medal[4];// 地面资源image land;// 开始游戏按钮image play;// 得分面板image panel;// 以下为五种游戏文字// 游戏结束 游戏预备 游戏标题 游戏提示 最高分image over;image ready;image title;image tutorial;image new;// 结束时状态image oveimg;// 是否为白天int isday = 0;// 鸟的颜色int birdcolor = 0;// 最高分int best = 0;// 游戏初始时间long starttime = 0;// 游戏基本属性// 重力加速度const double g = 6.5;// 管道的移动速度double vx = 11;// 鸟的下落速度double vy = 10;// 鸟的当前位置double y = 220;const double x = 288 / 2 - (41 + 8) / 2 - 80;// 管道的横向坐标double pipex[2];// 管道的纵向坐标int pipey[2];// 当前得分int score;// 鸟的矩形判断区域const int top = 12;const int left = 10;const int right = 37;const int buttom = 33;// 奖牌显示位置const int medalxy[2] = { 0, 0 };// 陆地坐标const double landy = 420;double landx = -20;// 飞鸟姿态int pose = 0;// 飞行间隔const int diff = 110;// 管道上补偿const int pipeup = -280;// 管道下补偿const int pipedown = 140;// 游戏预处理void start();// 游戏函数void game();// 结束游戏函数void end();// 移动函数void move(long time);// 绘制函数void draw();// 重置画布void reset();// 绘制画布void put();// 加载资源void loadres();// 根据透明度绘图void drawalpha(image* dstimg, int x, int y, image* srcimg);// 绘制分数void drawscore(int y, int sc, int dif, int se, int st, int type);// 绘制管道void drawpipe();// 判断鸟死亡bool isdie();// 初始化游戏资源void init();int main(){ // 游戏开局页面 init(); while (true) { // 游戏初始化 start(); // 游戏进行 game(); // 显示得分 end(); } return 0;}bool getcontrol() { bool res = false; if (_kbhit()) { char ch = _getch(); if (ch == ' ') { res = true; } } mousemsg msg; while (mousehit()) { msg = getmousemsg(); if (msg.mklbutton) { res = true; } } return res;}// 游戏预处理void start(){ // 初始化数据 isday = rand() % 2; birdcolor = rand() % 3; pipex[0] = 288 + 30; pipex[1] = 288 + 30 + 190; pipey[0] = rand() % 250; pipey[1] = rand() % 250; pose = 0; landx = 0; score = 0; y = 220; vy = 0; // 游戏初始时间 clock_t time = clock(); // 开场动画 clock_t t = clock(); while (true) { reset(); drawscore(60, score, 13, 26, 144, 0); drawalpha(&bk, 50, 120, &ready); drawalpha(&bk, (int)x, (int)y, &bird[birdcolor][pose]); drawalpha(&bk, 90, 220, &tutorial); drawalpha(&bk, (int)landx, (int)landy, &land); landx -= (clock() - t) * vx / 100; t = clock(); pose = ((clock() - time) / diff) % 3; put(); if (landx < -44) { landx = -20; } if (getcontrol()) { break; } sleep(10); }}// 游戏函数void game(){ // 根据毫秒 starttime = clock(); long time = clock(); while (!isdie()) { // 移动 move(clock() - time); time = clock(); // 控制 if (getcontrol()) { vy = -26; } // 绘制 draw(); sleep(10); } starttime = clock(); while (clock() - starttime < 1000); vy = -30; time = clock(); while (y 50) { if (r > 3) { r = 3; } drawalpha(&bk, 57, 195, &medal[r]); } // 打印当前分 drawscore(189, score, 16, 16, 240, 2); // 写最高分 int tmp = best; if (best < score) { best = score; } // 打印最高分 drawscore(231, best, 16, 16, 240, 2); // 如果当前分超过最高分 则显示新分数图标 if (tmp = 0; i--) { drawalpha(&bk, s, y, &number[type][num[i]]); s += se; }}// 管道、主角、地面移动void move(long time){ y += time * vy / 100; vy += g * time / 100; pipex[0] -= time * vx / 100; pipex[1] -= time * vx / 100; landx -= time * vx / 100; pose = ((clock() - starttime) / diff) % 3; if (landx < -44) { landx = -20; } if (pipex[0] < -52) { pipex[0] = pipex[1] + 190; pipey[0] = rand() % 250; } if (pipex[1] < -52) { pipex[1] = pipex[0] + 190; pipey[1] = rand() % 250; } if (y < 0 - top) { y = -top; } score = (int)(((clock() - starttime) * vx / 100 - (288 - x + 30)) / 190 + 1); if (score getwidth(); int src_height = srcimg->getheight(); int dst_width = dstimg->getwidth(); int dst_height = dstimg->getheight(); // 实现透明贴图 可优化 for (int iy = 0; iy < src_height; iy++) { for (int ix = 0; ix > 24); int sr = ((src[srcx] & 0xff0000) >> 16); int sg = ((src[srcx] & 0xff00) >> 8); int sb = src[srcx] & 0xff; if (x + ix >= 0 && x + ix = 0 && y + iy > 16); int dg = ((dst[dstx] & 0xff00) >> 8); int db = dst[dstx] & 0xff; dst[dstx] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16) | ((sg * sa / 255 + dg * (255 - sa) / 255) < landy) return true; if (x + right > pipex[0] && x + left < pipex[0] + 52) { if (y + top pipey[0] + 140) return true; } if (x + right > pipex[1] && x + left < pipex[1] + 52) { if (y + top pipey[1] + 140) return true; } return false;}void reset(){ drawalpha(&bk, 0, 0, &bk[isday]);}void put(){ putimage(0, 0, &bk);}// 初始化游戏资源void init(){ // 加载图形资源 loadres(); // 初始化图形界面 initgraph(288, 512); // 初始化随机数种子 srand((unsigned int)time(null)); // 初始化变量 best = 0; isday = rand() % 2; birdcolor = rand() % 3; // 游戏初始时间 clock_t time = clock(); // 开场动画 while (true) { reset(); drawalpha(&bk, 60, 120, &title); drawalpha(&bk, 125, 200, &bird[birdcolor][pose]); drawalpha(&bk, 90, 270, &play); pose = ((clock() - time) / diff) % 3; put(); if (getcontrol()) { break; } sleep(10); }}// 加载图片资源void loadres(){ loadimage(&bk[0], _t(res\bg_day.png)); loadimage(&bk[1], _t(res\bg_night.png)); loadimage(&bk, _t(res\bg_day.png)); loadimage(&oveimg, _t(res\bg_day.png)); loadimage(&bird[0][0], _t(res\bird0_0.png)); loadimage(&bird[0][1], _t(res\bird0_1.png)); loadimage(&bird[0][2], _t(res\bird0_2.png)); loadimage(&bird[1][0], _t(res\bird1_0.png)); loadimage(&bird[1][1], _t(res\bird1_1.png)); loadimage(&bird[1][2], _t(res\bird1_2.png)); loadimage(&bird[2][0], _t(res\bird2_0.png)); loadimage(&bird[2][1], _t(res\bird2_1.png)); loadimage(&bird[2][2], _t(res\bird2_2.png)); loadimage(&pipe[0][0], _t(res\pipe_down.png)); loadimage(&pipe[0][1], _t(res\pipe_up.png)); loadimage(&pipe[1][0], _t(res\pipe2_down.png)); loadimage(&pipe[1][1], _t(res\pipe2_up.png)); loadimage(&number[0][0], _t(res\font_048.png)); loadimage(&number[0][1], _t(res\font_049.png)); loadimage(&number[0][2], _t(res\font_050.png)); loadimage(&number[0][3], _t(res\font_051.png)); loadimage(&number[0][4], _t(res\font_052.png)); loadimage(&number[0][5], _t(res\font_053.png)); loadimage(&number[0][6], _t(res\font_054.png)); loadimage(&number[0][7], _t(res\font_055.png)); loadimage(&number[0][8], _t(res\font_056.png)); loadimage(&number[0][9], _t(res\font_057.png)); loadimage(&number[1][0], _t(res\number_context_00.png)); loadimage(&number[1][1], _t(res\number_context_01.png)); loadimage(&number[1][2], _t(res\number_context_02.png)); loadimage(&number[1][3], _t(res\number_context_03.png)); loadimage(&number[1][4], _t(res\number_context_04.png)); loadimage(&number[1][5], _t(res\number_context_05.png)); loadimage(&number[1][6], _t(res\number_context_06.png)); loadimage(&number[1][7], _t(res\number_context_07.png)); loadimage(&number[1][8], _t(res\number_context_08.png)); loadimage(&number[1][9], _t(res\number_context_09.png)); loadimage(&number[2][0], _t(res\number_score_00.png)); loadimage(&number[2][1], _t(res\number_score_01.png)); loadimage(&number[2][2], _t(res\number_score_02.png)); loadimage(&number[2][3], _t(res\number_score_03.png)); loadimage(&number[2][4], _t(res\number_score_04.png)); loadimage(&number[2][5], _t(res\number_score_05.png)); loadimage(&number[2][6], _t(res\number_score_06.png)); loadimage(&number[2][7], _t(res\number_score_07.png)); loadimage(&number[2][8], _t(res\number_score_08.png)); loadimage(&number[2][9], _t(res\number_score_09.png)); loadimage(&medal[0], _t(res\medals_3.png)); loadimage(&medal[1], _t(res\medals_2.png)); loadimage(&medal[2], _t(res\medals_1.png)); loadimage(&medal[3], _t(res\medals_0.png)); loadimage(&land, _t(res\land.png)); loadimage(&play, _t(res\button_play.png)); loadimage(&over, _t(res\text_game_over.png)); loadimage(&ready, _t(res\text_ready.png)); loadimage(&title, _t(res\title.png)); loadimage(&tutorial, _t(res\tutorial.png)); loadimage(&panel, _t(res\score_panel.png)); loadimage(&new, _t(res\new.png));} 大家赶紧去动手试试吧!


一手不能掌握,或许小米6将会出plus版,5.7英寸大屏幕,还有双摄
3D打印对智能硬件创业者意味着什么?
小米6什么时候上市?小米6最新消息:国内首发骁龙835,小米6预售偷跑,京东盲约3599元!
爱仕达以1.37亿元向钱江摩托收购钱江机器人39%股权
基于S3C4510B的串口网络服务器最小系统
C语言小游戏:飞翔的小鸟(完整版)
实现两只音箱的AV境界——虚拟环绕声技术 QS7779
一加手机占比90Hz手机线上销量超过77% 并即将官宣120Hz屏幕
智能化大棚温湿度控制系统可保证种苗的生长环境
谷歌Pixel 4a真机实拍照曝光 首次搭载挖孔全面屏且机身背面材质疑似为塑料
嵌入式编码规范解读
安捷伦E4407B频谱分析仪26.5GHz
Type-C拓展坞PDHUB取电IC方案
怎样在RTC DS1307在LCD上设置并显示时间
科思创上海PUD新工厂竣工
智能感知与物联网技术研究所优秀毕业生采访
华盛昌推出多功能智能激光测距仪
联想表明对中国经济的复苏动能以及全球数字经济的前景充满信心
电容为什么会发热,电容发热的原因是什么
市电电源监视电路原理图