在此记录下本人在大一暑假,2014.6~8这段时间复习C语言,随手编的一个模仿之前很火热的小游戏----flappy bird。代码bug基本被我找光了,如果有哪位兄弟找到其他的就帮我留言下吧,谢谢了!

代码的完美度肯定是不够的,随手编的嘛,找完bug后就没再去想怎样优化它了,毕竟时间有限。


先说下它的设计思路吧,算法方面,基本是纯靠for if 语句加上纯粹的坐标x,y运算实现的,在下面的代码里,将会看到很多阿拉伯数字的加加减减。没有用到链表什么的,当然,我相信,如果用到链表的话,会更简单,代码量更少。引用到的函数库有四个:

 #include<stdio.h>
#include<Windows.h>//win
#include <time.h>
#include<stdlib.h>

宏定义 :define一些标识图形,p为烟囱的组成单位方块,“ “为消除方块时用到的输出空白,-是界面美化,”鸟“是游戏体

 #define P printf("■")
#define PR printf(" ")
#define Q printf("-")
#define Br printf("鸟")

定义结构体,就一个鸟的结构体,以及一条最重要的函数----句柄的初始化。

 typedef    struct brid
{
double x,y;
int score;//分数
};
/*typedef struct Fangkuai
{
double x,y;
};*/ //此结构体废除
void Position(double x, double y) {//光标(坐标)函数
COORD pos = {
x - , y -
};
HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);//创建句柄
SetConsoleCursorPosition(Out, pos);//将句柄指向坐标,变为坐标句柄
}

下面是一些辅助函数,加上注释,这里再作介绍。由于函数名字基本是中文字的评语,这个之所以这样做,还是上面的原因,想改,可以自己改。

   jiemian(),这个函数的作用的在特定的位置输出”--------“,美化界面用的,置于为什么for循环里面我设置的i<103呢,是因为控制台的宽度大概是103像素,所以,
设置每一像素输出一个Q 即 - ,Position函数就是把特定此时的坐标; jiemian1(),不作解释,相信看得明白; feixing(...)鸟的飞行函数,思想很简单,先选择好一个坐标位置,显示出鸟,再停顿一段时间在相同的位置输出空白,达到非按键up操作时的下降目的; fenshuYUnandu(...),分数函数,显示分数; check1(...),检查烟囱外是否撞墙函数,这里要仔细看了,否则你会很难读懂!d 数组分别存储两烟囱之间的间距15~16像素, e 数组用来存储每条烟囱移动到与鸟的x坐标相同时的固定距离,i数组是传进来的烟囱移动的坐标变化,e-i-t是用来判断烟囱移动的时候,何时与鸟x相同,到这里,可能你有疑问了,为什么不直接判断烟囱的x和鸟的x重合,因为烟囱是动态的,同时它们还有距离限制,如果不加以限制就会乱,烟囱不是一条在往左边移动,是5条,0~4,如果相等,进入第一个if语句,进行第二次判断,判断此时鸟的y坐标是否是烟筒的入口y,如果是,则不报错,如果不是,证明撞墙了,最后的一个if语句是判断上下边界的撞墙; check(...),烟囱入口撞墙判断,这条较上条较复杂,因为烟囱的入口是有两列像素方块组成的,就是说,判断的时候要判断两列的方块。模仿上面,b c 数组分别是左列和右列的烟囱间距值,剩下的步骤就是判断入口内鸟的x是否与烟囱的x相同; 下面的一条最重要的函数,烟囱的制造、移动函数。
 void jiemian()//界面函数
{
int i=;
for(;i<;i++)
{
Position(i-,1.5);//上边
Q;
}
if(i==)
{
for(i=;i<;i++)
{
Position(i-,);//下边
Q;
}
}
}
void jiemian1() {
printf("____________________________________________________________________________\n");
printf(" ■\n");
printf(" ■\n");
printf(" ■C语言非链表版:Flappy Bird\n");
printf(" ■编写人:LinGuanH\n");
printf(" ■日期:2014.7.30\n");
printf(" ■耗时:4小时37分\n");
printf(" ■游戏说明:\n");
printf(" ■1-按键盘中的上箭头使鸟起飞\n");
printf(" ■2-分数每过20,难度增大,烟囱入口减小!\n");
printf(" ■3-光标显示方式为中文鸟字\n");
printf(" ■4-介于VS中graphics.h函数库使用失败,导致原图插入不了,所用转用黑白框。\n");
printf(" ■5-撞墙失败,游戏会提示输了,但是不会return 0,你可以继续按方向键接着玩。\n");
printf(" ■\n");
printf(" ■\n");
printf(" ■\n");
printf(" ■代码内带有注释,感兴趣的可以直接修改,增加其他效果\n");
printf(" ■必然存在bug,找到了麻烦跟我说声,谢谢。\n");
printf(" ■请按键盘的任意一个键继续。\n");
printf(" ■\n");
printf(" ■\n");
printf(" ■\n");
printf(" ____________________________________________________________________________\n");
system("pause");
}
/*void cleanjudge(int i)
{
if(i==77)
{
for(int i=1;i<6;i++)
{
Position(2,i);
PR;
Position(4,i);
PR;
}
}
}*/ //清屏函数作废
void feixing(brid B,int y)//鸟飞行坐标函数
{
Position(B.x,B.y);Br;//创建鸟
Sleep();//停顿0.2秒再下掉,也是难度的改变方法。
Position(B.x,B.y);PR;//清除鸟
//return 0;
}
void fenshuYUnandu(brid B,int i[],int o[])//显示分数函数
{
Position(,);//固定分数显示位置
printf("分数为:%d",B.score); }
void check(brid B,int i[],int o[],int temp)//检查非入口撞墙函数
{
int t,d[],e[];
d[]=;d[]=;d[]=;d[]=,d[]=;
e[]=;e[]=;e[]=;e[]=;e[]=;
for(t=;t<=;t++)
{
if(B.x==e[t]-i[t]+d[t]){
if(B.y<=o[t]+-temp||B.y>=o[t]+temp-){
Position(B.x,B.y);Br;printf("\n");Position(B.x,B.y+);
printf("Lost the game!\n");system("pause");
}
}
if(B.y>=||B.y<=1.5){
printf("Lost the game!\n");system("pause");
}
}
}
void check1(brid B,int i[],int o[],int temp)//检查入口内撞墙函数
{
int k,f,b[],c[],q[];
q[]=,q[]=,q[]=;
b[]=;b[]=;b[]=;b[]=,b[]=;//b为左
c[]=;c[]=,c[]=,c[]=,c[]=; //C为右
for(int f=;f<;f++){
for(k=;k<=;k++)
{
if((B.x-f==q[f]-i[k]+b[k]&&B.y==o[k]+-temp)||(B.x-f==q[f]-i[k]+c[k]&&B.y==o[k]+-temp)){
Position(B.x,B.y);Br;printf("\n");Position(B.x,B.y+);
printf("Lost the game!\n");system("pause");
}
if((B.x-f==q[f]-i[k]+b[k]&&B.y>=o[k]+temp-)||(B.x-f==q[f]-i[k]+c[k]&&B.y>=o[k]+temp-)){
Position(B.x,B.y);Br;printf("\n");Position(B.x,B.y+);
printf("Lost the game!\n");system("pause");
}
}//判断右侧
}
}
  1 void fangkuai(brid B,int y)
//此函数中的烟囱可以用一条函数表达,再调用5次,但是难度会更大。
//此函数为全局调用函数,历史2小时完成。
//包括方块的建成和撞墙检查的调用
//一个方块在黑白框中占2个单位
{
int i[],o[],f[],temp=;//四变量分别是坐标、随机数、距离、难度控制(烟囱间隔)
srand((int)time(NULL));//int 随即种子
o[]=rand()%+;o[]=rand()%+;o[]=rand()%+;
o[]=rand()%+;o[]=rand()%+;//先初始化5个随机数,用于首先引入方块的长度值
f[]=;f[]=;f[]=;f[]=,f[]=;
for(i[]=,i[]=,i[]=,i[]=,i[]=;i[]<,
i[]<,i[]<,i[]<,i[]<;//总循环,控制5烟囱的无限循环
i[]++,i[]++,i[]++,i[]++,i[]++,B.y++){
for(int k=;k<=o[];k++){
Position(-i[],k);P;}//上左
for(int k=;k<=-o[]-temp;k++){//25-26+o[0]+temp=temp-1+o[0]
Position(-i[],-k);P;}//下左
if(i[]==||i[]>){
for(int k=;k<=o[];k++){//上右
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;//下右
}
}
if(i[]==){//达屏幕最左端,开始清屏,下同理。
for(int k=;k<=o[];k++)
{
Position(,k);PR;//清理左边
Position(,k);PR;
}
for(int k=;k<=-o[]-temp;k++){//清理右边
Position(,-k);PR;
Position(,-k);PR;
}
if(i[]>=){//56+15=71,此处的if语句的作用是为了使两烟囱之间保持距离,距离为15/2像素
i[]=;//距离够了i【0】清0,从新从右边出烟囱
o[]=rand()%+;//从新产生随机数
}
else i[]=;//否则,一直在左边等清屏
}//第一条烟囱完成
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}
if(i[]==){
for(int k=;k<=o[];k++)
{
Position(,k);PR;
Position(,k);PR;
}
for(int k=;k<=-o[]-temp;k++){
Position(,-k);PR;
Position(,-k);PR;
}
if(i[]>=){
i[]=;
o[]=rand()%+;
}
else i[]=;
}//第二条
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}//
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}
if(i[]==){
for(int k=;k<=o[];k++)
{
Position(,k);PR;
Position(,k);PR;
}
for(int k=;k<=-o[]-temp;k++){
Position(,-k);PR;
Position(,-k);PR;
}
if(i[]>=){//14+15=29
o[]=rand()%+;
i[]=;
}
else i[]=;
}//第三条
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}
if(i[]==){
for(int k=;k<=o[];k++)
{
Position(,k);PR;
Position(,k);PR;
}
for(int k=;k<=-o[]-temp;k++){
Position(,-k);PR;
Position(,-k);PR;
}
if(i[]>=){//28+15=43
o[]=rand()%+;
i[]=;
}
else i[]=;
}//第四条
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}
if(i[]==||i[]>){
for(int k=;k<=o[];k++){
Position(-i[]+,k);P;}
for(int k=;k<=-o[]-temp;k++){
Position(-i[]+,-k);P;
}
}
if(i[]==){
for(int k=;k<=o[];k++)
{
Position(,k);PR;
Position(,k);PR;
}
for(int k=;k<=-o[]-temp;k++){
Position(,-k);PR;
Position(,-k);PR;
}
if(i[]>=){
o[]=rand()%+;
i[]=;
}
else i[]=;
}//第五条
feixing(B,y);
check1(B,i,o,temp);
if(GetAsyncKeyState(VK_UP)&&y>)
B.y=B.y-;
//if(GetAsyncKeyState(VK_DOWN)&&y>0)
//B.y=B.y+1;
//else if(B.y<=0)
check(B,i,o,temp);
for(int k=;k<=;k++){
if(B.x==-i[k]+f[k])
{B.score++;}//记录鸟超过的烟囱数并累加分数
}
fenshuYUnandu(B,i,o);
if(B.score%==&&B.x==-i[]+)//烟囱入口变小
temp--;
}
}

最后的main函数

 int main()
{
brid B;
B.x=;B.y=;B.score=;//初始鸟的位置和初始分数
int x=,y=;//初始分界线的位置
jiemian1();
system("cls");
jiemian();
fangkuai(B,y);
return ;
}

效果图片:

  

C语言版flappy bird黑白框游戏的更多相关文章

  1. 也来山寨一版Flappy Bird (js版)

    随着Flappy Bird的火爆,各种实现的版也不断出现,于是也手痒简单实现了一版. 其实本来只是想实现一下这只笨鸟的飞翔运动的,后来没忍住,就直接实现一个完整游戏了…… 因为这个游戏本身实现起来就没 ...

  2. cocos2dx-html5 实现网页版flappy bird游戏

    我也是第一次使用cocos2d_html5,对js和html5也不熟,看引擎自带的例子和引擎源码,边学边做,如果使用过cocos2d-x的话,完成这个游戏还是十分简单的.游戏体验地址: http:// ...

  3. 转载:Flappy Bird源代码 win32 console版

    #include"StdAfx.h" #include<stdio.h> #include<stdlib.h> #include<conio.h> ...

  4. Flappy bird源代码(略吊)

    #include<stdio.h> #include<stdlib.h> #include<conio.h> #include<time.h> #inc ...

  5. 飞翔的圆(Flappy Bird)游戏源码

    这个源码是一个不错的休闲类的游戏源码,飞翔的圆(Flappy Bird)游戏源码V1.0,本项目是一个仿Flappy Bird的小游戏,只不过是把Flappy Bird里面的鸟替换成了简单的圆.感兴趣 ...

  6. 【教程】HTML5+JavaScript编写flappy bird

         作者: 风小锐      新浪微博ID:永远de风小锐      QQ:547953539      转载请注明出处 PS:新修复了两个bug,已下载代码的同学请查看一下 大学立即要毕业了. ...

  7. Flappy Bird背后的故事

    更多有价值的互联网文章:晓煦分享(http://www.ihuxu.com/share) 由越南游戏工程师阮哈东(Nguyen Ha Dong)开发的Flappy Bird这款游戏,画面不算精致且看起 ...

  8. 自己动手写游戏:Flappy Bird

    START:最近闲来无事,看了看一下<C#开发Flappy Bird游戏>的教程,自己也试着做了一下,实现了一个超级简单版(十分简陋)的Flappy Bird,使用的语言是C#,技术采用了 ...

  9. 65行 JavaScript 代码实现 Flappy Bird 游戏

    飞扬的小鸟(Flappy Bird)无疑是2014年全世界最受关注的一款游戏.这款游戏是一位来自越南河内的独立游戏开发者阮哈东开发,形式简易但难度极高的休闲游戏,很容易让人上瘾. 这里给大家分享一篇这 ...

随机推荐

  1. angular 中父元素ng-repeat后子元素ng-click失效

    在angular中使用ng-repeat后ng-click失效,今天在这个上面踩坑了.特此记录一下. 因为ng-repeat创造了新的SCOPE.如果要使用这个scope的话就必须使用$parent来 ...

  2. Python新建动态命名txt文件

    # -*- coding: utf-8 -*- import os,sys,time fname=r"D:\01-学习资料\python" def GetNowTime():#获取 ...

  3. JavaScript 作用域知识点梳理

    JavaScript的作用域一直以来是前端开发中难以理解的知识点,对于JavaScript的作用域主要记住几句话. 一.“JavaScript” 中无块级作用域 在   Java 或 C# 中存在块级 ...

  4. 利用sqlmap进行mysql提权的小方法(win与liunx通用)

    文章作者:pt007@vip.sina.com文章来源:https://www.t00ls.net/thread-36196-1-1.html1.连接mysql数据打开一个交互shell:sqlmap ...

  5. MYSQL删除重复数据

     delete from co_jobinformation cwhere c.name in (select cc.name from co_jobinformation cc group by   ...

  6. content内网,会显示内容,没有内容可地址存在就是这个情况

    漏洞地址:http://note.youdao.com/memory/?url=http://www.wooyun.org(如需登录,请注册登录) 正文预览的地方会读取URL地址的<meta n ...

  7. 省市县三级联动(jqurey+json)

    1.效果图 2.联动js /** * jquery.choosearea.js - 地区联动封装 */ ; (function ($) { var choosearea = function (opt ...

  8. 突破瓶颈,对比学习:Eclipse开发环境与VS开发环境的调试对比

    曾经看了不少Java和Android的相关知识,不过光看不练易失忆,所以,还是写点文字,除了加强下记忆,也证明我曾经学过~~~ 突破瓶颈,对比学习: 学习一门语言,开发环境很重,对于VS的方形线条开发 ...

  9. 利用gulp搭建本地服务器,并能模拟ajax

    工作中可能会用到的小工具,在此记录一下.可以实现的功能有: 本地http服务器 页面实时刷新 可以模拟ajax请求 第一步,新建package.json文件.用到了gulp.gulp-webserve ...

  10. 小型单文件NoSQL数据库SharpFileDB初步实现

    小型单文件NoSQL数据库SharpFileDB初步实现 我不是数据库方面的专家,不过还是想做一个小型的数据库,算是一种通过mission impossible进行学习锻炼的方式.我知道这是自不量力, ...