我現在在讀大二,我們有一門課程叫《操作系統》,課程考查要求我們可以寫一段程序或者寫Windows、iOS、Mac的發展歷程。后面我結合網上的資料參考,就想用自己之前簡單學過的C寫一關的推箱子小程序。
這一程序主要用到了C語言中的二維數組,頭文件#include<conio.h>(因為要調用getch()函數以記錄輸入內容),switch函數等。
一、 功能概述
a) 游戲規則概述
玩家通過鍵盤輸入W、S、A、D四鍵或者“↑”、“↓”、“←”、“→”四個方向鍵推動箱子,而箱子只可以推, 不可以拉, 而且一次只能推動一個,勝利條件就是把所有的箱子都推到目的地。
b) 需要實現的功能
1) 能夠實現鍵盤操作功能:能夠接收到鍵盤輸入的方向鍵信息,並根據不同的方向鍵把游戲任務移動到相應的位置。例如,當玩家單擊方向鍵“↑”時,如果向上的位置是可移動的,那么就當把游戲人物向上移動一個方格;
2) 能夠判斷人物能否移動:比如說人旁邊是牆壁時是不能移動的,不能出現“人穿牆”的現象。人也不能同時推動兩個箱子,因此要判斷箱子的前方的情況;
3) 能夠判斷游戲結果:在玩家將所有的箱子推到對應的位置以后,能夠打印出“恭喜你,你贏了!”的結果。由於這個游戲並沒有設置時間限制,也沒有設置所能走的步數限制,因此,只要玩家有興趣玩下去,那么直到他將所有的箱子推進指定地點之前花了多少時間和步數都無所謂,只有將所有的箱子推進指定地點之后,才算贏了。
4) 優化游戲體驗:因為圖形化界面難做,簡單的圖案可能玩家看不懂,所以在游戲區域上方可以加上“溫馨提示”字樣,讓玩家能夠很容易地明白游戲界面各圖案表示的是什么意思,比如如下表示方法:■:牆;♀:人;☆:箱子;◎:終點;♂:人在終點。
二、 程序總體模塊分析
本程序總體大致可分為三大模塊,即讀入、判斷調整、輸出:
a) 讀入:即設置讀入操作把使用者的輸入操作符讀入程序,並定義變量儲存起來為下一步的判斷做好准備;
b) 判斷調整:這一操作為下一步的調整二維數組內容提供依據,通過大量的判斷語句對所有可能出現的情況提供相對應的唯一操作,使用戶能順利使用軟件並起到規范化輸入的目的——當輸入不明字符時不作處理。判斷結束后,執行相應操作改變數組內容從而改變輸出內容,使用戶順利進行下一步操作;
c) 輸出:通過刷屏后重新輸出從而使游戲界面得以改變(比如人物移動、箱子移動、箱子狀態改變等),進而等待用戶下步的輸入操作。
三、 程序關鍵代碼介紹
a) 頭文件#include<conio.h>與getch()函數
根據流程圖和功能需要的分析可知,程序要求要能夠實現鍵盤操作功能,即能夠接收到鍵盤輸入的方向鍵信息,並根據不同的方向鍵把游戲任務移動到相應的位置。因此,需要接收玩家指令。所以需要使用getch()函數以作記錄鍵盤輸入內容。
b) 繪制二維地圖
“推箱子”游戲有很多關卡,這里只設計了一個關卡,要增加更多關卡可以繼續進行繪制,采用三維數組,其中一組記錄關卡數即可,此處為簡便起見,只設計了一個關卡,關卡繪制的二維地圖如上圖所示。其中,■表示牆;♀表示人;☆表示箱子;◎表示終點;♂表示人在終點;★表示箱子位於終點。
在程序代碼中,繪制二維地圖采用二維數組的方式(因為這里只有一個關卡,就沒有使用三維數組)。繪制二維地圖采用的二維數組函數如下:
1 int map[9][11]= 2 { 3 {0,1,1,1,1,1,1,1,1,1,0}, 4 {0,1,0,0,0,1,0,0,0,1,0}, 5 {0,1,0,0,3,0,0,0,0,1,0}, 6 {0,1,0,3,0,3,3,3,0,1,1}, 7 {0,1,0,0,0,2,0,0,0,0,1}, 8 {1,1,0,0,1,1,1,0,3,0,1}, 9 {1,0,4,4,0,4,0,0,0,0,1}, 10 {1,0,4,4,0,4,4,3,0,1,1}, 11 {1,1,1,1,1,1,1,1,1,1,0} 12 };
其中 0 代表着空白的地方; 1 代表着牆;2 代表着人;3 代表着箱子;4 代表着箱子的終點位置。因為地圖為9行11列,所以map函數的兩個數組值為[9][11]。
c) 主函數主要內容
1 while(1) 2 { 3 system("cls"); 4 printf("溫馨提示:\n■:牆;\n♀:人;\n☆:箱子;\n◎:終點;\n♂:人在終點;\n★:箱子位於終點\n游戲制作者聖波祝您游戲愉快\n\n"); 5 drawmain(); 6 tuidong(); 7 }
說明:
1) 因為界面需要隨着人的移動而刷新,所以要使用循環結構並采用清屏函數system("cls")進行實時刷新;
2) 對玩家界面要友好,因此,用printf將提示信息打印在屏幕上,方便玩家理解游戲界面;
3) drawmain()函數是對游戲二維地圖的繪制,將代碼中的界面用圖形展示出來;
4) tuidong()函數是對玩家輸入的情況進行判斷,通過判斷鍵入的字符對游戲人物進行移動,並要判斷人物前方的情況,從而判斷人物能否移動,這是該游戲程序中最重要的部分,也是最難的一個部分。
d) drawmain()函數:二維地圖的繪制
1 int i,j; 2 winshu();//調用輸贏的函數(解釋見f部分) 3 for(i=0;i<9;i++) 4 {for(j=0;j<11;j++) 5 {switch(map[i][j]) 6 {case 0: printf(" "); //空白的地方 7 break; 8 case 1: printf("■"); //牆 9 break; 10 case 2: printf("♀"); //人 11 break; 12 case 3: printf("☆"); //箱子 13 break; 14 case 4: printf("◎"); //終點地方 15 break; 16 case 6: printf("♂");//人加終點位置 17 break; 18 case 7: printf("★") ;//箱子加終點位置 19 break; }} 20 printf("\n");}
說明:
1) 為了在圖的上方顯示結果,所以在打印二維地圖前調用判斷輸贏的函數;
2) 利用switch()函數,將二維數組中的數字轉化為屏幕中的圖形界面。
tuidong()及以后的函數請看后一篇隨筆《用C寫一個簡單的推箱子游戲(二)》