C++版本简易Flappy bird

 更新时间:2020年4月25日 17:39  点击:2141

大一,上学期学完了C,写了几个控制台游戏
这学期自学C++,由于学校课程第七周才有C++

边学边写了这个小游戏,SDL 图形库完成的图形绘画
时间匆忙,BUG也有,代码效率比较低
和原作品还是很大的差别, 源代码在附件游戏文件夹中

演示图

#include <stdlib.h> 
#include<windows.h>   
#include <time.h>
#include<conio.h>
#include <iostream> 
#include <mmsystem.h> 
#include "SDL\SDL_image.h"
#include "SDL\SDL_ttf.h"
#include "SDL\SDL.h"
using namespace std;
#pragma comment(lib, "winmm.lib") 
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"") 
 int iii=0;
 int score =0;
 int y=0;
 int posi[3][2]= {{640,-300},{940,-300},{1240,-300}};
int i=0,n=3;  //n为管道对数
SDL_Color textColor_1 = { 37, 134, 108 };//绿色
//SDL_Color textColor_2 = { 112, 112, 35 };
SDL_Color textColor_2 = { 255, 255, 255 }; //白色
 
SDL_Color textColor_3 = { 0, 88, 132 }; //白色
 
class Event
{
public:
  SDL_Event event;
  Uint8 *keystates;
  Event()
  {
    keystates=SDL_GetKeyState( NULL );
  }
 
 
};
Event thing;
class Data
{
public:
  int bird_y;
  int score;
  int posi[20][2];
  SDL_Rect bird_1;
  SDL_Rect bird_2;
  SDL_Rect bg;
  SDL_Rect welcome;
  SDL_Rect pipe_up;
  SDL_Rect pipe_down;
  SDL_Rect bird_cls;
  SDL_Rect foot;
 
  SDL_Surface* load_imag(char *s)
  {
    SDL_Surface* temp;
    temp=IMG_Load(s);
 
    bg.x=0;
    bg.y=0;
    bg.w=640;
    bg.h=480;
 
    welcome.x=681;
    welcome.y=0;
    welcome.w=640;
    welcome.h=480;
 
    bird_1.x=17;
    bird_1.y=508;
    bird_1.w=52;
    bird_1.h=34;
 
    bird_2.x=461;
    bird_2.y=531;
    bird_2.w=52;
    bird_2.h=33;
 
    bird_cls.w=52;
    bird_cls.h=33;
    bird_cls.x=0;
    bird_cls.y=0;
     
    pipe_up.x=1361;
    pipe_up.y=11;
    pipe_up.w=103;
    pipe_up.h=410;
 
    pipe_down.x=1487;
    pipe_down.y=14;
    pipe_down.w=103;
    pipe_down.h=443;
 
    foot.x=0;
    foot.y=404;
    foot.w=640;
    foot.h=80;
 
 
   
    return temp;//SDL_DisplayFormat( temp );
  }
 
  TTF_Font* load_font()
  {
    SDL_Init( SDL_INIT_EVERYTHING );
    TTF_Init();
    return TTF_OpenFont( "main_1.dat", 36 );
 
  }
};
 
Data data;
 
class Pri
{
 
public:
  SDL_Surface* out; //输出
  SDL_Surface* main ; //主窗口
  TTF_Font *font;
  SDL_Rect a; //设置初始位置
  SDL_Surface*bird;
  SDL_Rect xy;
  SDL_Surface*font_1;
  SDL_Surface*font_2;
  SDL_Surface*font_11;
  SDL_Surface*font_22;
 
 
  Pri()
  {
      TTF_Font *font = NULL;
      init();//初始化输出设备
     
  }
 
  int init()
  {
    SDL_Init( SDL_INIT_EVERYTHING );
    TTF_Init();
    main= SDL_SetVideoMode( 640, 478, 32, SDL_SWSURFACE );
    SDL_WM_SetCaption("Flappy bird",NULL);//标题
    font=data.load_font();
    out=data.load_imag("main_2.dat");
    y=150;
   
    posi[0][0]=640;
    posi[0][1]=-300;
    posi[1][0]=940;
    posi[1][1]=-300;
    posi[2][0]=1240;
    posi[2][1]=-300;
    return 1;
  }
 
  int pipe()
  {
 
  }
 
  int bir(int y)//x=150
  {int ii;
  i+=1;
  xy.x=150;
  xy.y=y;
  if(i<14)
   
    {
      xy.x=150;
      xy.y=y;
      SDL_BlitSurface(out,&data.bg,main,NULL);
 
       
      for(ii=0;ii<n;ii++)
      {
        xy.x=posi[ii][0];
        xy.y=posi[ii][1];
        SDL_BlitSurface(out,&data.pipe_down,main,&xy);
        xy.x=posi[ii][0];
        xy.y=posi[ii][1]+600;
        SDL_BlitSurface(out,&data.pipe_up,main,&xy);
 
      }
 
 
 
 
 
      xy.x=150;
      xy.y=y;
      SDL_BlitSurface(out,&data.bird_1,main,&xy);
    xy.x=0;
      xy.y=404;
      SDL_BlitSurface(out,&data.foot,main,&xy);
   
    }
   
     
  else
    {
      xy.x=150;
      xy.y=y;
      SDL_BlitSurface(out,&data.bg,main,NULL);
      for(ii=0;ii<n;ii++)
      {
        xy.x=posi[ii][0];
        xy.y=posi[ii][1];
        SDL_BlitSurface(out,&data.pipe_down,main,&xy);
 
        xy.x=posi[ii][0];
        xy.y=posi[ii][1]+600;
        SDL_BlitSurface(out,&data.pipe_up,main,&xy);
 
      }
 
      xy.x=150;
      xy.y=y;
      SDL_BlitSurface(out,&data.bird_2,main,&xy);
      xy.x=0;
      xy.y=404;
      SDL_BlitSurface(out,&data.foot,main,&xy);
      if(i>28)i=0;
    }
    return 0;
     
 
  }
 
  int bg()
  {
      SDL_BlitSurface(out,&data.bg,main,&xy);
       
      return 0;
  }
 
  int over()
  {
    int x=0,y=0,i=0;
 
    xy.x=250;
    xy.y=150;
    font_1=TTF_RenderText_Solid( font, "Game over !", textColor_3);
    SDL_BlitSurface( font_1 , NULL, main, &xy);
 
    SDL_Flip(main);
 
    xy.x=350;
    xy.y=200;
    font_1=TTF_RenderText_Solid( font, "Retry game", textColor_1 );
    font_11=TTF_RenderText_Solid( font, "Retry game", textColor_2 );
    SDL_BlitSurface( font_1 , NULL, main, &xy); 
     
 
    xy.x=350;
    xy.y=280;
 
    font_2=TTF_RenderText_Solid( font, " Exit game", textColor_1 );
    font_22=TTF_RenderText_Solid( font, " Exit game", textColor_2 );
    SDL_BlitSurface( font_2 , NULL, main, &xy); 
/*
    xy.x=10;
    xy.y=440;
    //野指针
    SDL_BlitSurface( TTF_RenderText_Solid( font, "Esc:exit game  Space:to jump hekun ", textColor_1 ) , NULL, main, &xy); 
    SDL_Flip( main ); //更新窗口
    */
 
    while(SDL_PollEvent( &thing.event ), 1)
    {
      i+=2;
      Sleep(1);
      if( thing.keystates[ SDLK_ESCAPE] )exit(0);
      if( thing.event.type == SDL_QUIT )// 点击了SDL关闭按钮
      {
        exit(0);
      } 
 
 
      if((x>350&&x<540)&&(y<240)&&(y>200))
      {
        if(thing. event.type == SDL_MOUSEBUTTONDOWN)
          if(thing.event.button.button== SDL_BUTTON_LEFT )
          {
            SDL_FreeSurface(font_1);
            SDL_FreeSurface(font_11);
            SDL_FreeSurface(font_22);
            SDL_FreeSurface(font_2);
          WinExec("Flappy bird.exe",NULL);
          exit(0);
            return 11;
          }
 
 
      }
      else
      {
 
 
      }
 
 
 
      if((x>350&&x<540)&&(y<320)&&(y>280))  //结束游戏
      {
        if(thing. event.type == SDL_MOUSEBUTTONDOWN)
          if(thing.event.button.button== SDL_BUTTON_LEFT )exit(0);
 
      }
 
 
      if(thing. event.type == SDL_MOUSEMOTION )
      {
        x=thing.event.motion.x;
        y=thing.event.motion.y;
 
        //获得鼠标坐标
        if((thing.event.motion.x>350&&thing.event .motion .x<540)&&(thing.event.motion.y<240)&&(thing.event.motion.y>200))
        {
          xy.x=350;
          xy.y=200;
          SDL_BlitSurface( font_11, NULL, main, &xy); 
          SDL_Flip(main);
        }
        else
        {
          xy.x=350;
          xy.y=200;
          SDL_BlitSurface( font_1 , NULL, main, &xy); 
          SDL_Flip(main);
        }
 
 
 
        if((thing.event.motion.x>350&&thing.event .motion .x<540)&&(thing.event.motion.y<320)&&(thing.event.motion.y>280))
        {
          xy.x=350;
          xy.y=280;
          SDL_BlitSurface( font_22 , NULL, main, &xy); 
          SDL_Flip(main);
 
 
        }
        else
        {
          xy.x=350;
          xy.y=280;
          SDL_BlitSurface( font_2 , NULL, main, &xy); 
          SDL_Flip(main);
        }
      }
 
 
 
    }
    return 0;
  }
 
  int welcome()
  {    
 
    int x=0,y=0,i=0;
 
 
    SDL_BlitSurface(out,&data.welcome,main,NULL);
    bird=out;
    xy.x=350;
    xy.y=200;
    font_1=TTF_RenderText_Solid( font, "Start game", textColor_1 );
    font_11=TTF_RenderText_Solid( font, "Start game", textColor_2 );
    SDL_BlitSurface( font_1 , NULL, main, &xy); 
 
    xy.x=350;
    xy.y=280;
 
    font_2=TTF_RenderText_Solid( font, " Exit game", textColor_1 );
    font_22=TTF_RenderText_Solid( font, " Exit game", textColor_2 );
    SDL_BlitSurface( font_2 , NULL, main, &xy); 
 
    xy.x=10;
    xy.y=440;
    //野指针
    SDL_BlitSurface( TTF_RenderText_Solid( font, "Esc:exit game  Space:to jump hekun ", textColor_1 ) , NULL, main, &xy); 
    SDL_Flip( main ); //更新窗口
     
 
    while(SDL_PollEvent( &thing.event ), 1)
    {
      i+=2;
      Sleep(1);
      if( thing.keystates[ SDLK_ESCAPE] )exit(0);
      if( thing.event.type == SDL_QUIT )// 点击了SDL关闭按钮
      {
        exit(0);
      } 
 
 
      if((x>350&&x<540)&&(y<240)&&(y>200))
      {
        if(thing. event.type == SDL_MOUSEBUTTONDOWN)
          if(thing.event.button.button== SDL_BUTTON_LEFT )
          {
            SDL_FreeSurface(font_1);
            SDL_FreeSurface(font_11);
            SDL_FreeSurface(font_22);
            SDL_FreeSurface(font_2);
            return 0;
          }
     
       
      }
      else
      {
         
       
      }
 
 
 
      if((x>350&&x<540)&&(y<320)&&(y>280))  //结束游戏
      {
        if(thing. event.type == SDL_MOUSEBUTTONDOWN)
          if(thing.event.button.button== SDL_BUTTON_LEFT )exit(0);
 
      }
     
 
      if(thing. event.type == SDL_MOUSEMOTION )
      {
        x=thing.event.motion.x;
        y=thing.event.motion.y;
 
        //获得鼠标坐标
        if((thing.event.motion.x>350&&thing.event .motion .x<540)&&(thing.event.motion.y<240)&&(thing.event.motion.y>200))
        {
          xy.x=350;
          xy.y=200;
          SDL_BlitSurface( font_11, NULL, main, &xy); 
          SDL_Flip(main);
        }
        else
        {
          xy.x=350;
          xy.y=200;
          SDL_BlitSurface( font_1 , NULL, main, &xy); 
          SDL_Flip(main);
        }
 
 
 
         if((thing.event.motion.x>350&&thing.event .motion .x<540)&&(thing.event.motion.y<320)&&(thing.event.motion.y>280))
        {
          xy.x=350;
          xy.y=280;
          SDL_BlitSurface( font_22 , NULL, main, &xy); 
          SDL_Flip(main);
       
 
        }
        else
        {
          xy.x=350;
          xy.y=280;
          SDL_BlitSurface( font_2 , NULL, main, &xy); 
          SDL_Flip(main);
        }
      }
       
 
      if(i==400)
      {
        xy.x=150;
        xy.y=250;
        SDL_BlitSurface(bird,&data.bird_1,main,&xy);
        SDL_Flip(main);
      }
 
 
     
      if(i==800)
      {
        xy.x=150;
        xy.y=250;
        SDL_BlitSurface(bird,&data.bird_2,main,&xy);
        i=0;
        SDL_Flip(main);
      }
 
 
    }
    return 0;
   
  }
 
 
 
};
 
Pri pri;
 
 
 
int game_judge()
{int i=0;
  if(y>370||y<-10)
  {
    if(pri.over()==11)return 12;
 
  }
 
  for(i=0;i<3;i++)
  {
    if(posi[i][0]<202 &&posi[i][0]>50)
    {
      if(y<posi[i][1]+ 420 ||y>posi[i][1]+570)
      {if(pri.over()==11)return 12;}
    }
 
  }
 
 
  return 0;
}
 
 
 
int game_loop()
{ y=150,i=0;
  int ii=0,iii=0;
  SDL_Surface *font;
  pri.bg();
 
  char s[50];
  Uint32 start = 0;
  sprintf(s," FPS:%d\t\t\t\t\t\t\t\tScore:%d",1000/(SDL_GetTicks()-start),score);
 
  int q=0;
while(SDL_PollEvent( &thing.event ), 1)
{
 
  start = SDL_GetTicks();
  i++;
  Sleep(1);
  SDL_Flip(pri.main);
  y+=4;
  if(y>430)y=100;
 
  if(thing.event.button.state==SDL_PRESSED)y-=20;
  if( thing.keystates[ SDLK_SPACE] )y-=20;
  if( thing.keystates[ SDLK_ESCAPE] )exit(0);
  if( thing.event.type == SDL_QUIT )// 点击了SDL关闭按钮
  {
    exit(0);
  } 
   
  if(game_judge()==12)return 0;
 
    pri.bir(y);
   
    //显示 每秒循环的次数 
    ii++;
    if(ii>20)  
    {
      sprintf(s," FPS:%d\t\t\t\t\t\t\t\tScore:%d",1000/(SDL_GetTicks()-start)+rand()%5,score);
      ii=0;
    }
     
       
      font=TTF_RenderText_Solid( pri.font, s, textColor_2 );
      SDL_BlitSurface(font , NULL,pri. main, NULL); 
      SDL_Flip(pri.main);
      SDL_FreeSurface(font);
 
      posi[0][0]-=2;
      posi[1][0]-=2;
      posi[2][0]-=2;
 
      if(posi[0][0]<=(-110))
      {posi[0][0]=posi[2][0]+300;posi[0][1]=-(rand()%180)-220;}
   
      if(posi[1][0]<=(-110))
      {posi[1][0]=posi[0][0]+300;posi[1][1]=-(rand()%180)-220;}
 
 
      if(posi[2][0]<=(-110))
      {posi[2][0]=posi[1][0]+300;posi[2][1]=-(rand()%180)-220;}
       
 
     
      iii++;
      if(iii>50)
 
      for(iii=0;iii<3;iii++)
      {
        if(posi[iii][0]<50);
        score++;
        iii=0;
        break;
      }
 
}
 
  return 0;
 
}
 
int main(int argc, char* argv[])
{
   
  while(1)
  {
   
    pri.init();//初始化输出设备
    pri.welcome();
    game_loop();
   
  }
  return 0;
}
 

以上所述就是本文的全部内容了,希望大家能够喜欢。

[!--infotagslink--]

相关文章

  • C++ STL标准库std::vector的使用详解

    vector是表示可以改变大小的数组的序列容器,本文主要介绍了C++STL标准库std::vector的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2022-03-06
  • C++中取余运算的实现

    这篇文章主要介绍了C++中取余运算的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • 详解C++ string常用截取字符串方法

    这篇文章主要介绍了C++ string常用截取字符串方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • C++中四种加密算法之AES源代码

    本篇文章主要介绍了C++中四种加密算法之AES源代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。...2020-04-25
  • C++ 整数拆分方法详解

    整数拆分,指把一个整数分解成若干个整数的和。本文重点给大家介绍C++ 整数拆分方法详解,非常不错,感兴趣的朋友一起学习吧...2020-04-25
  • C++中 Sort函数详细解析

    这篇文章主要介绍了C++中Sort函数详细解析,sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变...2022-08-18
  • C++万能库头文件在vs中的安装步骤(图文)

    这篇文章主要介绍了C++万能库头文件在vs中的安装步骤(图文),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-23
  • 详解C++ bitset用法

    这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • 浅谈C++中的string 类型占几个字节

    本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节...2020-04-25
  • C++ Eigen库计算矩阵特征值及特征向量

    这篇文章主要为大家详细介绍了C++ Eigen库计算矩阵特征值及特征向量,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-04-25
  • C++ pair的用法实例详解

    这篇文章主要介绍了C++ pair的用法实例详解的相关资料,需要的朋友可以参考下...2020-04-25
  • VSCode C++多文件编译的简单使用方法

    这篇文章主要介绍了VSCode C++多文件编译的简单使用方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-29
  • C++中的循环引用

    虽然C++11引入了智能指针的,但是开发人员在与内存的斗争问题上并没有解放,如果我门实用不当仍然有内存泄漏问题,其中智能指针的循环引用缺陷是最大的问题。下面通过实例代码给大家介绍c++中的循环引用,一起看看吧...2020-04-25
  • C++随机点名生成器实例代码(老师们的福音!)

    这篇文章主要给大家介绍了关于C++随机点名生成器的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • C++如何删除map容器中指定值的元素详解

    map容器是C++ STL中的重要一员,删除map容器中value为指定元素的问题是我们经常与遇到的一个问题,下面这篇文章主要给大家介绍了关于利用C++如何删除map容器中指定值的元素的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。...2020-04-25
  • C++ 约瑟夫环问题案例详解

    这篇文章主要介绍了C++ 约瑟夫环问题案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-08-15
  • C++中cin的用法详细

    这篇文章主要介绍了C++中cin的用法详细,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25
  • 基于C++中常见编译错误的总结详解

    本篇文章是对C++中的常见编译错误进行了详细的分析介绍,需要的朋友参考下...2020-04-25
  • c++优先队列(priority_queue)用法详解

    这篇文章主要介绍了c++优先队列(priority_queue)用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-25