大家好 , 我是逼哥 , 記得每天好好學習 , 天天向上 , 尤其是大學生 . 不要荒廢學業.
首先說明 , 我使用的開發環境是 vs2017 , 有些函數方法可能不通用 ,大家可以百度下其他方法. 向童老師致敬
第一步:先讀取本地的背景圖片
1 . 這第一步就非常簡單 , 只需要先讀取背景圖 , 並且顯示出來就可以.
#include <graphics.h>
#include <conio.h>
void main()
{
initgraph(350,600);
IMAGE bird_bg; // 小鳥圖片背景
loadimage(&bird_bg , _T("D:\\桌面\\super_bird\\background.jpg") );
putimage(0, 0, &bird_bg); // 在座標(0 , 0 )位置顯示IMAGE 對象
_getch(); //防止窗口關閉
closegraph();
}
2 . 處理小鳥
如果直接顯示小鳥
因爲我們顯示的小鳥圖片是矩形 , 這樣的小鳥是留有白色區域棱角就不好看了 ,此時就需要用函數去處理 , 是白色區域透明化
拿到小鳥的遮罩和原圖
可以利用美圖秀秀進行摳圖 ,扣出原圖和遮罩.
NOTSRCERASE 先對遮罩進行處理 , 使得遮罩白色變黑 ,黑色區域變透明
SRCINVERT 在對小鳥原圖處理
一定要遮罩在前 ,作爲背景 , 小鳥在後
讓兩張處理過的圖片在同一區域進行效果疊加 , 看小效果
#include <graphics.h>
#include <conio.h>
void main()
{
initgraph(350,600);
IMAGE bird_bg; // 小鳥圖片背景
loadimage(&bird_bg , _T("D:\\桌面\\super_bird\\background.jpg") );
putimage(0, 0, &bird_bg); // 在座標(0 , 0 )位置顯示IMAGE 對象
IMAGE im_bird_shade; //遮罩
IMAGE im_bird;
loadimage(&im_bird_shade, _T("D:\\桌面\\super_bird\\bird1.jpg"));
loadimage(&im_bird, _T("D:\\桌面\\super_bird\\bird2.jpg"));
// 一定要遮罩在前 ,作爲背景 , 小鳥在後
putimage(100, 200, &im_bird_shade, NOTSRCERASE); //NOTSRCERASE -->目標圖像 = NOT (目標圖像 OR 源圖像) //遮罩的黑色進行透明處理 , 白色區域顯黑色
putimage(100, 200, &im_bird , SRCINVERT); //SRCINVERT---> 目標圖像 = 目標圖像 XOR 源圖像 (三原色進行系列取反運算)
_getch(); //防止窗口關閉
closegraph(); //
}
版本升級處理 , 對 顯示數據 進行 模塊化 , 用函數來封裝 . 修改後的代碼.
#include <graphics.h>
#include <conio.h>
// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")
//全局變量
IMAGE img_bk, img_bd1, img_bd2, img_bar_up1, img_bar_up2, img_bar_down1, img_bar_down2; int bird_x;
int bird_y;
void startup()
{
initgraph(350, 600);
loadimage(&img_bk, _T("D:\\桌面\\super_bird\\background.jpg") );
loadimage(&img_bd1, _T("D:\\桌面\\super_bird\\bird1.jpg"));
loadimage(&img_bd2, _T("D:\\桌面\\super_bird\\bird2.jpg"));
bird_x = 50;
bird_y = 200;
BeginBatchDraw();
}
void show()
{
putimage(0, 0, &img_bk); // 顯示背景
putimage(bird_x, bird_y, &img_bd1, NOTSRCERASE); // 遮罩透明處理
putimage(bird_x, bird_y, &img_bd2, SRCINVERT);// 顯示小鳥
FlushBatchDraw();
Sleep(50);
}
void updateWithoutInput()
{
}
void updateWithInput()
{
}
void gameover()
{
EndBatchDraw();
_getch();
closegraph();
}
int main()
{
startup(); // 數據初始化
while (1) // 遊戲循環執行
{
show(); // 顯示畫面
updateWithoutInput(); // 與用戶輸入無關的更新
updateWithInput(); // 與用戶輸入有關的更新
}
gameover(); // 遊戲結束、後續處理
return 0;
}
第三步: 顯示障礙物 ,並且讓小鳥自由下落
1. 障礙物 ,和處理小鳥一致 , 只要讀取圖片 , 處理遮罩 , 處理障礙物原圖 , 疊加顯示即可
2. 小鳥自由下落 , 就是 改變 小鳥圖片的左上角的起始繪畫點的座標. 只能上下自自由下落 ,改變小鳥的Y軸座標即可 .
3. 移動障礙物
4.障礙物 隨機生成 , 並且隨機高度
5.小鳥越過障礙物 , 並計算得分 , 撞上柱子則死亡
看下效果
最後, 貼出所有的代碼 , 環境是 : VS2017
#include <graphics.h>
#include <conio.h>
// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")
#define width 350
#define high 600
//全局變量
IMAGE img_bk, img_bd1, img_bd2, img_bar_up1, img_bar_up2, img_bar_down1, img_bar_down2;
int bird_x , bird_y;
int bar1_x, bar1_xDown, bar1_xTop; // 障礙物1的相關座標
int score; // 得分,經過障礙物的個數
void startup()
{
initgraph(width, high);
loadimage(&img_bk, _T("D:\\桌面\\super_bird\\background.jpg") );
loadimage(&img_bd1, _T("D:\\桌面\\super_bird\\bird1.jpg"));
loadimage(&img_bd2, _T("D:\\桌面\\super_bird\\bird2.jpg"));
//顯示上下障礙物
loadimage(&img_bar_up1, _T("D:\\桌面\\super_bird\\bar_up1.gif"));
loadimage(&img_bar_up2, _T("D:\\桌面\\super_bird\\bar_up2.gif"));
loadimage(&img_bar_down1, _T("D:\\桌面\\super_bird\\bar_down1.gif"));
loadimage(&img_bar_down2, _T("D:\\桌面\\super_bird\\bar_down2.gif"));
//小鳥
bird_x = width / 7; // 50
bird_y = high / 3; //200
score = 0;
//障礙物
bar1_x = width;
int randPosition = rand() % (high - 400) +50; // 隨機數就只在 50-250
//注意這是上障礙物的起始座標
bar1_xTop = randPosition - high; // top 的範圍就在 -550 ------ -350 之間
// 上障礙物畫完 , 畫下障礙物 , 間隔100
bar1_xDown = bar1_xTop +high + 100;
BeginBatchDraw();
}
void show()
{
putimage(0, 0, &img_bk); // 顯示背景
putimage(bird_x, bird_y, &img_bd1, NOTSRCERASE); // 遮罩透明處理
putimage(bird_x, bird_y, &img_bd2, SRCINVERT);// 顯示小鳥
//顯示 障礙物
putimage(bar1_x, bar1_xTop, &img_bar_up1, NOTSRCERASE); // 遮罩透明處理
putimage(bar1_x, bar1_xTop, &img_bar_up2, SRCINVERT);// 顯示上障礙物
putimage(bar1_x, bar1_xDown, &img_bar_down1, NOTSRCERASE); // 遮罩透明處理
putimage(bar1_x, bar1_xDown, &img_bar_down2, SRCINVERT);// 顯示下障礙物
FlushBatchDraw();
Sleep(50);
}
void updateWithoutInput()
{
// 輸入空格進行控制小鳥
char input;
if (_kbhit())
{
input = _getch();
if (input == ' ' && bird_y > 20)
bird_y -= 25;
}
}
// 圖形更新
void updateWithInput()
{
// 小鳥不能飛出界面
if (bird_y < 0 || bird_y > 556)
_exit(0); // 結束
// 小鳥的座標不能出框 , Y軸不能小於0 , 不能大於580
if (0 < bird_y && bird_y < 580)
bird_y += 3;
// 障礙物的移動
if (bar1_x > -140)
bar1_x -= 2;
else
{
// 重新生成
bar1_x = width;
//障礙物
int randPosition = rand() % (high - 400) + 50; // 隨機數就只在 50-250
//注意這是上障礙物的起始座標
bar1_xTop = randPosition - high; // top 的範圍就在 -550 ------ -350 之間
// 上障礙物畫完 , 畫下障礙物 , 間隔100
bar1_xDown = bar1_xTop + high + 100;
}
//得分計算 小鳥的寬度爲34 , 柱子寬度爲140
if ( (bar1_x < bird_x + 34) && (bar1_x +140 > bird_x + 34) )
{
if ((bird_y > bar1_xTop +600) && (bird_y < bar1_xDown))
{
score++;
}
else
{
_exit(0);
}
}
}
void gameover()
{
EndBatchDraw();
_getch();
closegraph();
}
int main()
{
startup(); // 數據初始化
while (1) // 遊戲循環執行
{
show(); // 顯示畫面
updateWithoutInput(); // 界面的更新
updateWithInput(); // 與用戶輸入有關的更新
}
gameover(); // 遊戲結束、後續處理
return 0;
}
到這裏,我們可以配上音樂
可以引用 Windows Multimedia API
使用 #pragma comment(lib,"Winmm.lib")
#include <graphics.h>
#include <conio.h>
// 引用 Windows Multimedia API
#pragma comment(lib,"Winmm.lib")
#define width 350
#define high 600
//全局變量
IMAGE img_bk, img_bd1, img_bd2, img_bar_up1, img_bar_up2, img_bar_down1, img_bar_down2;
int bird_x , bird_y;
int bar1_x, bar1_xDown, bar1_xTop; // 障礙物1的相關座標
int score; // 得分,經過障礙物的個數
void startup()
{
initgraph(width, high);
loadimage(&img_bk, _T("D:\\桌面\\super_bird\\background.jpg") );
loadimage(&img_bd1, _T("D:\\桌面\\super_bird\\bird1.jpg"));
loadimage(&img_bd2, _T("D:\\桌面\\super_bird\\bird2.jpg"));
//顯示上下障礙物
loadimage(&img_bar_up1, _T("D:\\桌面\\super_bird\\bar_up1.gif"));
loadimage(&img_bar_up2, _T("D:\\桌面\\super_bird\\bar_up2.gif"));
loadimage(&img_bar_down1, _T("D:\\桌面\\super_bird\\bar_down1.gif"));
loadimage(&img_bar_down2, _T("D:\\桌面\\super_bird\\bar_down2.gif"));
//小鳥
bird_x = width / 7; // 50
bird_y = high / 3; //200
score = 0;
//障礙物
bar1_x = width;
int randPosition = rand() % (high - 400) +50; // 隨機數就只在 50-250
//注意這是上障礙物的起始座標
bar1_xTop = randPosition - high; // top 的範圍就在 -550 ------ -350 之間
// 上障礙物畫完 , 畫下障礙物 , 間隔100
bar1_xDown = bar1_xTop +high + 100;
BeginBatchDraw();
mciSendString(_T("open D:\\桌面\\super_bird\\background.mp3 alias bkmusic"), NULL, 0, NULL);//打開背景音樂
mciSendString(_T("play bkmusic repeat"), NULL, 0, NULL); // 循環播放
}
void show()
{
putimage(0, 0, &img_bk); // 顯示背景
putimage(bird_x, bird_y, &img_bd1, NOTSRCERASE); // 遮罩透明處理
putimage(bird_x, bird_y, &img_bd2, SRCINVERT);// 顯示小鳥
//顯示 障礙物
putimage(bar1_x, bar1_xTop, &img_bar_up1, NOTSRCERASE); // 遮罩透明處理
putimage(bar1_x, bar1_xTop, &img_bar_up2, SRCINVERT);// 顯示上障礙物
putimage(bar1_x, bar1_xDown, &img_bar_down1, NOTSRCERASE); // 遮罩透明處理
putimage(bar1_x, bar1_xDown, &img_bar_down2, SRCINVERT);// 顯示下障礙物
FlushBatchDraw();
Sleep(50);
}
void updateWithoutInput()
{
// 輸入空格進行控制小鳥
char input;
if (_kbhit())
{
input = _getch();
if (input == ' ' && bird_y > 20)
{
bird_y -= 25;
mciSendString(_T("close jpmusic"), NULL, 0, NULL); // 先把前面一次的音樂關閉
mciSendString(_T("open D:\\Jump.mp3 alias jpmusic"), NULL, 0, NULL);// 打開跳動音樂
mciSendString(_T("play jpmusic"), NULL, 0, NULL); // 僅播放一次
}
}
}
// 圖形更新
void updateWithInput()
{
// 小鳥不能飛出界面
if (bird_y < 0 || bird_y > 556)
_exit(0); // 結束
// 小鳥的座標不能出框 , Y軸不能小於0 , 不能大於580
if (0 < bird_y && bird_y < 580)
bird_y += 3;
// 障礙物的移動
if (bar1_x > -140)
bar1_x -= 2;
else
{
// 重新生成
bar1_x = width;
//障礙物
int randPosition = rand() % (high - 400) + 50; // 隨機數就只在 50-250
//注意這是上障礙物的起始座標
bar1_xTop = randPosition - high; // top 的範圍就在 -550 ------ -350 之間
// 上障礙物畫完 , 畫下障礙物 , 間隔100
bar1_xDown = bar1_xTop + high + 100;
}
//得分計算 小鳥的寬度爲34 , 柱子寬度爲140
if ( (bar1_x < bird_x + 34) && (bar1_x +140 > bird_x + 34) )
{
if ((bird_y > bar1_xTop +600) && (bird_y < bar1_xDown))
{
score++;
}
else
{
_exit(0);
}
}
}
void gameover()
{
EndBatchDraw();
_getch();
closegraph();
}
int main()
{
startup(); // 數據初始化
while (1) // 遊戲循環執行
{
show(); // 顯示畫面
updateWithoutInput(); // 界面的更新
updateWithInput(); // 與用戶輸入有關的更新
}
gameover(); // 遊戲結束、後續處理
return 0;
}
好了 , 到此結束 . 大家記得每天提醒自己 , 好好學習 , 天天向上