用SDL編寫的Flappy bird電腦版。
請大家尊重原創,轉載或者用到其中的函數請註明出處,以及作者(五十風)
main.cpp
/***************************************************************
*
版權所有 (C)2014, 五十風
*
*
文件名稱:main.cpp
*
內容摘要:FlappyBird主函數文件
*
其它說明:無
*
當前版本:v1.2
*
作 者:五十風
*
完成日期:2014.11.4
*
代替版本:v1.1
*
原作者: 五十風
*
原版完成日期:2014.10.18
*
*
修改記錄1:
*
修改日期:2014.11.4
*
版本號:v1.2
*
修改人:五十風
*
修改內容:1.修改了main函數
2.加入宏定義#pragma
***************************************************************/
#include<SDL/SDL.h>
#include<SDL/SDL_image.h>
#include<SDL/SDL_mixer.h>
#include<SDL/SDL_ttf.h>
#include<string>
#include<cstdio>
#include<fstream>
#include<sstream>
#include<ctime>
#include<windows.h>
//#include "resource.h"
#include"variable.h"
#include"funcation.h"
#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
Bird mybird;
Tile *tiles[ TOTAL_TILES ];
/**********************************************************************
* 功能描述:主函數
* 輸入參數:int argc,char*args[]
* 輸出參數:無
* 返回值:0
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.11.4 V1.2 五十風 修改openfile函數的名稱爲firsttime,
把load函數放到firsttime前面,
load函數,firsttime函數增加了返回值,返回bool類型的值,改回false退出程序。
***********************************************************************/
int main(int argc,char*args[])
{
if(load()==false)
return 0;
if(firsttime()==false)
return 0;
while(quit==false)
{
if(showmenu==true)
{
quit=menu();
showmenu=false;
}
if(die==false && quit==false)
{play(mybird,tiles);}
if(die==true && quit==false)
{
Die();
score=0;
scoreline=359;
}
}
clean_up(tiles);
return 0;
}
variable.h
/***************************************************************
*
版權所有 (C)2014, 五十風
*
*
文件名稱:variable.h
*
內容摘要:定義用到的全局變量
*
其它說明:
*
當前版本:v1.2
*
作 者:五十風
*
完成日期:2014.11.14
*
代替版本:v1.1
*
原作者: 五十風
*
原版完成日期:2014.10.18
*
修改記錄1:
*
修改日期:2014.11.4
*
版本號:v1.2
*
修改人:五十風
*
修改內容:1.加入變量first1,first2,first3用於加載提示圖片
2.加入變量button_lift,button_right用於調節難度
3.加入變量button_soundon,button_soundoff=NULL用於顯示靜音按鈕
4.加入變量startbox,liftbox,rightbox,soundbox,helpbox,rankingbox用於設置按鈕的位置
5.加入變量fontcn_tip,theeasy 用於加載字體
6.加入變量thehelp,theranking,thetip,theeasy 用於顯示幫助,高分榜,小提示,難度的文字
7.加入變量iseasy,easy用於記錄難度,以及調節當前難度下鳥的飛行高度
7.用變量scorea,scoreb替代了temp用於從文件讀取分數
*
修改記錄2:
*
修改日期:2014.11.18
*
版本號:v1.2
*
修改人:五十風
*
修改內容:1.加入變量type。
***************************************************************/
//圖
SDL_Surface *tips=NULL;
SDL_Surface *title=NULL;
SDL_Surface *background=NULL;
SDL_Surface *bird=NULL;
SDL_Surface *pipe_blank=NULL;//管道和空白盒子
SDL_Surface *screen=NULL;
SDL_Surface *scorepic=NULL;
SDL_Surface *highpic=NULL;
SDL_Surface *engineer=NULL;
SDL_Surface *first1=NULL;
SDL_Surface *first2=NULL;
SDL_Surface *first3=NULL;
//按鈕
SDL_Surface *button_start = NULL;
SDL_Surface *button_lift = NULL;
SDL_Surface *button_right = NULL;
SDL_Surface *button_soundon=NULL;
SDL_Surface *button_soundoff=NULL;
SDL_Rect startbox={187,350,166,100};
SDL_Rect liftbox={205,310,22,30};
SDL_Rect rightbox={310,311,22,30};
SDL_Rect soundbox={0,630,30,30};
SDL_Rect helpbox={150,500,40,30};
SDL_Rect rankingbox={320,500,50,30};
int startTicks=0;//計時器
const int FRAMES_PER_SECOND = 18;//幀頻率
const int screen_h=660;
const int screen_w=540;
const int bird_w=40;
const int bird_h=30;
const int LEVEL_WIDTH=3580;
const int LEVEL_HEIGHT=660;
Mix_Chunk *pu = NULL;//聲效“噗”
Mix_Chunk *dingdong= NULL; //聲效“叮咚”
Mix_Chunk *pa = NULL;//聲效“啪”
//字體
TTF_Font *font = NULL;
TTF_Font *font2 = NULL;
TTF_Font *fontcn_tip = NULL;
TTF_Font *fontcn_easy = NULL;
SDL_Color textColor={91,64,75};
SDL_Color textColor2={0,0,0};
//字表面
SDL_Surface *message = NULL;//用於顯示最終得分
SDL_Surface *thescore = NULL;//在遊戲中顯示得分
SDL_Surface *thetip = NULL;//小提示
SDL_Surface *theeasy = NULL;
SDL_Surface *thehelp = NULL;
SDL_Surface *theranking = NULL;
//地圖相關
//第1種管道的上、下管道的寬、高
const int top1_w = 59;
const int top1_h = 270;
const int btm1_w = 59;
const int btm1_h = 270;
//第2種管道的上、下管道的寬、高
const int top2_w = 59;
const int top2_h = 150;
const int btm2_w = 59;
const int btm2_h = 390;
//第3種管道的上、下管道的寬、高
const int top3_w = 59;
const int top3_h = 390;
const int btm3_w = 59;
const int btm3_h = 150;
//第4種管道的上、下管道的寬、高
const int top4_w = 59;
const int top4_h = 360;
const int btm4_w = 59;
const int btm4_h = 180;
//空白盒子的寬、高
const int blank_w = 59;
const int blank_h = 120;
const int TOTAL_TILES = 60;//用到的貼圖數量
const int TILE_SPRITES = 9;//貼圖種類數量
//給貼圖標號
const int top1= 0;
const int top2 = 1;
const int top3 = 2;
const int top4 = 3;
const int btm1 = 4;
const int btm2 = 5;
const int btm3 = 6;
const int btm4 = 7;
const int blank = 8;
SDL_Rect clips[ TILE_SPRITES ];//剪切的圖
SDL_Rect camera = {0,0,screen_w, screen_h};//相機
SDL_Event event;//事件體
bool start=false;
bool quit=false;
bool iseasy=false;//難度
int easy=1;//調整鳥的飛行高度
bool issound=true;//打開音樂
int bgX = 0, bgY = 0;//背景座標
int score=0;
bool die=false;
bool showmenu=true;
int scorea,scoreb;
int scoreline=359;
int type;//管道的類型
funcation.h
/***************************************************************
*
版權所有 (C)2014, 五十風
*
*
文件名稱:function.h
*
內容摘要:FlappyBird用到的類以及函數
*
其它說明:無
*
當前版本:v1.2
*
作 者:五十風
*
完成日期:2014.11.4
*
代替版本:v1.1
*
原作者: 五十風
*
原版完成日期:2014.10.18
*
*
修改記錄1:
*
修改日期:2014.11.4
*
版本號:v1.2
*
修改人:五十風
*
修改內容:1.修改openfile函數,並改名爲firsttime
2.在加載錯誤的判斷語句中加入彈窗提示。
3.修改Score函數
4.修改Button類
5.加入localeToUTF8函數用於字符的轉碼
6.修改Die函數
***************************************************************/
/**********************************************************************
* 類描述:貼圖類,用於設置顯示貼圖,獲取貼圖種類
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
class Tile
{
private:
SDL_Rect box;
int type;
public:
Tile( int x, int y, int tileType );
void show();
int get_type();
SDL_Rect get_box();
};
/**********************************************************************
* 類描述:鳥類,用於控制鳥的飛行
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 增加變量ishit用於記錄是否按下按鍵。
***********************************************************************/
class Bird
{
private:
SDL_Rect box;
int yVel,xVel;
SDL_Rect dotbox;
bool ishit;
public:
Bird();
void handle_input();
void move(Tile *tiles[]);
void show();
void set_camera();
};
/**********************************************************************
* 類描述:按鈕類,用於設置按鈕,檢測按鈕是否按下
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.11.4 V1.2 五十風 修改構造函數,並增加了重載的構造函數
***********************************************************************/
class Button
{
private:
SDL_Rect box;
SDL_Surface* button;
public:
bool isdown_button;//是否按下按鈕
Button(SDL_Rect);
Button(SDL_Rect ,SDL_Surface*);
void handle_events();
void show();
};
/**********************************************************************
* 功能描述:生成隨機地圖文件
* 輸入參數:無
* 輸出參數:無
* 返回值:0
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
void builtmap()
{
std::ofstream fout("map.map");
if(fout==NULL)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 04-1"),TEXT("錯誤!"),MB_OK);
return;
}
int a;
double b,c;
srand(unsigned(time(0)));
for(int i=0;i<20;i++)
{
b=(0+(4-0)*rand()/(RAND_MAX+1.0));
c=(0+(20-0)*rand()/(RAND_MAX+1.0));
a=(int)b*c;
a=a%4;
fout<<0;
fout<<a;
fout<<" ";
fout<<0<<8;
fout<<" ";
switch(a)
{
case 0:a=4;break;
case 1:a=5;break;
case 2:a=6;break;
case 3:a=7;break;
}
fout<<0;
fout<<a;
fout<<" ";
fout<<"\n";
}
fout.clear();
fout.close();
}
/**********************************************************************
* 功能描述:用於字符編碼轉換
* 輸入參數:char *src
* 輸出參數:無
* 返回值:buf
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.11.4 V1.2 五十風 創建
***********************************************************************/
char *localeToUTF8(char *src)
{
static char *buf = NULL;
if(buf)
{
free(buf);
buf = NULL;
}
wchar_t *unicode_buf;
int nRetLen = MultiByteToWideChar(CP_ACP,0,src,-1,NULL,0);
unicode_buf = (wchar_t*)malloc((nRetLen+1)*sizeof(wchar_t));
MultiByteToWideChar(CP_ACP,0,src,-1,unicode_buf,nRetLen);
nRetLen = WideCharToMultiByte(CP_UTF8,0,unicode_buf,-1,NULL,0,NULL,NULL);
buf = (char*)malloc(nRetLen+1);
WideCharToMultiByte(CP_UTF8,0,unicode_buf,-1,buf,nRetLen,NULL,NULL);
free(unicode_buf);
return buf;
}
/**********************************************************************
* 功能描述:初始化sdl
* 輸入參數:無
* 輸出參數:無
* 返回值:true
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.11.4 V1.2 五十風 加入MessageBox函數
***********************************************************************/
bool init()
{
if(SDL_Init(SDL_INIT_EVERYTHING)==-1)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 01-1"),TEXT("錯誤!"),MB_OK);
return false;
}
screen=SDL_SetVideoMode(screen_w,screen_h,32,SDL_SWSURFACE);
if(screen==NULL)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 02"),TEXT("錯誤!"),MB_OK);
return false;
}
if(TTF_Init()==-1)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 01-2"),TEXT("錯誤!"),MB_OK);
return false;
}
SDL_WM_SetCaption(localeToUTF8("flappy bird v1.2 by:五十風"), NULL );
if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 ) == -1 )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 01-3"),TEXT("錯誤!"),MB_OK);
return false;
}
return true;
}
/**********************************************************************
* 功能描述:優化圖片
* 輸入參數:std::string name
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
SDL_Surface *load_image(std::string name)
{
SDL_Surface *loadedimage=NULL;
SDL_Surface *optimizedimage=NULL;
loadedimage=IMG_Load(name.c_str());
if(loadedimage)
{
optimizedimage = SDL_DisplayFormat( loadedimage );
SDL_FreeSurface( loadedimage );
if(optimizedimage!=NULL )
{
Uint32 colorkey=SDL_MapRGB(optimizedimage->format,0xFE,0xFE,0xFE);
SDL_SetColorKey(optimizedimage,SDL_SRCCOLORKEY,colorkey);
}
}
return optimizedimage;
}
/**********************************************************************
* 功能描述:加載圖片、字體、音樂
* 輸入參數:無
* 輸出參數:無
* 返回值:true
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 添加tips,font2加載的內容
* 2014.11.4 V1.2 五十風 添加button_lift,button_right,button_soundon,button_soundoff加載的內容
添加MessageBox函數
***********************************************************************/
bool load_files()
{
//圖片
pipe_blank=load_image("pic/tiles.png" );
bird=load_image("pic/bird.png" );
title=load_image("pic/title.png" );
background=load_image("pic/background.png" );
button_start = load_image( "pic/start.png" );
scorepic=load_image("pic/score.png" );
highpic = load_image( "pic/high.png" );
engineer=load_image( "pic/engineer.png" );
tips=load_image( "pic/tips.png" );
button_lift=load_image( "pic/2.png" );
button_right=load_image( "pic/1.png" );
button_soundon=load_image( "pic/soundon.png" );
button_soundoff=load_image( "pic/soundoff.png" );
if(background==NULL || bird==NULL || pipe_blank==NULL || title==NULL)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-1"),TEXT("錯誤!"),MB_OK);
return false;
}
if(button_start==NULL || button_lift==NULL || button_right==NULL)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-1"),TEXT("錯誤!"),MB_OK);
return false;
}
if(scorepic==NULL )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-1"),TEXT("錯誤!"),MB_OK);
return false;
}
if(highpic==NULL )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-1"),TEXT("錯誤!"),MB_OK);
return false;
}
if(engineer==NULL )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-1"),TEXT("錯誤!"),MB_OK);
return false;
}
if(tips==NULL || button_soundoff==NULL || button_soundon==NULL)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-1"),TEXT("錯誤!"),MB_OK);
return false;
}
//聲效
pu=Mix_LoadWAV("sound/pu.wav");;
dingdong= Mix_LoadWAV("sound/dingdong.wav");
pa= Mix_LoadWAV( "sound/pa.wav" );
if( (dingdong== NULL ) || (pa == NULL )|| (pu == NULL ))
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-2"),TEXT("錯誤!"),MB_OK);
return false;
}
//字體
font = TTF_OpenFont("font/segoeprb.ttf",30);
font2 = TTF_OpenFont("font/segoeprb.ttf",15);
fontcn_tip= TTF_OpenFont(localeToUTF8("font/ygyxsziti.ttf"),15);
fontcn_easy=TTF_OpenFont(localeToUTF8("font/ygyxsziti.ttf"),25);
if( font == NULL || font2 == NULL || (fontcn_tip == NULL ) || (fontcn_easy == NULL))
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-3"),TEXT("錯誤!"),MB_OK);
return false;
}
return true;
}
/**********************************************************************
* 功能描述:加載圖片到屏幕
* 輸入參數:int x, int y, SDL_Surface* source, SDL_Surface* destination,SDL_Rect* clip
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 輸入參數增加SDL_Rect* clip
修改SDL_BlitSurface的參數
***********************************************************************/
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination,SDL_Rect* clip = NULL)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source,clip,destination,&offset);
}
/**********************************************************************
* 功能描述:釋放sdl
* 輸入參數:Tile *tiles[]
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 輸入參數增加Tile *tiles[]
增加釋放tips,font2變量
***********************************************************************/
void clean_up(Tile *tiles[])
{
//圖片
SDL_FreeSurface(background);
SDL_FreeSurface(bird);
SDL_FreeSurface(pipe_blank);
SDL_FreeSurface(first1);
SDL_FreeSurface(first2);
SDL_FreeSurface(first3);
SDL_FreeSurface(title);
SDL_FreeSurface(tips);
SDL_FreeSurface(message);
SDL_FreeSurface(thetip);
SDL_FreeSurface(thescore);
SDL_FreeSurface(thehelp);
SDL_FreeSurface(theranking);
SDL_FreeSurface(button_start);
SDL_FreeSurface(button_lift);
SDL_FreeSurface(button_right);
SDL_FreeSurface(button_soundoff);
SDL_FreeSurface(button_soundon);
for( int t = 0; t < TOTAL_TILES; t++ )
{
delete tiles[ t ];
}
//音樂
Mix_FreeChunk(dingdong);
Mix_FreeChunk(pa);
Mix_FreeChunk(pu);
Mix_CloseAudio();
//字體
TTF_CloseFont(font);
TTF_CloseFont(font2);
TTF_CloseFont(fontcn_tip);
TTF_CloseFont(fontcn_easy);
SDL_Quit();
}
/**********************************************************************
* 功能描述:檢測a,b是否方式碰撞
* 輸入參數:SDL_Rect A, SDL_Rect B
* 輸出參數:無
* 返回值:true,false
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
bool check_collision( SDL_Rect A, SDL_Rect B )
{
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
leftA = A.x;
rightA = A.x + A.w;
topA = A.y;
bottomA = A.y + A.h;
leftB = B.x;
rightB = B.x + B.w;
topB = B.y;
bottomB = B.y + B.h;
if( bottomA <= topB )
{
return false;
}
if( topA >= bottomB )
{
return false;
}
if( rightA <= leftB )
{
return false;
}
if( leftA >= rightB )
{
return false;
}
return true;
}
/**********************************************************************
* 功能描述:檢測鳥是否到達得線
* 輸入參數:SDL_Rect A
* 輸出參數:無
* 返回值:true,false
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
bool check_score(SDL_Rect A)
{
int rightA;
rightA = A.x+A.w;
if(rightA>=scoreline)
{
scoreline+=200;
return true;
}
return false;
}
/**********************************************************************
* 功能描述:剪切貼圖
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
void clip_tiles()
{
clips[ top1 ].x = 0;
clips[ top1 ].y = 207;
clips[ top1 ].w = 59;
clips[ top1 ].h = 290;
clips[ btm1 ].x = 99;
clips[ btm1 ].y = 0;
clips[ btm1 ].w = 59;
clips[ btm1 ].h = 270;
clips[ top2 ].x = 0;
clips[ top2 ].y = 327;
clips[ top2 ].w = 59;
clips[ top2 ].h = 150;
clips[ btm2 ].x = 99;
clips[ btm2 ].y = 0;
clips[ btm2 ].w = 59;
clips[ btm2 ].h = 390;
clips[ top3 ].x = 0;
clips[ top3 ].y = 87;
clips[ top3 ].w = 59;
clips[ top3 ].h = 390;
clips[ btm3 ].x = 99;
clips[ btm3 ].y = 0;
clips[ btm3 ].w = 59;
clips[ btm3 ].h = 150;
clips[ top4 ].x = 0;
clips[ top4 ].y = 117;
clips[ top4 ].w = 59;
clips[ top4 ].h = 360;
clips[ btm4 ].x = 99;
clips[ btm4 ].y = 0;
clips[ btm4 ].w = 59;
clips[ btm4 ].h = 180;
clips[ blank ].x = 198;
clips[ blank ].y = 100;
clips[ blank ].w = 59;
clips[ blank ].h = 120;
}
/**********************************************************************
* 功能描述:根據貼圖種類,返回空白盒子的y座標
* 輸入參數:int tileType
* 輸出參數:無
* 返回值:y座標
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
int tile_type(int tileType)
{
if(tileType==0)
return top1_h;
if( tileType==1)
return top2_h;
if( tileType==2)
return top3_h;
if( tileType==3)
return top4_h;
}
/**********************************************************************
* 功能描述:設置地圖
* 輸入參數:Tile *tiles[]
* 輸出參數:無
* 返回值:true,false
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.18 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 添加MessageBox函數
***********************************************************************/
bool set_tiles( Tile *tiles[] )
{
int x = 300, y = 0;
int yy;
std::ifstream map( "map.map" );
if( map == NULL )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 04-2"),TEXT("錯誤!"),MB_OK);
return false;
}
//地圖
for( int t = 0; t < TOTAL_TILES; )
{
int tileType = -1;
map >> tileType;
if( map.fail() == true )
{
map.close();
return false;
}
if( ( tileType >= 0 ) && ( tileType < TILE_SPRITES ) )
{
yy=tile_type(tileType);
tiles[ t ] = new Tile( x, y, tileType );
}
t++;
map >> tileType;
if( ( tileType >= 0 ) && ( tileType < TILE_SPRITES ) )
{
tiles[ t ] = new Tile( x, y+yy, tileType );
}
t++;
map >> tileType;
if( ( tileType >= 0 ) && ( tileType < TILE_SPRITES ) )
{
tiles[ t ] = new Tile( x, y+yy+blank_h, tileType );
}
t++;
x+=200;
}
map.close();
return true;
}
/**********************************************************************
* 功能描述:檢測是否碰到管道
* 輸入參數:SDL_Rect box, Tile *tiles[]
* 輸出參數:無
* 返回值:true,false
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
bool touches_wall( SDL_Rect box, Tile *tiles[] )
{
for( int t = 0; t < TOTAL_TILES; t++ )
{
if( ( tiles[ t ]->get_type() >= top1 ) && ( tiles[ t ]->get_type() <= btm4 ) )
{
if( check_collision( box, tiles[ t ]->get_box() ) == true )
{
type=tiles[ t ]->get_type();
return true;
}
}
}
return false;
}
/**********************************************************************
* 功能描述:根據柱子類型返回柱子的高
* 輸入參數:int type
* 輸出參數:無
* 返回值:柱子高
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
int Box_h(int type)
{
if(type==0)
return top1_h;
if( type==1)
return top2_h;
if(type==2)
return top3_h;
if(type==3)
return top4_h;
if(type==4)
return btm1_h;
if(type==5)
return btm2_h;
if(type==6)
return btm3_h;
if(type==7)
return btm4_h;
if(type==8)
return blank_h;
}
/**********************************************************************
* 功能描述:初始化貼圖類
* 輸入參數:int x, int y, int tileType
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
Tile::Tile( int x, int y, int tileType )
{
box.x = x;
box.y = y;
type = tileType;
box.w = 78;
box.h =Box_h(type);
}
/**********************************************************************
* 功能描述:根據相機位置顯示柱子
* 輸入參數:int x, int y, int tileType
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
void Tile::show()
{
if( check_collision( camera, box ) == true)
{
apply_surface( box.x - camera.x, box.y - camera.y, pipe_blank, screen, &clips[ type ] );
}
}
/**********************************************************************
* 功能描述:返回柱子類型
* 輸入參數:無
* 輸出參數:無
* 返回值:type
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
int Tile::get_type()
{
return type;
}
/**********************************************************************
* 功能描述:返回柱子的座標,寬高
* 輸入參數:無
* 輸出參數:無
* 返回值:box
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
SDL_Rect Tile::get_box()
{
return box;
}
/**********************************************************************
* 功能描述:初始化鳥的座標,寬高,x,y軸速度,相機點的座標,寬高,以及ishit=0。
* 輸入參數:無
* 輸出參數:無
* 返回值:box
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 加入對ishit的初始化
***********************************************************************/
Bird::Bird()
{
box.x=100;
box.y=300;
box.w=bird_w;
box.h=bird_h;
dotbox.x=0;
dotbox.y=0;
dotbox.w=bird_w;
dotbox.h=bird_h;
yVel =0;
xVel =3;
ishit=0;
}
/**********************************************************************
* 功能描述:根據按下的按鍵調整yVel
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 加入對ishit的賦值,按鍵被按下則ishit=1。
* 2014.11.4 V1.2 五十風 修改yVel的賦值,用於控制難度
***********************************************************************/
void Bird::handle_input()
{
ishit=0;
if( event.type == SDL_KEYDOWN )
{
if(event.key.keysym.sym ==SDLK_SPACE)
{
yVel=-16+easy;
ishit=1;
if(issound)
if( Mix_PlayChannel(-1,pu,0)==-1)
{
return;
}
}
}
else
{
if( ishit==0 )
{
yVel=10-easy;
}
}
}
/**********************************************************************
* 功能描述:根據按下的按鍵調整yVel
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 加入對ishit的判斷,等於1則yVel不做變化
* 2014.11.4 V1.2 五十風 修改ishit的判斷下的yVel的賦值,用於控制難度
* 2014.11.20 V1.2 五十風 修改碰到柱子後對box.y的調整
***********************************************************************/
void Bird::move(Tile *tiles[])
{
if( ishit==0 )
{
yVel=10-easy;
}
box.y+=yVel;
box.x+=xVel;
dotbox.x+=xVel;
if(check_score(box)==true)
{
score+=5;
if(issound)
if( Mix_PlayChannel(-1,dingdong,0)==-1)
{
return;
}
}
if( ( box.y < 0 ) || ( box.y +bird_h>screen_h)|| touches_wall( box, tiles ) )
{
if(type>=top1 && type<=top4)
box.y=clips[type].h-easy;
else
box.y=screen_h-clips[type].h-bird_h+easy;
die=true;
if(issound)
if( Mix_PlayChannel(-1,pa,0)==-1)
{
return;
}
}
if( ( box.x < 0 ) || ( box.x +bird_w>LEVEL_WIDTH) || touches_wall( box, tiles ))
{
box.x -= 3;
die=true;
if(issound)
if( Mix_PlayChannel(-1,pa,0)==-1)
{
return;
}
}
if( (dotbox.x < 0 ) || ( dotbox.x +bird_w>LEVEL_WIDTH))
{
dotbox.x -= xVel;
}
}
/**********************************************************************
* 功能描述:顯示鳥
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
void Bird::show()
{
apply_surface( box.x - camera.x, box.y - camera.y,bird,screen);
}
/**********************************************************************
* 功能描述:根據電的位置移動相機
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
void Bird::set_camera()
{
camera.x =dotbox.x;
camera.y =0;
if( camera.x < 0 )
{
camera.x = 0;
}
if( camera.x > LEVEL_WIDTH - camera.w )
{
camera.x = LEVEL_WIDTH - camera.w;
}
}
/**********************************************************************
* 功能描述:初始化按鈕盒子
* 輸入參數:SDL_Rect b
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.11.4 V1.2 五十風 加入對isdown_button的初始化
***********************************************************************/
Button::Button(SDL_Rect b)
{
isdown_button=false;
box.x = b.x;
box.y = b.y;
box.w = b.w;
box.h = b.h;
}
/**********************************************************************
* 功能描述:初始化按鈕盒子
* 輸入參數:SDL_Rect b,SDL_Surface* mybutton
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.11.4 V1.2 五十風 創建
***********************************************************************/
Button::Button(SDL_Rect b,SDL_Surface* mybutton)
{
button=mybutton;
isdown_button=false;
box.x = b.x;
box.y = b.y;
box.w = b.w;
box.h = b.h;
}
/**********************************************************************
* 功能描述:判斷是否點擊按鈕
* 輸入參數:SDL_Rect b
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.11.4 V1.2 五十風 點擊按鈕isdown_button=1
***********************************************************************/
void Button::handle_events()
{
int x = 0, y = 0;
if( event.type == SDL_MOUSEBUTTONDOWN )
{
if( event.button.button == SDL_BUTTON_LEFT )
{
x = event.button.x;
y = event.button.y;
if( ( x > box.x ) && ( x < box.x + box.w ) && ( y > box.y ) && ( y < box.y + box.h ) )
{
isdown_button=true;
}
}
}
}
/**********************************************************************
* 功能描述:顯示按鈕
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
void Button::show()
{
apply_surface(box.x, box.y,button,screen);
}
/**********************************************************************
* 功能描述:加載遊戲
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
bool load()
{
if(init()==false )
{
return false;
}
if( load_files() == false )
{
return false;
}
clip_tiles();
return true;
}
/**********************************************************************
* 功能描述:滾動背景
* 輸入參數:無
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
***********************************************************************/
void ScrollingBackground()
{
bgX -= 4;
if( bgX <= -background->w )
{
bgX = 0;
}
apply_surface( bgX, bgY, background, screen );
apply_surface( bgX + background->w, bgY, background, screen );
}
/**********************************************************************
* 功能描述:首次運行顯示操作提示
* 輸入參數:無
* 輸出參數:無
* 返回值:true false
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.30 V1.1 五十風 創建
* 2014.11.4 V1.2 五十風 修改函數名,增加了圖片提示的顯示,增加了highest文件的修改
***********************************************************************/
bool firsttime()
{
int t=0;
std::ifstream fin( "highest.dat" );
if( fin == NULL )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 04-3"),TEXT("錯誤!"),MB_OK);
return false;
}
int t1,t2,t3,t4;
fin>>t1;
fin>>t2;
fin>>t3;
fin>>t4;
fin.clear();
fin.close();
std::ofstream fout("highest.dat");
if( fout == NULL )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 04-3"),TEXT("錯誤!"),MB_OK);
return false;
}
fout<<t1;
fout<<" ";
fout<<t2;
fout<<" ";
fout<<t3;
fout<<" ";
fout<<1;
fout<<" ";
fout.clear();
fout.close();
if(t4==0)
{
first1=IMG_Load("pic/first1.png" );
first2=IMG_Load("pic/first2.png" );
first3=IMG_Load("pic/first3.png" );
if(first3==NULL )
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 03-1"),TEXT("錯誤!"),MB_OK);
return false;
}
while(1)
{
if( SDL_PollEvent( &event ))
{
if( event.type == SDL_MOUSEBUTTONDOWN )
if( event.button.
button == SDL_BUTTON_LEFT )
t++;
if( event.type == SDL_QUIT )
return false;
}
if(t==0)
apply_surface(0,0,first1,screen);
if(t==1)
apply_surface(0,0,first2,screen);
if(t==2)
apply_surface(0,0,first3,screen);
if(t==3)
return true;
if( SDL_Flip(screen)==-1)//更新
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 05"),TEXT("錯誤!"),MB_OK);
return false;
}
SDL_Delay(30);
}
}
return true;
}
/**********************************************************************
* 功能描述:菜單
* 輸入參數:無
* 輸出參數:無
* 返回值:true false
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.11.4 V1.2 五十風 增加新添按鈕的顯示,增加MessageBox函數
***********************************************************************/
bool menu()
{
bgX = 0;
bgY = 0;
while(start==false)
{
startTicks = SDL_GetTicks();
ScrollingBackground();
Button start_button(startbox,button_start);
Button lift_button(liftbox,button_lift);
Button right_button(rightbox,button_right);
Button soundon_button(soundbox,button_soundon);
Button soundoff_button(soundbox,button_soundoff);
Button help_button(helpbox);
Button ranking_button(rankingbox);
start_button.show();
lift_button.show();
right_button.show();
if(issound)
soundon_button.show();
else
soundoff_button.show();
apply_surface(170,150,title,screen);
apply_surface(440,618,engineer,screen);
if(iseasy==false)
theeasy=TTF_RenderUTF8_Solid(fontcn_easy,localeToUTF8("困難"),textColor);
else
theeasy=TTF_RenderUTF8_Solid(fontcn_easy,localeToUTF8("簡單"),textColor);
thehelp=TTF_RenderUTF8_Solid(fontcn_easy,localeToUTF8("說明"),textColor);
theranking=TTF_RenderUTF8_Solid(fontcn_easy,localeToUTF8("高分榜"),textColor);
apply_surface(240,310,theeasy,screen);
apply_surface(150,500,thehelp,screen);
apply_surface(320,500,theranking,screen);
if( SDL_Flip(screen)==-1)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 05"),TEXT("錯誤!"),MB_OK);
return true;
}
startTicks = SDL_GetTicks()-startTicks;
if( startTicks< 1000 / FRAMES_PER_SECOND )
{
SDL_Delay(( 1000 / FRAMES_PER_SECOND ) -startTicks);
}
if( SDL_PollEvent( &event ) )
{
start_button.handle_events();
lift_button.handle_events();
right_button.handle_events();
help_button.handle_events();
ranking_button.handle_events();
if(issound)
soundon_button.handle_events();
else
soundoff_button.handle_events();
if(start_button.isdown_button==true)
start=true;
if(lift_button.isdown_button==true || right_button.isdown_button==true)
iseasy=!iseasy;
if(soundon_button.isdown_button==true || soundoff_button.isdown_button==true)
issound=!issound;
if(help_button.isdown_button==true)
ShellExecute(NULL,"open","說明.txt",NULL,NULL,SW_SHOW);
if(ranking_button.isdown_button==true)
{
ShellExecute(NULL,"open","高分榜.txt",NULL,NULL,SW_SHOW);
}
if( event.type == SDL_QUIT )
{
return true;
}
}
}
bgX = 0;
bgY = 0;
return false;
}
/**********************************************************************
* 功能描述:更新最高分榜
* 輸入參數:int a,int b
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.11.4 V1.2 五十風 創建
***********************************************************************/
void updateranking(int a,int b)
{
std::ofstream fout( "高分榜.txt" );
fout<<"第一名";
fout<<" ";
fout<<score;
fout<<"\n";
fout<<"第二名";
fout<<" ";
fout<<a;
fout<<"\n";
fout<<"第三名";
fout<<" ";
fout<<b;
fout<<"\n";
fout.close();
}
/**********************************************************************
* 功能描述:死亡後計算得分,並顯示得分界面
* 輸入參數:int t
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 加入圖片tips的顯示
* 2014.11.4 V1.2 五十風 加入新加文字的顯示,
加入p鍵截圖功能,
更改highest文件的讀取修改內容
加入updateranking函數
***********************************************************************/
void Score(int t)
{
// int b=-1;
std::stringstream s;
s<<score;
if(t==0)
{
std::ifstream fin( "highest.dat" );
if( fin == NULL)
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 04-3"),TEXT("錯誤!"),MB_OK);
return;
}
fin>>scorea;
fin>>scoreb;
fin.close();
}
if(scorea<score)
{
if(t==0)
{
std::ofstream fout( "highest.dat" );
fout<<score;
fout<<" ";
fout<<scorea;
fout<<" ";
fout<<scoreb;
fout<<" ";
fout<<1;
fout<<" ";
fout.close();
}
apply_surface(120,200,highpic,screen);
updateranking(scorea,scoreb);
}
else
{
apply_surface(120,200,scorepic,screen);
}
apply_surface(96,380,tips,screen);
message= TTF_RenderText_Solid( font, s.str().c_str(), textColor );
thetip= TTF_RenderUTF8_Solid(fontcn_tip,localeToUTF8("小提示: 按住“空格”可以一直上升"),textColor2);
apply_surface(240,290,message,screen);
apply_surface(0,0,thetip,screen);
}
/**********************************************************************
* 功能描述:更新最高分榜
* 輸入參數:Bird mybird,Tile *tiles[TOTAL_TILES]
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.10.30 V1.1 五十風 修改mybird.move(tiles);
加入mybird.set_camera()函數
* 2014.11.4 V1.2 五十風 加入對iseasy的判斷,用於難度控制
***********************************************************************/
void play(Bird mybird,Tile *tiles[ TOTAL_TILES ])
{
if(iseasy)
easy=3;
else
easy=1;
builtmap();
if( set_tiles(tiles)==false)
{
return ;
}
while(die==false)
{
while(SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
{
quit=true;
return;
}
mybird.handle_input();
}
ScrollingBackground();
mybird.move(tiles);
mybird.set_camera();
for( int t = 0; t < TOTAL_TILES; t++ )
{
tiles[ t ]->show();
}
mybird.show();
std::stringstream s;
s<<"scores: "<<score;
thescore=TTF_RenderText_Solid(font2,s.str().c_str(),textColor2);
apply_surface(460,0,thescore,screen);
if( SDL_Flip(screen)==-1)//更新
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 05"),TEXT("錯誤!"),MB_OK);
return;
}
SDL_Delay(35);
}
}
/**********************************************************************
* 功能描述:更新最高分榜
* 輸入參數:Bird mybird,Tile *tiles[TOTAL_TILES]
* 輸出參數:無
* 返回值:無
* 其它說明:無
* 修改日期 版本號 修改人 修改內容
*--------------------------------------------------------------------
* 2014.10.19 V1.0 五十風 創建
* 2014.11.4 V1.2 五十風 去除temp變量,加入對scorea,scoreb的賦值
***********************************************************************/
void Die()
{
bgX = 0;
bgY = 0;
int t;
t=0;
scorea=scoreb=-1;
while(die==true)
{
ScrollingBackground();
Score(t);
while(SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
{
quit=true;
return;
}
if( event.type == SDL_KEYDOWN )
{
if(event.key.keysym.sym==SDLK_r)
{
die=false;
}
if(event.key.keysym.sym==SDLK_ESCAPE)
{
start=false;
showmenu=true;
die=false;
}
if(event.key.keysym.sym==SDLK_p)
{
SDL_SaveBMP(screen,"SavePic.bmp") ;
MessageBox(NULL,TEXT("圖片已保存到遊戲目錄"),TEXT("保存成功"),MB_OK);
}
}
}
if( SDL_Flip(screen)==-1)//更新
{
MessageBox(NULL,TEXT("糟糕,遊戲發生了錯誤。\n錯誤: 05"),TEXT("錯誤!"),MB_OK);
return;
}
SDL_Delay(35);
t=1;
}
}
---------------------------------------
工程文件下載:點擊打開鏈接
(代碼是用vc6.0編譯的)