我是靠谱客的博主 靓丽芒果,最近开发中收集的这篇文章主要介绍C语言小游戏(flappy bird),附带源码及素材前言一、系统简介及最终效果二、函数模块图及所需的一些材料素材下载三、具体代码(在代码中有具体的解释)四、一些图片处理原理五、完整源代码,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

课程设计—用C语言编码一个小游戏(flappy bird)

  • 前言
  • 一、系统简介及最终效果
  • 二、函数模块图及所需的一些材料素材下载
  • 三、具体代码(在代码中有具体的解释)
    • 1、头文件
    • 2、全局变量定义
    • 3、存读档函数
    • 4、关于/帮助菜单函数
    • 5、主菜单/暂停菜单/结束菜单函数
    • 6、初始化函数
    • 7、其他辅助函数
    • 8、主函数
  • 四、一些图片处理原理
  • 五、完整源代码

前言

这是我写的第一个程序,写一篇文章纪念一下,同时也给后续刚刚开始学习计算机的同学们一个参考。

注意:完成该程序需要用到easy-x库下<graphics.h>数据,建议用vc6或vs2013版本以上等支持安装easy-x库的软件

一、系统简介及最终效果


二、函数模块图及所需的一些材料素材下载


三、具体代码(在代码中有具体的解释)

我是在安装了easy-x库的VC6.0下运行的

1、头文件

// #include<bits/stdc++.h>
#include<stdio.h>
#include <conio.h>
#include <time.h>
#include <graphics.h>
#pragma comment(lib,"Winmm.lib")//导入音乐等多媒体
void main();//主函数
void startup();//初始化
void show();//画面显示
void updateWithInput();//与玩家输入有关的画面数据更新
void updateWithoutInput();//与玩家输入无关的画面数据更新
void gameOver();//结束处理
void startMenu();//开始菜单
oid pauseMenu();//暂停菜单
void overMenu();//结束菜单
void readHelpFile();//打开帮助页面
void readAboutFile();//打开关于页面
void readRecordFile();//读档
void writeRecordFile();//存档
#define High 600
//定义游戏界面的高度
#define Width 600
//定义游戏界面的宽度
#define Difficulty 10 //定义游戏难度(用Sleep函数控制快慢)

2、全局变量定义

//定义全局变量
IMAGE
huaji1,huaji2,img_bk,tiao1,tiao2,pause,help,about,shang1,shang2,xia1,xia2,over1,over2,over3,over4;//各种图片
int huaji_x,huaji_y;//滑稽的坐标
int bar_x,shang_y,xia_y;//障碍的坐标
int score;//得分
//定义游戏状态:若为0初始化后显示主菜单,若为1直接进入游戏
int gameStatus=0;

3、存读档函数

//读取游戏存档,实现“继续游戏”
void readRecordFile()
{
FILE *fp;
fp=fopen("F:\游戏记录.txt","r");
fscanf(fp,"%d %d %d %d %d %d",&huaji_x,&huaji_y,&bar_x,&shang_y,&xia_y,&score);//游戏核心数据读出
fclose(fp);
}
//游戏数据写入存档,保存游戏记录
void writeRecordFile()
{
FILE *fp;
fp=fopen("F:\游戏记录.txt","w+");
fprintf(fp,"%d %d %d %d %d %d",huaji_x,huaji_y,bar_x,shang_y,xia_y,score);//游戏核心数据写入
fclose(fp);
}

4、关于/帮助菜单函数

//主菜单里的“帮助”界面
void readHelpFile()
{
loadimage(&help,"F:\帮助.jpg");//打开帮助界面背景图片
putimage(0,0,&help);
FlushBatchDraw();
mciSendString("close bkmusic_1",NULL,0,NULL);//关闭主菜单背景音乐
mciSendString("open F:\帮助.mp3 alias help",NULL,0,NULL);//打开帮助界面背景音乐
mciSendString("play help repeat",NULL,0,NULL);//播放
FILE *fp;
char s[32];
fp=fopen("F:\帮助.txt","r");//读取“帮助”文档
int length=25;
//定义行间距
while(!feof(fp)) // 经过试验发现每行32个字符很适合
{
fgets(s,32,fp);
setbkmode(TRANSPARENT);//透明化文字背景
settextcolor(WHITE);
settextstyle(20,0,_T("楷体"));
outtextxy(25,length, s);//将字符串输出到界面对应坐标位置上
length+=25;
}
settextcolor(YELLOW);
settextstyle(35,0,_T("华文新魏"));
outtextxy(0,555,"温馨提示:点击屏幕任意位置回主菜单");//在底端输出温馨提示
Sleep(1000);
FlushBatchDraw();
fclose(fp);
MOUSEMSG m;//用鼠标控制退出帮助界面回到主菜单
while(1)
{
m=GetMouseMsg();
if(m.uMsg==WM_LBUTTONDOWN)
{
mciSendString("close help",NULL,0,NULL);//左击任意位置回主菜单
gameStatus=0;
main();
}
}
}
//主菜单里的“关于”界面
void readAboutFile()
{
loadimage(&about,"F:\关于.jpg");//打开关于界面背景图片
putimage(0,0,&about);
FlushBatchDraw();
mciSendString("close bkmusic_1",NULL,0,NULL);//关闭主菜单背景音乐
mciSendString("open F:\关于.mp3 alias about",NULL,0,NULL);//打开帮助界面背景音乐
mciSendString("play about repeat",NULL,0,NULL);//播放
FILE *fp;
char s[80];
fp=fopen("F:\关于.txt","r");
fgets(s,80,fp);
setbkmode(TRANSPARENT);//背景透明
settextcolor(BLACK);
settextstyle(50,0,_T("华文彩云"));
outtextxy(250,0,"关于");
settextstyle(30,0,_T("华文行楷"));//输出关于界面的相关内容(内容较少就不用文本了直接写入)
outtextxy(240,60,"关于的话");
outtextxy(250,95,"emmmmmm");
outtextxy(150,130,"这是个非常好玩的游戏");
outtextxy(250,165,"嗯 没错");
outtextxy(240,195,"就是这样");
settextcolor(RED);
settextstyle(35,0,_T("华文新魏"));
outtextxy(0,555,"温馨提示:点击屏幕任意位置回主菜单");
Sleep(1000);
FlushBatchDraw();
fclose(fp);
MOUSEMSG m;//用鼠标控制退出帮助界面回到主菜单
while(1)
{
m=GetMouseMsg();
if(m.uMsg==WM_LBUTTONDOWN)
{
mciSendString("close about",NULL,0,NULL);//左击任意位置回主菜单
gameStatus=0;
main();
}
}
}

5、主菜单/暂停菜单/结束菜单函数

//主菜单界面
void startMenu()
{
mciSendString("close bkmusic_2",NULL,0,NULL);//关闭背景音乐
loadimage(&pause,"F:\初始化界面.jpg");//打开初始化界面背景图片
putimage(0,0,&pause);
FlushBatchDraw();
setbkmode(TRANSPARENT);//背景透明
settextcolor(YELLOW);
settextstyle(50,0,_T("华文行楷"));//在对应位置输出菜单选项内容
outtextxy(175,150,"1 开始游戏");
outtextxy(175,250,"2 继续游戏");
outtextxy(50,350,"3 什么游戏,我要学习!");
settextcolor(WHITE);//这两个内容用不同字体
settextstyle(40,0,_T("华文彩云"));
outtextxy(50,500,"4 帮助");
outtextxy(425,500,"5 关于");
char input;//判断是否有键盘输入
if(kbhit())
{
input=getch();
if(input=='1')
gameStatus=1;//进入新游戏
else if(input=='2')
{
readRecordFile();//读取存档,继续游戏
gameStatus=1;
}
else if(input=='3')
{
gameStatus=1;//去学习,退出游戏
exit(0);
}
else if(input=='4')
{
while(1)//让内容长久显示
readHelpFile();//读取帮助界面内容
}
else if(input=='5')
{
while(1)//让内容长久显示
readAboutFile();//读取关于界面内容
}
}
}
//暂停菜单界面
void pauseMenu()
{
while(1)//让内容长久显示
{
loadimage(&pause,"F:\暂停时的图片.jpg");//打开暂停菜单的背景图片
putimage(0,0,&pause);
FlushBatchDraw();
char input;
if(kbhit())//判断是否有鼠标输入
{
input=getch();
if(input=='1')//开始新游戏
{
gameStatus=1;//不进入主菜单,直接开始新游戏
main();
}
else if(input=='2')//继续游戏
{
startup();//从头开始初始化后读取存档,继续游戏
readRecordFile();//读取存档
show();
Sleep(1400);//预备开始阶段延时
while(1)//游戏循环执行
{
show();//显示画面
updateWithoutInput();//与玩家输入无关的游戏界面更新
updateWithInput();//与玩家输入有光的游戏界面更新
}
}
else if(input=='3')//回主菜单
{
gameStatus=0;
startup();
putimage(0,0,&img_bk);
//打开预备开始阶段背景画面
FlushBatchDraw();
show();
Sleep(1400);//预备开始阶段延时
break;
}
else if(input=='4')//退出游戏
{
gameStatus=1;
exit(0);
}
}
}
}
void overMenu()
{
while(1) //让结束菜单长久显示
{
loadimage(&over4,"F:\结束时的背景图片.jpg");
putimage(0,0,&over4);
setbkmode(TRANSPARENT);//透明化文字背景
settextcolor(WHITE);
settextstyle(50,0,_T("华文行楷"));
outtextxy(Width-500,High-500,"1 不够爽!再来一局!");//输出菜单内容
outtextxy(Width-500,High-400,"2 我想回主菜单了");
outtextxy(Width-500,High-300,"3 我要去学习了!!!");
settextcolor(YELLOW);
settextstyle(50,0,_T("华文彩云"));
outtextxy(Width-425,High-200,"得分: ");
//显示得分
char s[10];
sprintf(s,"%d",score);
outtextxy(Width-275,High-200,s);
FlushBatchDraw();
char input;
//判断是否有键盘输入
if(kbhit())
{
input=getch();
if(input=='1')//开始新游戏
{
gameStatus=1;
main();
}
else if(input=='2')//回主菜单
{
gameStatus=0;//状态值为零,初始化后显示主菜单
startup();
putimage(0,0,&img_bk);
//打开背景画面
FlushBatchDraw();
show();
Sleep(1400);
break;
}
else if(input=='3')//去学习,退出游戏
exit(0);
}
}
}

6、初始化函数

//初始化
void startup()
{
score=0;
//初始化分数为0
initgraph(Width,High); //定义游戏界面大小
loadimage(&img_bk,"F:\背景图片.jpg");//打开一系列游戏界面的图片
loadimage(&huaji1,"F:\滑稽1.jpg");
loadimage(&huaji2,"F:\滑稽2.jpg");
loadimage(&shang1,"F:\上障碍1.jpg");
loadimage(&shang2,"F:\上障碍2.jpg");
loadimage(&xia1,"F:\下障碍1.jpg");
loadimage(&xia2,"F:\下障碍2.jpg");
mciSendString("open F:\背景音乐1.mp3 alias bkmusic_1",NULL,0,NULL);//打开背景音乐
mciSendString("play bkmusic_1 repeat",NULL,0,NULL);//播放
srand(time(NULL));
//利用系统时间产生伪随机种子,以为了得到随机位置的障碍
huaji_x = 24;
//初始化滑稽坐标
huaji_y = rand() % 150 + 250;
bar_x = 450;
//初始化障碍的坐标
shang_y = rand() % 400 - 550;
while(xia_y - shang_y>730 || xia_y - shang_y<670) //上下障碍随机出现的坐标范围
{
shang_y = rand()%400 - 550;
xia_y = rand()%300 + 150 ;
}
while(gameStatus==0)
//状态为0则进入主菜单
{
Sleep(200);
startMenu();//主菜单界面
FlushBatchDraw();
}
mciSendString("close bkmusic_1",NULL,0,NULL);//关闭主菜单背景音乐
mciSendString("open F:\背景音乐2.mp3 alias bkmusic_2",NULL,0,NULL);//打开游戏背景音乐
mciSendString("play bkmusic_2 repeat",NULL,0,NULL);//播放
mciSendString("close beginmusic",NULL,0,NULL);
mciSendString("open F:\开始.mp3 alias beginmusic ",NULL,0,NULL);//播放一次开始时的预备音效
mciSendString("play beginmusic",NULL,0,NULL);
}

7、其他辅助函数

//显示画面
void show()
{
Sleep(Difficulty);
//整体速度控制即难度
putimage(0,0,&img_bk);
//打开背景画面
//采用精灵图与掩码图叠加偶读方法实现抠图,让部分区域透明
putimage(huaji_x,huaji_y,&huaji1,NOTSRCERASE);
//透明化边界外的图片
putimage(huaji_x,huaji_y,&huaji2,SRCINVERT);
putimage(bar_x,shang_y,&shang1,NOTSRCERASE);//上障碍
putimage(bar_x,shang_y,&shang2,SRCINVERT);
putimage(bar_x,xia_y,&xia1,NOTSRCERASE);//下障碍
putimage(bar_x,xia_y,&xia2,SRCINVERT);
setbkmode(TRANSPARENT);//文字背景透明
settextcolor(RED);
settextstyle(50,0,_T("华文行楷"));
outtextxy(0,0,"得分:");
settextcolor(RED);
settextstyle(50,0,_T("Algerain"));//显示分数
char s[10];
sprintf(s,"%d",score);
outtextxy(125,0,s);
FlushBatchDraw();
}
//与输入有关的更新
void updateWithInput()
{
char input;
if (kbhit())//判断是否有键盘输入
{
input = getch();
if (input==' ')
{
loadimage(&tiao1,"F:\我跳1.jpg");
loadimage(&tiao2,"F:\我跳2.jpg");
putimage(huaji_x,huaji_y,&tiao1,NOTSRCERASE);//每跳一下滑稽的表情就变一次
putimage(huaji_x,huaji_y,&tiao2,SRCINVERT);
huaji_y-=30;//点一下空格滑稽就会上跳的高度
mciSendString("close jpmusic",NULL,0,NULL);
mciSendString("open F:\跳.mp3 alias jpmusic ",NULL,0,NULL);//按一下空格播放一次音效
mciSendString("play jpmusic",NULL,0,NULL);
}
else if(input==27)//27为esc 键的ascll码
{
writeRecordFile();//存档
mciSendString("close bkmusic_2",NULL,0,NULL);//关闭游戏时的背景音乐
pauseMenu();//打开暂停界面
}
}
}
//与玩家输入无关的游戏界面更新
void updateWithoutInput()
{
if (huaji_y<High)
//自动下落
huaji_y++;
if (bar_x>-140)
//障碍左移,140为整个障碍的宽度
bar_x--;
else
//障碍重新从右边出现
{
bar_x = Width;
shang_y = rand()%300 - 450;
while(xia_y - shang_y>730 || xia_y - shang_y<670)
{
shang_y =rand()%300 - 450;
xia_y = rand()%300 + 150 ;
}
}
if (((bar_x<50 && bar_x>-100) && (huaji_y+40>xia_y || huaji_y<shang_y+585)) || (huaji_y>550 || huaji_y<0 ))//判断失败
{
mciSendString("close bkmusic_2",NULL,0,NULL);//关闭背景音乐
mciSendString("close overmusic_1",NULL,0,NULL);
mciSendString("open F:\尖叫.mp3 alias overmusic_1 ",NULL,0,NULL);//播放触碰危险边缘的尖叫音效
mciSendString("play overmusic_1",NULL,0,NULL);
loadimage(&over1,"F:\我输了1.jpg");//还是用两图叠加的方法实现 失败时表情边缘的透明
loadimage(&over2,"F:\我输了2.jpg");
putimage(huaji_x,huaji_y,&over1,NOTSRCERASE);//输了后滑稽变为 失败时 的表情
putimage(huaji_x,huaji_y,&over2,SRCINVERT);
FlushBatchDraw();
Sleep(2000);//表情出现后停留一段时间
mciSendString("close overmusic_2",NULL,0,NULL);
mciSendString("open F:\失败.mp3 alias overmusic_2 ",NULL,0,NULL);//播放 失败后 的背景音乐
mciSendString("play overmusic_2",NULL,0,NULL);
loadimage(&over3,"F:\不要打扰我学习.jpg");//打开 失败后 的背景图片
putimage(0,0,&over3);
FlushBatchDraw();
Sleep(5000);//图片出现后停留一段时间
overMenu();
}
if
(bar_x==-90) //跳过障碍后加一分
{
score++;
mciSendString("close score",NULL,0,NULL);
mciSendString("open F:\加一.mp3 alias score",NULL,0,NULL);//打开加分时的音效
mciSendString("play score",NULL,0,NULL);
}
}
//游戏结束处理
void gameOver()
{
EndBatchDraw();//结束绘图
closegraph();//关闭图片
}

8、主函数

void main()
{
startup();
//数据初始化
show();
//显示画面(这一画面为准备阶段的画面)
Sleep(1400);
//游戏准备阶段的延时
while(1)//游戏循环执行
{
show();
//再次显示画面(游戏开始玩时的界面)
updateWithoutInput();//与玩家输入无关的游戏界面更新
updateWithInput();//与玩家输入有光的游戏界面更新
}
gameOver();//游戏结束处理
}

四、一些图片处理原理

图片处理主要就是抠图,把想要的步伐取出来,emmmm,那就以下面这个东西为例子吧。

loadimage(&tiao1,"F:\我跳1.jpg"); //导入图片
loadimage(&tiao2,"F:\我跳2.jpg");
putimage(huaji_x,huaji_y,&tiao1,NOTSRCERASE);
//这里输入一张黑白图
putimage(huaji_x,huaji_y,&tiao2,SRCINVERT);
// 这里输入原图

经过这几行代码的处理,在程序中就会把我们所需要的表情扣出来,不会有边缘的白边

五、完整源代码

#include<stdio.h>
#include <conio.h>
#include <time.h>
#include <graphics.h>
#pragma comment(lib,"Winmm.lib")//导入音乐等多媒体
void main();//主函数
void startup();//初始化
void show();//画面显示
void updateWithInput();//与玩家输入有关的画面数据更新
void updateWithoutInput();//与玩家输入无关的画面数据更新
void gameOver();//结束处理
void startMenu();//开始菜单
void pauseMenu();//暂停菜单
void overMenu();//结束菜单
void readHelpFile();//打开帮助页面
void readAboutFile();//打开关于页面
void readRecordFile();//读档
void writeRecordFile();//存档
#define High 600
//定义游戏界面的高度
#define Width 600
//定义游戏界面的宽度
#define Difficulty 10 //定义游戏难度(用Sleep函数控制快慢)
//定义全局变量
IMAGE
huaji1,huaji2,img_bk,tiao1,tiao2,pause,help,about,shang1,shang2,xia1,xia2,over1,over2,over3,over4;//各种图片
int huaji_x,huaji_y;//滑稽的坐标
int bar_x,shang_y,xia_y;//障碍的坐标
int score;//得分
//定义游戏状态:若为0初始化后显示主菜单,若为1直接进入游戏
int gameStatus=0;
//读取游戏存档,实现“继续游戏”
void readRecordFile()
{
FILE *fp;
fp=fopen("F:\游戏记录.txt","r");
fscanf(fp,"%d %d %d %d %d %d",&huaji_x,&huaji_y,&bar_x,&shang_y,&xia_y,&score);//游戏核心数据读出
fclose(fp);
}
//游戏数据写入存档,保存游戏记录
void writeRecordFile()
{
FILE *fp;
fp=fopen("F:\游戏记录.txt","w+");
fprintf(fp,"%d %d %d %d %d %d",huaji_x,huaji_y,bar_x,shang_y,xia_y,score);//游戏核心数据写入
fclose(fp);
}
//主菜单里的“帮助”界面
void readHelpFile()
{
loadimage(&help,"F:\帮助.jpg");//打开帮助界面背景图片
putimage(0,0,&help);
FlushBatchDraw();
mciSendString("close bkmusic_1",NULL,0,NULL);//关闭主菜单背景音乐
mciSendString("open F:\帮助.mp3 alias help",NULL,0,NULL);//打开帮助界面背景音乐
mciSendString("play help repeat",NULL,0,NULL);//播放
FILE *fp;
char s[32];
fp=fopen("F:\帮助.txt","r");//读取“帮助”文档
int length=25;
//定义行间距
while(!feof(fp)) // 经过试验发现每行32个字符很适合
{
fgets(s,32,fp);
setbkmode(TRANSPARENT);//透明化文字背景
settextcolor(WHITE);
settextstyle(20,0,_T("楷体"));
outtextxy(25,length, s);//将字符串输出到界面对应坐标位置上
length+=25;
}
settextcolor(YELLOW);
settextstyle(35,0,_T("华文新魏"));
outtextxy(0,555,"温馨提示:点击屏幕任意位置回主菜单");//在底端输出温馨提示
Sleep(1000);
FlushBatchDraw();
fclose(fp);
MOUSEMSG m;//用鼠标控制退出帮助界面回到主菜单
while(1)
{
m=GetMouseMsg();
if(m.uMsg==WM_LBUTTONDOWN)
{
mciSendString("close help",NULL,0,NULL);//左击任意位置回主菜单
gameStatus=0;
main();
}
}
}
//主菜单里的“关于”界面
void readAboutFile()
{
loadimage(&about,"F:\关于.jpg");//打开关于界面背景图片
putimage(0,0,&about);
FlushBatchDraw();
mciSendString("close bkmusic_1",NULL,0,NULL);//关闭主菜单背景音乐
mciSendString("open F:\关于.mp3 alias about",NULL,0,NULL);//打开帮助界面背景音乐
mciSendString("play about repeat",NULL,0,NULL);//播放
FILE *fp;
char s[80];
fp=fopen("F:\关于.txt","r");
fgets(s,80,fp);
setbkmode(TRANSPARENT);//背景透明
settextcolor(BLACK);
settextstyle(50,0,_T("华文彩云"));
outtextxy(250,0,"关于");
settextstyle(30,0,_T("华文行楷"));//输出关于界面的相关内容(内容较少就不用文本了直接写入)
outtextxy(240,60,"关于的话");
outtextxy(250,95,"emmmmmm");
outtextxy(150,130,"这是个非常好玩的游戏");
outtextxy(250,165,"嗯 没错");
outtextxy(240,195,"就是这样");
settextcolor(RED);
settextstyle(35,0,_T("华文新魏"));
outtextxy(0,555,"温馨提示:点击屏幕任意位置回主菜单");
Sleep(1000);
FlushBatchDraw();
fclose(fp);
MOUSEMSG m;//用鼠标控制退出帮助界面回到主菜单
while(1)
{
m=GetMouseMsg();
if(m.uMsg==WM_LBUTTONDOWN)
{
mciSendString("close about",NULL,0,NULL);//左击任意位置回主菜单
gameStatus=0;
main();
}
}
}
//主菜单界面
void startMenu()
{
mciSendString("close bkmusic_2",NULL,0,NULL);//关闭背景音乐
loadimage(&pause,"F:\初始化界面.jpg");//打开初始化界面背景图片
putimage(0,0,&pause);
FlushBatchDraw();
setbkmode(TRANSPARENT);//背景透明
settextcolor(YELLOW);
settextstyle(50,0,_T("华文行楷"));//在对应位置输出菜单选项内容
outtextxy(175,150,"1 开始游戏");
outtextxy(175,250,"2 继续游戏");
outtextxy(50,350,"3 什么游戏,我要学习!");
settextcolor(WHITE);//这两个内容用不同字体
settextstyle(40,0,_T("华文彩云"));
outtextxy(50,500,"4 帮助");
outtextxy(425,500,"5 关于");
char input;//判断是否有键盘输入
if(kbhit())
{
input=getch();
if(input=='1')
gameStatus=1;//进入新游戏
else if(input=='2')
{
readRecordFile();//读取存档,继续游戏
gameStatus=1;
}
else if(input=='3')
{
gameStatus=1;//去学习,退出游戏
exit(0);
}
else if(input=='4')
{
while(1)//让内容长久显示
readHelpFile();//读取帮助界面内容
}
else if(input=='5')
{
while(1)//让内容长久显示
readAboutFile();//读取关于界面内容
}
}
}
//暂停菜单界面
void pauseMenu()
{
while(1)//让内容长久显示
{
loadimage(&pause,"F:\暂停时的图片.jpg");//打开暂停菜单的背景图片
putimage(0,0,&pause);
FlushBatchDraw();
char input;
if(kbhit())//判断是否有鼠标输入
{
input=getch();
if(input=='1')//开始新游戏
{
gameStatus=1;//不进入主菜单,直接开始新游戏
main();
}
else if(input=='2')//继续游戏
{
startup();//从头开始初始化后读取存档,继续游戏
readRecordFile();//读取存档
show();
Sleep(1400);//预备开始阶段延时
while(1)//游戏循环执行
{
show();//显示画面
updateWithoutInput();//与玩家输入无关的游戏界面更新
updateWithInput();//与玩家输入有光的游戏界面更新
}
}
else if(input=='3')//回主菜单
{
gameStatus=0;
startup();
putimage(0,0,&img_bk);
//打开预备开始阶段背景画面
FlushBatchDraw();
show();
Sleep(1400);//预备开始阶段延时
break;
}
else if(input=='4')//退出游戏
{
gameStatus=1;
exit(0);
}
}
}
}
void overMenu()
{
while(1) //让结束菜单长久显示
{
loadimage(&over4,"F:\结束时的背景图片.jpg");
putimage(0,0,&over4);
setbkmode(TRANSPARENT);//透明化文字背景
settextcolor(WHITE);
settextstyle(50,0,_T("华文行楷"));
outtextxy(Width-500,High-500,"1 不够爽!再来一局!");//输出菜单内容
outtextxy(Width-500,High-400,"2 我想回主菜单了");
outtextxy(Width-500,High-300,"3 我要去学习了!!!");
settextcolor(YELLOW);
settextstyle(50,0,_T("华文彩云"));
outtextxy(Width-425,High-200,"得分: ");
//显示得分
char s[10];
sprintf(s,"%d",score);
outtextxy(Width-275,High-200,s);
FlushBatchDraw();
char input;
//判断是否有键盘输入
if(kbhit())
{
input=getch();
if(input=='1')//开始新游戏
{
gameStatus=1;
main();
}
else if(input=='2')//回主菜单
{
gameStatus=0;//状态值为零,初始化后显示主菜单
startup();
putimage(0,0,&img_bk);
//打开背景画面
FlushBatchDraw();
show();
Sleep(1400);
break;
}
else if(input=='3')//去学习,退出游戏
exit(0);
}
}
}
//初始化
void startup()
{
score=0;
//初始化分数为0
initgraph(Width,High); //定义游戏界面大小
loadimage(&img_bk,"F:\背景图片.jpg");//打开一系列游戏界面的图片
loadimage(&huaji1,"F:\滑稽1.jpg");
loadimage(&huaji2,"F:\滑稽2.jpg");
loadimage(&shang1,"F:\上障碍1.jpg");
loadimage(&shang2,"F:\上障碍2.jpg");
loadimage(&xia1,"F:\下障碍1.jpg");
loadimage(&xia2,"F:\下障碍2.jpg");
mciSendString("open F:\背景音乐1.mp3 alias bkmusic_1",NULL,0,NULL);//打开背景音乐
mciSendString("play bkmusic_1 repeat",NULL,0,NULL);//播放
srand(time(NULL));
//利用系统时间产生伪随机种子,以为了得到随机位置的障碍
huaji_x = 24;
//初始化滑稽坐标
huaji_y = rand() % 150 + 250;
bar_x = 450;
//初始化障碍的坐标
shang_y = rand() % 400 - 550;
while(xia_y - shang_y>730 || xia_y - shang_y<670) //上下障碍随机出现的坐标范围
{
shang_y = rand()%400 - 550;
xia_y = rand()%300 + 150 ;
}
while(gameStatus==0)
//状态为0则进入主菜单
{
Sleep(200);
startMenu();//主菜单界面
FlushBatchDraw();
}
mciSendString("close bkmusic_1",NULL,0,NULL);//关闭主菜单背景音乐
mciSendString("open F:\背景音乐2.mp3 alias bkmusic_2",NULL,0,NULL);//打开游戏背景音乐
mciSendString("play bkmusic_2 repeat",NULL,0,NULL);//播放
mciSendString("close beginmusic",NULL,0,NULL);
mciSendString("open F:\开始.mp3 alias beginmusic ",NULL,0,NULL);//播放一次开始时的预备音效
mciSendString("play beginmusic",NULL,0,NULL);
}
//显示画面
void show()
{
Sleep(Difficulty);
//整体速度控制即难度
putimage(0,0,&img_bk);
//打开背景画面
//采用精灵图与掩码图叠加偶读方法实现抠图,让部分区域透明
putimage(huaji_x,huaji_y,&huaji1,NOTSRCERASE);
//透明化边界外的图片
putimage(huaji_x,huaji_y,&huaji2,SRCINVERT);
putimage(bar_x,shang_y,&shang1,NOTSRCERASE);//上障碍
putimage(bar_x,shang_y,&shang2,SRCINVERT);
putimage(bar_x,xia_y,&xia1,NOTSRCERASE);//下障碍
putimage(bar_x,xia_y,&xia2,SRCINVERT);
setbkmode(TRANSPARENT);//文字背景透明
settextcolor(RED);
settextstyle(50,0,_T("华文行楷"));
outtextxy(0,0,"得分:");
settextcolor(RED);
settextstyle(50,0,_T("Algerain"));//显示分数
char s[10];
sprintf(s,"%d",score);
outtextxy(125,0,s);
FlushBatchDraw();
}
//与输入有关的更新
void updateWithInput()
{
char input;
if (kbhit())//判断是否有键盘输入
{
input = getch();
if (input==' ')
{
loadimage(&tiao1,"F:\我跳1.jpg");
loadimage(&tiao2,"F:\我跳2.jpg");
putimage(huaji_x,huaji_y,&tiao1,NOTSRCERASE);//每跳一下滑稽的表情就变一次
putimage(huaji_x,huaji_y,&tiao2,SRCINVERT);
huaji_y-=30;//点一下空格滑稽就会上跳的高度
mciSendString("close jpmusic",NULL,0,NULL);
mciSendString("open F:\跳.mp3 alias jpmusic ",NULL,0,NULL);//按一下空格播放一次音效
mciSendString("play jpmusic",NULL,0,NULL);
}
else if(input==27)//27为esc 键的ascll码
{
writeRecordFile();//存档
mciSendString("close bkmusic_2",NULL,0,NULL);//关闭游戏时的背景音乐
pauseMenu();//打开暂停界面
}
}
}
//与玩家输入无关的游戏界面更新
void updateWithoutInput()
{
if (huaji_y<High)
//自动下落
huaji_y++;
if (bar_x>-140)
//障碍左移,140为整个障碍的宽度
bar_x--;
else
//障碍重新从右边出现
{
bar_x = Width;
shang_y = rand()%300 - 450;
while(xia_y - shang_y>730 || xia_y - shang_y<670)
{
shang_y =rand()%300 - 450;
xia_y = rand()%300 + 150 ;
}
}
if (((bar_x<50 && bar_x>-100) && (huaji_y+40>xia_y || huaji_y<shang_y+585)) || (huaji_y>550 || huaji_y<0 ))//判断失败
{
mciSendString("close bkmusic_2",NULL,0,NULL);//关闭背景音乐
mciSendString("close overmusic_1",NULL,0,NULL);
mciSendString("open F:\尖叫.mp3 alias overmusic_1 ",NULL,0,NULL);//播放触碰危险边缘的尖叫音效
mciSendString("play overmusic_1",NULL,0,NULL);
loadimage(&over1,"F:\我输了1.jpg");//还是用两图叠加的方法实现 失败时表情边缘的透明
loadimage(&over2,"F:\我输了2.jpg");
putimage(huaji_x,huaji_y,&over1,NOTSRCERASE);//输了后滑稽变为 失败时 的表情
putimage(huaji_x,huaji_y,&over2,SRCINVERT);
FlushBatchDraw();
Sleep(2000);//表情出现后停留一段时间
mciSendString("close overmusic_2",NULL,0,NULL);
mciSendString("open F:\失败.mp3 alias overmusic_2 ",NULL,0,NULL);//播放 失败后 的背景音乐
mciSendString("play overmusic_2",NULL,0,NULL);
loadimage(&over3,"F:\不要打扰我学习.jpg");//打开 失败后 的背景图片
putimage(0,0,&over3);
FlushBatchDraw();
Sleep(5000);//图片出现后停留一段时间
overMenu();
}
if
(bar_x==-90) //跳过障碍后加一分
{
score++;
mciSendString("close score",NULL,0,NULL);
mciSendString("open F:\加一.mp3 alias score",NULL,0,NULL);//打开加分时的音效
mciSendString("play score",NULL,0,NULL);
}
}
//游戏结束处理
void gameOver()
{
EndBatchDraw();//结束绘图
closegraph();//关闭图片
}
void main()
{
startup();
//数据初始化
show();
//显示画面(这一画面为准备阶段的画面)
Sleep(1400);
//游戏准备阶段的延时
while(1)//游戏循环执行
{
show();
//再次显示画面(游戏开始玩时的界面)
updateWithoutInput();//与玩家输入无关的游戏界面更新
updateWithInput();//与玩家输入有光的游戏界面更新
}
gameOver();//游戏结束处理
}

最后

以上就是靓丽芒果为你收集整理的C语言小游戏(flappy bird),附带源码及素材前言一、系统简介及最终效果二、函数模块图及所需的一些材料素材下载三、具体代码(在代码中有具体的解释)四、一些图片处理原理五、完整源代码的全部内容,希望文章能够帮你解决C语言小游戏(flappy bird),附带源码及素材前言一、系统简介及最终效果二、函数模块图及所需的一些材料素材下载三、具体代码(在代码中有具体的解释)四、一些图片处理原理五、完整源代码所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部