色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言小游戲:飛翔的小鳥(完整版)

C語言編程學習基地 ? 來源:C語言編程學習基地 ? 2023-02-02 16:22 ? 次閱讀

每天一個C語言小項目,提升你的編程能力!

《Flappy Bird》是曾經一款流行的一款手機游戲,你只要讓小鳥保持飛行,不要碰到綠色的管道就可以啦。操作雖然簡單,但是非常具有挑戰!本次我們也是自己動手來實現這樣一款游戲的高仿版,大家不妨自己先讀一遍代碼然后動手試試!

ebdc74aa-a2cc-11ed-bfe3-dac502259ad0.png

該程序是用 C 語言實現的 FlappyBird 的電腦版,玩法和手機版的相同。

程序通過 alpha 域實現透明貼圖,并且通過雙緩沖繪圖防止刷新閃屏。

程序執行效果如下:

ec060892-a2cc-11ed-bfe3-dac502259ad0.png

本程序設計了三種不同顏色的小鳥(可以實現三人對戰)另外也有白天模式和夜晚模式,不同模式和不同小鳥是在上次死亡后隨機刷新,避免產生視覺疲勞。

簡單了解游戲后我們就來試試吧!

本項目編譯環境:Visual Studio 2019/2022,EasyX插件

必備素材:

ec1f8240-a2cc-11ed-bfe3-dac502259ad0.png

網盤鏈接:https://pan.baidu.com/s/10ALP-QdcTu0UV4p8alTE4w?pwd=3p3s 提取碼:3p3s

代碼展示:(有五百多行代碼,每一個功能實現都會給出對應注釋)

#include 
#include 
#include 
#include 
#include 
#include 


// 初始背景圖 白天、黑夜
IMAGE BK[2];


// 全局畫板
IMAGE bk;


// 飛鳥資源 橘、藍、紅
IMAGE BIRD[3][3];


// 管道資源 綠、紅
IMAGE PIPE[2][2];


// 三種數字字體
IMAGE NUMBER[3][10];


// 獎牌資源
IMAGE MEDAL[4];


// 地面資源
IMAGE LAND;


// 開始游戲按鈕
IMAGE PLAY;


// 得分面板
IMAGE PANEL;


// 以下為五種游戲文字
// 游戲結束 游戲預備 游戲標題 游戲提示 最高分
IMAGE OVER;
IMAGE READY;
IMAGE TITLE;
IMAGE TUTORIAL;
IMAGE NEW;


// 結束時狀態
IMAGE OVEIMG;


// 是否為白天
int isDay = 0;


// 鳥的顏色
int birdColor = 0;


// 最高分
int best = 0;


// 游戲初始時間
long startTime = 0;


// 游戲基本屬性


// 重力加速度
const double g = 6.5;
// 管道的移動速度
double vx = 11;
// 鳥的下落速度
double vy = 10;
// 鳥的當前位置
double y = 220;
const double x = 288 / 2 - (41 + 8) / 2 - 80;
// 管道的橫向坐標
double pipeX[2];
// 管道的縱向坐標
int pipeY[2];
// 當前得分
int score;
// 鳥的矩形判斷區域
const int top = 12;
const int left = 10;
const int right = 37;
const int buttom = 33;


// 獎牌顯示位置
const int medalXY[2] = { 0, 0 };


// 陸地坐標
const double landY = 420;
double landX = -20;


// 飛鳥姿態
int pose = 0;


// 飛行間隔
const int diff = 110;


// 管道上補償
const int pipeUp = -280;
// 管道下補償
const int pipeDown = 140;


// 游戲預處理
void start();
// 游戲函數
void game();
// 結束游戲函數
void end();
// 移動函數
void move(long time);
// 繪制函數
void draw();
// 重置畫布
void reset();
// 繪制畫布
void put();
// 加載資源
void loadRes();
// 根據透明度繪圖
void drawAlpha(IMAGE* dstimg, int x, int y, IMAGE* srcimg);
// 繪制分數
void drawScore(int y, int sc, int dif, int se, int st, int type);
// 繪制管道
void drawPipe();
// 判斷鳥死亡
bool isDie();
// 初始化游戲資源
void init();




int main()
{
  // 游戲開局頁面
  init();
  while (true)
  {
    // 游戲初始化
    start();
    // 游戲進行
    game();
    // 顯示得分
    end();
  }
  return 0;
}




bool GetControl() 
{
  bool res = false;


  if (_kbhit()) 
  {
    char ch = _getch();
    if (ch == ' ') 
    {
      res = true;
    }
  }


  MOUSEMSG msg;
  while (MouseHit()) 
  {
    msg = GetMouseMsg();
    if (msg.mkLButton) 
    {
      res = true;
    }
  }


  return res;
}




// 游戲預處理
void start()
{
  // 初始化數據
  isDay = rand() % 2;
  birdColor = rand() % 3;
  pipeX[0] = 288 + 30;
  pipeX[1] = 288 + 30 + 190;
  pipeY[0] = rand() % 250;
  pipeY[1] = rand() % 250;
  pose = 0;
  landX = 0;
  score = 0;
  y = 220;
  vy = 0;


  // 游戲初始時間
  clock_t time = clock();
  // 開場動畫
  clock_t t = clock();
  while (true)
  {
    reset();
    drawScore(60, score, 13, 26, 144, 0);
    drawAlpha(&bk, 50, 120, &READY);
    drawAlpha(&bk, (int)x, (int)y, &BIRD[birdColor][pose]);
    drawAlpha(&bk, 90, 220, &TUTORIAL);
    drawAlpha(&bk, (int)landX, (int)landY, &LAND);
    landX -= (clock() - t) * vx / 100;
    t = clock();
    pose = ((clock() - time) / diff) % 3;
    put();
    if (landX < -44)
    {
      landX = -20;
    }
    if (GetControl())
    {
      break;
    }
    Sleep(10);
  }
}




// 游戲函數
void game()
{
  // 根據毫秒
  startTime = clock();
  long time = clock();
  while (!isDie())
  {
    // 移動
    move(clock() - time);
    time = clock();
    // 控制
    if (GetControl())
    {
      vy = -26;
    }
    // 繪制
    draw();
    Sleep(10);
  }


  startTime = clock();
  while (clock() - startTime < 1000);
  vy = -30;
  time = clock();
  while (y < 520)
  {
    y += (clock() - time) * vy / 100;
    vy += g * (clock() - time) / 100;
    time = clock();
    draw();
    Sleep(10);
  }


  // 備份此時圖片
  drawAlpha(&OVEIMG, 0, 0, &bk);
}




void flush()
{
  while (MouseHit())
    GetMouseMsg();


  while (_kbhit())
    _getch();
}




// 結束函數
void end()
{
  // 將面板移出
  startTime = clock();
  // 重置畫板
  reset();
  // 面板從下方移出
  drawPipe();
  drawAlpha(&bk, (int)landX, (int)landY, &LAND);
  drawAlpha(&bk, 0, 0, &OVEIMG);
  drawAlpha(&bk, 25, 150, &PANEL);
  // 根據評分打印獎牌
  int r = (score - 50) / 50;
  if (score > 50)
  {
    if (r > 3)
    {
      r = 3;
    }
    drawAlpha(&bk, 57, 195, &MEDAL[r]);
  }
  // 打印當前分
  drawScore(189, score, 16, 16, 240, 2);
  // 寫最高分
  int tmp = best;
  if (best < score)
  {
    best = score;
  }
  // 打印最高分
  drawScore(231, best, 16, 16, 240, 2);


  // 如果當前分超過最高分 則顯示新分數圖標
  if (tmp < score)
  {
    drawAlpha(&bk, 165, 210, &NEW);
  }
  flush();
  put();
  while (true)
  {
    if (GetControl())
    {
      break;
    }
    Sleep(10);
  }
}




void drawScore(int y, int sc, int dif, int se, int st, int type)
{
  // 將分數居中顯示
  int t = sc;
  int num[8];
  int length = 0;
  do
  {
    num[length] = t % 10;
    length++;
    t /= 10;
  } while (t != 0);


  // 計算出起始坐標
  int s = st - dif * length;
  for (int i = length - 1; i >= 0; i--)
  {
    drawAlpha(&bk, s, y, &NUMBER[type][num[i]]);
    s += se;
  }
}




// 管道、主角、地面移動
void move(long time)
{
  y += time * vy / 100;
  vy += g * time / 100;
  pipeX[0] -= time * vx / 100;
  pipeX[1] -= time * vx / 100;
  landX -= time * vx / 100;
  pose = ((clock() - startTime) / diff) % 3;
  if (landX < -44)
  {
    landX = -20;
  }
  if (pipeX[0] < -52)
  {
    pipeX[0] = pipeX[1] + 190;
    pipeY[0] = rand() % 250;
  }
  if (pipeX[1] < -52)
  {
    pipeX[1] = pipeX[0] + 190;
    pipeY[1] = rand() % 250;
  }
  if (y < 0 - top)
  {
    y = -top;
  }
  score = (int)(((clock() - startTime) * vx / 100 - (288 - x + 30)) / 190 + 1);
  if (score < 0)
  {
    score = 0;
  }
}




void draw()
{
  // 初始化背景圖
  drawAlpha(&bk, 0, 0, &BK[isDay]);
  // 畫管道
  drawPipe();
  // 畫陸地
  drawAlpha(&bk, (int)landX, (int)landY, &LAND);
  // 畫鳥
  drawAlpha(&bk, (int)x, (int)y, &BIRD[birdColor][pose]);
  // 畫分數
  drawScore(60, score, 13, 26, 144, 0);
  // 將背景畫到窗口上
  put();
}




// 根據透明度繪圖
void drawAlpha(IMAGE* dstimg, int x, int y, IMAGE* srcimg)
{
  if (dstimg == NULL)
  {
    return;
  }
  // 變量初始化
  DWORD *dst = GetImageBuffer(dstimg);
  DWORD *src = GetImageBuffer(srcimg);
  int src_width = srcimg->getwidth();
  int src_height = srcimg->getheight();
  int dst_width = dstimg->getwidth();
  int dst_height = dstimg->getheight();


  // 實現透明貼圖  可優化
  for (int iy = 0; iy < src_height; iy++)
  {
    for (int ix = 0; ix < src_width; ix++)
    {
      int srcX = ix + iy * src_width;
      int sa = ((src[srcX] & 0xff000000) >> 24);
      int sr = ((src[srcX] & 0xff0000) >> 16);
      int sg = ((src[srcX] & 0xff00) >> 8);
      int sb = src[srcX] & 0xff;
      if (x + ix >= 0 && x + ix < dst_width
        && y + iy >= 0 && y + iy < dst_height)
      {
        int dstX = (x + ix) + (y + iy) * dst_width;
        int dr = ((dst[dstX] & 0xff0000) >> 16);
        int dg = ((dst[dstX] & 0xff00) >> 8);
        int db = dst[dstX] & 0xff;
        dst[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16)
              | ((sg * sa / 255 + dg * (255 - sa) / 255) << 8)
              |  (sb * sa / 255 + db * (255 - sa) / 255);
      }
    }
  }
}




void drawPipe()
{
  // 畫管道
  drawAlpha(&bk, (int)pipeX[0], pipeY[0] + pipeUp, &PIPE[isDay][0]);
  drawAlpha(&bk, (int)pipeX[0], pipeY[0] + pipeDown, &PIPE[isDay][1]);
  // 畫管道
  drawAlpha(&bk, (int)pipeX[1], pipeY[1] + pipeUp, &PIPE[isDay][0]);
  drawAlpha(&bk, (int)pipeX[1], pipeY[1] + pipeDown, &PIPE[isDay][1]);
}




// 判斷鳥死亡
bool isDie()
{
  if (y + buttom > landY)
    return true;


  if (x + right > pipeX[0] && x + left < pipeX[0] + 52)
  {
    if (y + top < pipeY[0] + 40 || y + buttom > pipeY[0] + 140)
      return true;
  }


  if (x + right > pipeX[1] && x + left < pipeX[1] + 52)
  {
    if (y + top < pipeY[1] + 40 || y + buttom > pipeY[1] + 140)
      return true;
  }


  return false;
}




void reset()
{
  drawAlpha(&bk, 0, 0, &BK[isDay]);
}




void put()
{
  putimage(0, 0, &bk);
}




// 初始化游戲資源
void init()
{
  // 加載圖形資源
  loadRes();
  // 初始化圖形界面
  initgraph(288, 512);
  // 初始化隨機數種子
  srand((unsigned int)time(NULL));
  // 初始化變量
  best = 0;
  isDay = rand() % 2;
  birdColor = rand() % 3;
  // 游戲初始時間
  clock_t time = clock();
  // 開場動畫
  while (true)
  {
    reset();
    drawAlpha(&bk, 60, 120, &TITLE);
    drawAlpha(&bk, 125, 200, &BIRD[birdColor][pose]);
    drawAlpha(&bk, 90, 270, &PLAY);
    pose = ((clock() - time) / diff) % 3;
    put();
    if (GetControl())
    {
      break;
    }
    Sleep(10);
  }
}




// 加載圖片資源
void loadRes()
{
  loadimage(&BK[0], _T("res\bg_day.png"));
  loadimage(&BK[1], _T("res\bg_night.png"));
  loadimage(&bk, _T("res\bg_day.png"));
  loadimage(&OVEIMG, _T("res\bg_day.png"));


  loadimage(&BIRD[0][0], _T("res\bird0_0.png"));
  loadimage(&BIRD[0][1], _T("res\bird0_1.png"));
  loadimage(&BIRD[0][2], _T("res\bird0_2.png"));
  loadimage(&BIRD[1][0], _T("res\bird1_0.png"));
  loadimage(&BIRD[1][1], _T("res\bird1_1.png"));
  loadimage(&BIRD[1][2], _T("res\bird1_2.png"));
  loadimage(&BIRD[2][0], _T("res\bird2_0.png"));
  loadimage(&BIRD[2][1], _T("res\bird2_1.png"));
  loadimage(&BIRD[2][2], _T("res\bird2_2.png"));


  loadimage(&PIPE[0][0], _T("res\pipe_down.png"));
  loadimage(&PIPE[0][1], _T("res\pipe_up.png"));
  loadimage(&PIPE[1][0], _T("res\pipe2_down.png"));
  loadimage(&PIPE[1][1], _T("res\pipe2_up.png"));


  loadimage(&NUMBER[0][0], _T("res\font_048.png"));
  loadimage(&NUMBER[0][1], _T("res\font_049.png"));
  loadimage(&NUMBER[0][2], _T("res\font_050.png"));
  loadimage(&NUMBER[0][3], _T("res\font_051.png"));
  loadimage(&NUMBER[0][4], _T("res\font_052.png"));
  loadimage(&NUMBER[0][5], _T("res\font_053.png"));
  loadimage(&NUMBER[0][6], _T("res\font_054.png"));
  loadimage(&NUMBER[0][7], _T("res\font_055.png"));
  loadimage(&NUMBER[0][8], _T("res\font_056.png"));
  loadimage(&NUMBER[0][9], _T("res\font_057.png"));


  loadimage(&NUMBER[1][0], _T("res\number_context_00.png"));
  loadimage(&NUMBER[1][1], _T("res\number_context_01.png"));
  loadimage(&NUMBER[1][2], _T("res\number_context_02.png"));
  loadimage(&NUMBER[1][3], _T("res\number_context_03.png"));
  loadimage(&NUMBER[1][4], _T("res\number_context_04.png"));
  loadimage(&NUMBER[1][5], _T("res\number_context_05.png"));
  loadimage(&NUMBER[1][6], _T("res\number_context_06.png"));
  loadimage(&NUMBER[1][7], _T("res\number_context_07.png"));
  loadimage(&NUMBER[1][8], _T("res\number_context_08.png"));
  loadimage(&NUMBER[1][9], _T("res\number_context_09.png"));


  loadimage(&NUMBER[2][0], _T("res\number_score_00.png"));
  loadimage(&NUMBER[2][1], _T("res\number_score_01.png"));
  loadimage(&NUMBER[2][2], _T("res\number_score_02.png"));
  loadimage(&NUMBER[2][3], _T("res\number_score_03.png"));
  loadimage(&NUMBER[2][4], _T("res\number_score_04.png"));
  loadimage(&NUMBER[2][5], _T("res\number_score_05.png"));
  loadimage(&NUMBER[2][6], _T("res\number_score_06.png"));
  loadimage(&NUMBER[2][7], _T("res\number_score_07.png"));
  loadimage(&NUMBER[2][8], _T("res\number_score_08.png"));
  loadimage(&NUMBER[2][9], _T("res\number_score_09.png"));


  loadimage(&MEDAL[0], _T("res\medals_3.png"));
  loadimage(&MEDAL[1], _T("res\medals_2.png"));
  loadimage(&MEDAL[2], _T("res\medals_1.png"));
  loadimage(&MEDAL[3], _T("res\medals_0.png"));


  loadimage(&LAND, _T("res\land.png"));
  loadimage(&PLAY, _T("res\button_play.png"));
  loadimage(&OVER, _T("res\text_game_over.png"));
  loadimage(&READY, _T("res\text_ready.png"));
  loadimage(&TITLE, _T("res\title.png"));
  loadimage(&TUTORIAL, _T("res\tutorial.png"));
  loadimage(&PANEL, _T("res\score_panel.png"));
  loadimage(&NEW, _T("res\new.png"));
}

大家趕緊去動手試試吧!

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7614

    瀏覽量

    137401
  • 源碼
    +關注

    關注

    8

    文章

    652

    瀏覽量

    29353

原文標題:C語言小游戲:飛翔的小鳥(完整版),素材源碼都準備好了!

文章出處:【微信號:cyuyanxuexi,微信公眾號:C語言編程學習基地】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    須知道的495個C語言問題(完整版本)

    須知道的495個C語言問題(完整版本)
    發表于 08-16 16:29

    須知道的495個C語言問題(完整版本)

    須知道的495個C語言問題(完整版本)https://bbs.elecfans.com/forum.php?mod=viewthread&tid=265658&fromuid=483505
    發表于 08-16 19:06

    【原創】LabVIEW版 自虐的小鳥 小游戲

    ` 本帖最后由 隔壁老wang 于 2017-2-18 08:41 編輯 自己寫的LabVIEW版自虐的小鳥小游戲,見截圖`
    發表于 02-16 17:36

    PID控制算法的C語言實現(完整版)

    PID控制算法的C語言實現(完整版)
    發表于 08-10 09:40

    PID控制算法的C語言實現(完整版)

    PID控制算法的C語言實現(完整版)
    發表于 02-06 17:08

    PID控制算法的C語言實現(完整版)

    PID控制算法的C語言實現(完整版)
    發表于 04-02 11:39

    PID控制算法的C語言實現(完整版)

    PID控制算法的C語言實現(完整版)
    發表于 05-01 11:03

    【178頁完整版】輕松搞定C語言(提高篇)!!

    【178頁完整版】輕松搞定C語言(提高篇)!!需要完整版的朋友可以下載附件保存哦~
    發表于 08-16 10:58

    STM8的C語言編程1-14講完整版

    電子發燒友網站提供《STM8的C語言編程1-14講完整版.doc》資料免費下載
    發表于 04-26 15:22 ?0次下載

    ASCLL碼表(完整版)

    ASCLL碼表(完整版)ASCLL碼表(完整版)ASCLL碼表(完整版)ASCLL碼表(完整版)
    發表于 11-20 11:26 ?0次下載

    ASCII碼表完整版

    ASCII碼表完整版,方便學習C語言或者做LCD顯示器時用到。
    發表于 12-22 10:44 ?0次下載

    徹底搞定C語言指針詳解完整版

    徹底搞定C語言指針詳解完整版
    發表于 05-10 17:04 ?0次下載

    PID控制算法的C語言實現(完整版)

    PID控制算法的C語言實現(完整版),感興趣的發燒友們可以看一看。
    發表于 08-09 16:09 ?0次下載

    C51學習的教程完整版

    C51學習的教程完整版
    發表于 10-16 10:52 ?0次下載
    <b class='flag-5'>C</b>51學習的教程<b class='flag-5'>完整版</b>

    c語言面試題集(完整版)

    電子發燒友網站提供《c語言面試題集(完整版).pdf》資料免費下載
    發表于 10-20 11:20 ?2次下載
    <b class='flag-5'>c</b><b class='flag-5'>語言</b>面試題集(<b class='flag-5'>完整版</b>)
    主站蜘蛛池模板: videos gratis欧美另类| 三级在线网址| 甜性涩爱免费下载| YELLOW在线观看高清视频免费 | free性欧美xxx狂欢| 国产99视频精品免费播放| 男人网站在线观看| 把极品白丝班长啪到腿软| 日韩精品免费在线观看| 国产GV天堂亚洲国产GV刚刚碰| 天天躁日日躁狠狠躁AV麻豆| 国产人妻人伦精品1国产| 亚洲精品乱码久久久久久v| 狠狠色狠狠色综合系列| 在线少女漫画| 欧美 亚洲 有码中文字幕| 亚洲免费网站在线观看| 黄色三级网站| 1788福利视频在视频线| 精品国产原创在线观看视频| 伊人久久大香线蕉综合色啪| 美女裸露100%奶头视频| 超碰免费视频部落格| 忘忧草在线| 久久国产精品麻豆AV影视| 97人人碰免费视频公开| 日韩av国产av欧美天堂社区| 国产原创中文视频| 99成人在线视频| 偷偷鲁手机在线播放AV| 九九热视频在线观看| aa级毛片毛片免费观看久| 久久亚洲精品2017| beeg xxx日本老师| 午夜一个人在线观看完整版 | 京香在线播放| beeg xxx日本老师| 亚洲精品久久久无码AV片软件| 国产成人免费全部网站| 亚洲精品在线看| 农村脱精光一级|