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

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

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

3天內不再提示

C語言實現推箱子游戲!代碼思路+源碼分享

C語言編程學習基地 ? 來源:C語言編程學習基地 ? 作者:童晶 ? 2022-11-29 16:22 ? 次閱讀

經典的推箱子是一個很古老的游戲了,相信大家都不陌生。其目的是在訓練我們的邏輯思考能力。在一個狹小的倉庫中,要求把木箱放到指定的位置,稍不小心就會出現箱子無法移動或者通道被堵住的情況,所以需要巧妙的利用有限的空間和通道,合理安排移動的次序和位置,才能順利的完成任務。

我們將編寫推箱子游戲,玩家鍵盤控制游戲角色將所有黃色箱子推到白色方塊處,效果如圖所示:

da8b0848-6fbd-11ed-8abf-dac502259ad0.png

操作方法:方向鍵↑↓←→控制移動推箱子,將箱子推到對應位置。

首先學習字符串與字符數組的概念,并應用字符數組初始化關卡數據;然后利用鍵盤控制游戲角色移動,實現地圖元素更新和游戲勝利的判斷;接著利用三維字符數組,實現多關卡的游戲;最后學習基于文件的關卡數據讀取,利用枚舉類型改進游戲代碼。

源碼:

#include   
#include 
#include 
#define B_SIZE 60 // 方塊大小
#define B_NUM 8 // 方塊個數,一共8*8個方塊


struct Player // 結構體,用于記錄玩家位置
{
  int i;
  int j;
};
Player player; // 玩家全局變量


enum Element // 定義枚舉類型,小方塊所有的可能的種類
{
  wall,target,box,empty,achieved,role
};


// 用于存儲地圖數據,用枚舉類型實現
Element level[B_NUM][B_NUM] = 
{{wall,wall,wall,wall,wall,wall,wall,wall},
{wall,wall,wall,target,box,empty,empty,wall},
{wall,empty,empty,empty,empty,empty,empty,wall},
{wall,empty,empty,empty,empty,empty,empty,wall},
{wall,empty,empty,empty,empty,empty,empty,wall},
{wall,role,empty,box,target,wall,wall,wall},
{wall,empty,empty,empty,empty,wall,wall,wall},
{wall,wall,wall,wall,wall,wall,wall,wall}};


int targetNum,achievedNum; // 目標位置個數、完成目標個數


void startup()  // 初始化函數
{
  initgraph(B_NUM*B_SIZE,B_NUM*B_SIZE); // 新開一個畫面
  setbkcolor(RGB(150,150,150)); // 灰色背景
  BeginBatchDraw(); // 開始批量繪圖
  int i,j;
  targetNum = 0; // 目標個數,初始為0
  // 對二維數組遍歷
  for (i=0;i
    for (j=0;j
    {
      if (level[i][j]==role) // 找到地圖中player位置
      {
        player.i = i; // 設定player位置
        player.j = j; // 
        level[i][j]=empty; // 把地圖元素變成空白empty
      }
      else if (level[i][j]==target || level[i][j]==achieved ) // 如果元素是target或achieved
        targetNum++; // 目標個數+1
    }
}


void show() // 繪制函數
{
  int i,j;
  cleardevice(); // 以背景顏色清空屏幕
  // 遍歷關卡二維數組數據
  for (i=0;i
  {
    for (j=0;j
    {
      if (level[i][j]==empty) // empty 元素是空白區域
      {
        setfillcolor(RGB(150,150,150)); // 繪制灰色地面
        setlinecolor(RGB(150,150,150));
        fillrectangle(j*B_SIZE,i*B_SIZE,(j+1)*B_SIZE,(i+1)*B_SIZE);
      }
      else if (level[i][j]==wall)  // wall 元素是墻
      {
        setfillcolor(RGB(155,0,0));
        setlinecolor(RGB(150,150,150)); // 繪制淡紅色、灰色線的方框
        fillrectangle(j*B_SIZE,i*B_SIZE,(j+1)*B_SIZE,(i+1)*B_SIZE);
      }
      else if (level[i][j]==box) // box 元素是可移動的箱子
      {
        setfillcolor(RGB(255,255,0)); // 繪制一個黃色的方塊
        setlinecolor(RGB(150,150,150));
        fillrectangle(j*B_SIZE,i*B_SIZE,(j+1)*B_SIZE,(i+1)*B_SIZE);
      }
      else if (level[i][j]==target) // target 元素是目標
      {
        setfillcolor(RGB(250,250,250)); // 繪制一個白色的小方塊
        fillrectangle((j+0.3)*B_SIZE,(i+0.3)*B_SIZE,
          (j+0.7)*B_SIZE,(i+0.7)*B_SIZE);
      }
      else if (level[i][j]==achieved) // achieved 元素是已完成目標
      {
        setlinecolor(RGB(150,150,150));
        setfillcolor(RGB(255,255,0)); // 繪制一個黃色的方塊
        fillrectangle(j*B_SIZE,i*B_SIZE,(j+1)*B_SIZE,(i+1)*B_SIZE);
        setfillcolor(RGB(250,250,250)); // 繪制一個白色的小方塊
        fillrectangle((j+0.3)*B_SIZE,(i+0.3)*B_SIZE,
          (j+0.7)*B_SIZE,(i+0.7)*B_SIZE);
      }    
    }
  }
  // 以下繪制玩家,繪制一個人臉圖案
  i = player.i; 
  j = player.j;
  setfillcolor(RGB(255,0,0));
  fillcircle((j+0.5)*B_SIZE,(i+0.5)*B_SIZE,0.4*B_SIZE);//一個紅色圓臉
  setfillcolor(RGB(80,80,80));
  setlinecolor(RGB(80,80,80));
  fillcircle((j+0.3)*B_SIZE,(i+0.45)*B_SIZE,0.08*B_SIZE);//兩個黑色眼睛
  fillcircle((j+0.7)*B_SIZE,(i+0.45)*B_SIZE,0.08*B_SIZE); 
  setlinestyle(PS_SOLID,3);
  line((j+0.35)*B_SIZE,(i+0.7)*B_SIZE,(j+0.65)*B_SIZE,(i+0.7)*B_SIZE);//深灰色嘴巴
  setlinestyle(PS_SOLID,1);


  if (achievedNum==targetNum) // 如完成目標個數==目標個數
  {
    setbkmode(TRANSPARENT); // 透明顯示文字
    settextcolor(RGB(0,255,255)); // 設置字體顏色
    settextstyle(80, 0, _T("宋體")); // 設置字體大小、樣式
    outtextxy(80,200,_T("游戲勝利")); // 顯示游戲勝利文字
  }
  FlushBatchDraw(); // 開始批量繪制
}


void update()  // 每幀更新運行
{
  if(kbhit() && (achievedNum// 如果按鍵,并且游戲沒有勝利
  {
    char input = getch(); // 獲取按鍵
    if (input=='a' || input=='s' || input=='d' || input=='w') // 如果是有效按鍵
    {
      int goal_i = player.i; // 移動的目標位置
      int goal_j = player.j;
      int goalNext_i = goal_i; // 目標位置再向前的一個位置
      int goalNext_j = goal_j;
      // 根據用戶的不同按鍵輸入,獲得目標位置、再向前的一個位置
      if (input=='a') // 向左
      {
        goal_j = player.j -1 ; // 目標位置在玩家位置的左邊
        goalNext_j = goal_j-1; // 目標的下一個位置,在其再左邊
      }
      else if (input=='d') // 向右
      {
        goal_j = player.j +1 ; // 目標位置在玩家位置的右邊 
        goalNext_j = goal_j+1; // 目標的下一個位置,在其再右邊
      }
      else if (input=='s') // 向下
      {
        goal_i = player.i+1; // 目標位置在玩家位置的下邊 
        goalNext_i = goal_i+1; // 目標的下一個位置,在其再下邊 
      }
      else if (input=='w') // 向上
      {
        goal_i = player.i-1; // 目標位置在玩家位置的上邊 
        goalNext_i = goal_i-1; // 目標的下一個位置,在其再上邊 
      }


      // 根據不同地圖元素的情況,判斷如何移動角色和更新地圖元素  
      if (level[goal_i][goal_j]==empty || level[goal_i][goal_j]==target ) 
      {  // 如果目標位置是empty,或者target
        player.i = goal_i; // 玩家移動到目標位置
        player.j = goal_j;        
      }
      else if (level[goal_i][goal_j]==box && level[goalNext_i][goalNext_j]==empty ) 
      {  // 如果目標位置是box,再前面一個是empty
        player.i = goal_i; // 玩家移動到目標位置
        player.j = goal_j;    
        level[goal_i][goal_j]=empty;  // 目標位置變成empty
        level[goalNext_i][goalNext_j]=box;   // 再前面變成box
      }
      else if (level[goal_i][goal_j]==box && level[goalNext_i][goalNext_j]==target) 
      {  // 如果目標位置是box,再前面一個是target
        player.i = goal_i; // 玩家移動到目標位置
        player.j = goal_j;  
        level[goal_i][goal_j] = empty;  // 目標位置變成empty 
        level[goalNext_i][goalNext_j] = achieved;  // 再前面變成achieved
      }
      else if (level[goal_i][goal_j]==achieved && level[goalNext_i][goalNext_j]== empty) 
      {  // 如果目標位置是achieved,再前面一個是empty
        player.i = goal_i; // 玩家移動到目標位置
        player.j = goal_j;    
        level[goal_i][goal_j] = target;  // 目標位置變成target 
        level[goalNext_i][goalNext_j] = box; // 再前面變成box   
      }
      else if (level[goal_i][goal_j]==achieved && level[goalNext_i][goalNext_j]== target) 
      {  // 如果目標位置是achieved,再前面一個是target
        player.i = goal_i; // 玩家移動到目標位置
        player.j = goal_j;
        level[goal_i][goal_j] = target;  // 目標位置變成target  
        level[goalNext_i][goalNext_j] = achieved; // 再前面變成achieved    
      }
      else // 其他情況都推不動
        return; // 不做任何處理,函數直接返回
    }
    achievedNum = 0; // 完成目標個數,初始為0
    int i,j;
    for (i=0;i// 對二維數組遍歷
      for (j=0;j// 
        if (level[i][j]==achieved) // 如果元素是achieved
          achievedNum++; // 完成目標個數+1
  }
}


int main() // 主函數
{
  startup();  // 初始化  
  while (1)  // 游戲主循環
  {
    show();    // 繪制
    update();   // 更新
  }
  return 0;
}

主要講解了字符串與字符數組、文件讀寫、枚舉類型等語法知識,實現了推箱子游戲。讀者可以嘗試在本章代碼基礎上繼續改進:

1、實現多關卡的選擇界面;

2、實現某一步移動的撤銷功能(類似于下棋游戲中的悔棋功能);

3、實現按'h'鍵后進行提示,播放正確步驟動畫的功能;

4、實現一個圖形編輯器,并將設計的關卡信息保存為txt文件。

審核編輯 :李倩


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

    關注

    180

    文章

    7605

    瀏覽量

    136990
  • 編輯器
    +關注

    關注

    1

    文章

    806

    瀏覽量

    31190

原文標題:C語言實現推箱子游戲!(超簡單詳細)代碼思路+源碼分享

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

收藏 人收藏

    評論

    相關推薦

    AKI跨語言調用庫神助攻C/C++代碼遷移至HarmonyOS NEXT

    )開發框架。它極大地簡化了JS與C/C++之間的跨語言訪問,為開發者提供了一種邊界性編程體驗友好的解決方案。通過AKI,開發者可以使用讓代碼更易讀的語法糖,
    發表于 01-02 17:08

    基于FPGA實現圖像直方圖設計

    直方圖統計的原理 直方圖統計從數學上來說,是對圖像中的像素點進行統計。圖像直方圖統計常用于統計灰度圖像,表示圖像中各個灰度級出現的次數或者概率。統計直方圖的實現采用C/C++或者其他高級語言實
    的頭像 發表于 12-24 10:24 ?119次閱讀
    基于FPGA<b class='flag-5'>實現</b>圖像直方圖設計

    FPGA打磚塊小游戲設計思路

    ? 交流問題 ? Q :FPGA打磚塊小游戲,如何基于FPGA用verilog語言在Vivado平臺上寫打磚塊小游戲,最好能用到PS2與VGA。 A :以下是一個基于 FPGA? Verilog
    的頭像 發表于 12-09 16:57 ?222次閱讀

    深入理解C語言:循環語句的應用與優化技巧

    在程序設計中,我們常常需要重復執行某一段代碼。為了提高效率和簡化代碼,循環語句應運而生。C語言作為一門經典的編程語言,提供了多種循環控制結構
    的頭像 發表于 12-07 01:11 ?178次閱讀
    深入理解<b class='flag-5'>C</b><b class='flag-5'>語言</b>:循環語句的應用與優化技巧

    使用C語言實現函數模板

      用C語言能不能實現一個通用的函數,既能完成整數的相加,又能完成浮點數的相加?
    的頭像 發表于 11-09 11:38 ?401次閱讀

    TMS320LF240x DSP的C語言和匯編代碼快速入門

    電子發燒友網站提供《TMS320LF240x DSP的C語言和匯編代碼快速入門.pdf》資料免費下載
    發表于 10-18 10:14 ?1次下載
    TMS320LF240x DSP的<b class='flag-5'>C</b><b class='flag-5'>語言</b>和匯編<b class='flag-5'>代碼</b>快速入門

    hex文件如何查看原c語言代碼

    直接將 .hex 文件轉換回原始的 C 語言代碼是不可能的,因為 .hex 文件是二進制文件,它包含了單片機程序編譯后的機器碼,這些機器碼與原始的 C
    的頭像 發表于 09-02 10:37 ?2421次閱讀

    如何用C語言實現高效查找(二分法)

    今天給分享一下使用C語言實現二分算法,主要包含以下幾部分內容:二分查找算法介紹二分查找算法使用場景二分查找算法代碼實現二分查找算法實現過程用
    的頭像 發表于 06-04 08:04 ?1159次閱讀
    如何用<b class='flag-5'>C</b><b class='flag-5'>語言實現</b>高效查找(二分法)

    使用C語言實現的CRC計算單元的例子

    使用C語言實現的CRC計算單元的例子
    的頭像 發表于 05-16 16:16 ?1006次閱讀

    如何提升嵌入式C語言代碼可讀性

    接口是面向對象語言中的一個比較重要的概念,接口只對外部承諾實現該接口的實體可以完成什么樣的功能,但是不暴露實現的方式。這樣的好處是,實現者可以在不接觸接口使用者的
    發表于 04-11 11:30 ?361次閱讀
    如何提升嵌入式<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>代碼</b>可讀性

    C語言實現Web參數傳遞

    電子發燒友網站提供《C語言實現Web參數傳遞.docx》資料免費下載
    發表于 03-24 09:14 ?2次下載

    C語言內存泄漏問題原理

    內存泄漏問題只有在使用堆內存的時候才會出現,棧內存不存在內存泄漏問題,因為棧內存會自動分配和釋放。C語言代碼中堆內存的申請函數是malloc。
    發表于 03-19 11:38 ?530次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b>內存泄漏問題原理

    c語言,c++,java,python區別

    C語言C++、Java和Python是四種常見的編程語言,各有優點和特點。 C語言
    的頭像 發表于 02-05 14:11 ?2429次閱讀

    VectorCAST的Probe Point探測點功能,不改變源碼插入代碼實現測試#代碼動態測試

    源碼代碼
    北匯信息POLELINK
    發布于 :2024年01月17日 18:50:55

    ADUC7061如何使用C語言實現EEPROM功能?

    我使用ADUC7061做的信號采集,現在客戶需要實現EEPROM功能來保存3-5個數據,請問如何使用C語言實現?不使用外部EEPROM 專用IC。
    發表于 01-12 06:56
    主站蜘蛛池模板: 中国xxx视频| 国产亚洲精品高清视频免费| 九九免费的视频| 最新老头恋老OLDMAN| 嫩草视频在线观看免费| 欧美日韩另类在线专区| 被滋润的艳妇疯狂呻吟白洁老七| 色女孩综合| 韩国成人理伦片免费播放| 中文字幕亚洲欧美日韩2019| 青青草原亚洲| 果冻传媒在线播放| 99视频国产在线| 校花爽好大快深点h| 麻豆官网md.pub| 国产成人免费观看在线视频| 一二三四高清中文版视频| 欧美日韩精品不卡在线观看| 国产精品无需播放器| 做暖暖视频在线看片免费| 手机看片国产免费| 开心色99xxxx开心色| 国产成人无码AV麻豆| 又爽又黄又粗又大免费视频| 日本女人bbb| 久久视频在线视频观看天天看视频| 成人国产精品日本在线| 永久adc视频年龄确认| 日韩精品AV一区二区三区| 久久精品电影院| 国产精品-区区久久久狼| 88.7在线收听| 亚洲人视频在线| 色狠狠一区| 免费看国产曰批40分钟| 国产探花在线精品一区二区| av网站视频在线观看| 亚洲一区二区女搞男| 日韩高清毛片| 内射人妻无码色AV麻豆去百度搜| 挤奶门事件完整照片|