C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的推箱子小游戲
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單推箱子小游戲的具體代碼,供大家參考,具體內(nèi)容如下
此推箱子游戲可以實(shí)現(xiàn)人物移動(dòng),箱子移動(dòng),人物不出框,自義定文件關(guān)卡,重新開(kāi)始以及回退復(fù)位等功能的實(shí)現(xiàn),由于系統(tǒng)或版本問(wèn)題,關(guān)卡和人物及物體未做美化處理,希望美化的可自行美化。
1.所用到的宏
#include <stdio.h> #include <stdlib.h> #include <getopt.h> #define MAX_ROWS 16 #define MAX_CLOS 16 #define MAX_LEVEL 5 #define FILE_NAME_LEN 40 #define ROAD 0 ?//路? #define WALL 1 ?//墻? #define BOX ?2 ?//箱子? #define TERM 3 ?//門(mén)? #define MOUS 4 ?//老鼠? #define IGN ?224 //無(wú)效的鍵值? #define LEFT ?75 //上下左右相對(duì)應(yīng)的鍵值? #define RIGHT 77 #define UP ? ?72 #define DOWN ?80 #define MINT MOUS+TERM ? //老鼠在門(mén)上 #define BINT BOX+TERM ? ?//箱子在門(mén)上? #define QUIT 'q'//退出? #define RESET 'r'//重新開(kāi)始? #define BACK 'b'//回退? #define NM ?0 #define MM ?1 #define BM ?2 #define MAX_BACK_STEP 10//回退最多的步數(shù)?
2.變量聲明
struct Act{ ?? ?int dir; ?? ?int sta;?? ? }; struct Act acts[MAX_BACK_STEP] = {}; int stepsize = 0;//用于記錄回退的數(shù)量 int newindex = -1;//用于記錄產(chǎn)生一個(gè)新的動(dòng)作? int board[MAX_ROWS][MAX_CLOS] = {}; int row, col; int mx = 0,my = 0;//記錄老鼠位置? int bcnt = 0;//記錄箱子
3.地圖文件開(kāi)啟
void load(int level){//將地圖文件存放在Dev-CC文件夾下? ?? ?char fileName[FILE_NAME_LEN] = ""; ?? ?sprintf(fileName,"%d.txt",level); ?? ?FILE *fp = fopen(fileName,"r");//只讀形式打開(kāi)文件? ?? ?if(fp == NULL){ ?? ??? ?printf("%s文件打開(kāi)失敗\n",fileName); ?? ??? ?exit(-1);//失敗退出? ?? ?}? ?? ?fscanf(fp,"%d %d",&row,&col); ?? ?int i,j; ?? ?bcnt = 0; ?? ?for(i=0;i<row;i++){ ?? ??? ?for(j=0;j<col;j++){ ?? ??? ??? ?fscanf(fp,"%d",&board[i][j]);//讀取地圖行和列? ?? ??? ??? ?if(board[i][j] == MOUS || board[i][j] == MINT){ ?? ??? ??? ??? ?mx = i; ?? ??? ??? ??? ?my = j; ?? ??? ??? ?}? ?? ??? ??? ?else if(board[i][j] == BOX || board[i][j] == BINT){ ?? ??? ??? ??? ?++bcnt; ?? ??? ??? ?} ?? ??? ?} ?? ?} ?? ?fclose(fp); ?? ?stepsize = 0; ?? ?newindex = -1;//返回值初始化? }?
4.地圖顯示及記錄模塊
//顯示地圖,記錄箱子到達(dá)終點(diǎn)? int show(void){ ?? ?int i,j; ?? ?int bs = 0; ?? ?for(i=0;i<row;i++){ ?? ??? ?for(j=0;j<col;j++){ ?? ??? ??? ?switch(board[i][j]){//畫(huà)出地圖? ?? ??? ??? ??? ?case ROAD: ?? ??? ??? ??? ??? ?printf(" "); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?case WALL: ?? ??? ??? ??? ??? ?printf("#"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?case BINT: ?? ??? ??? ??? ??? ?++bs; ?? ??? ??? ??? ?case BOX: ?? ??? ??? ??? ??? ?printf("@"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ?case TERM: ?? ??? ??? ??? ??? ?printf("O"); ?? ??? ??? ??? ??? ?break;? ?? ??? ??? ??? ?case MOUS: ?? ??? ??? ??? ?case MINT: ?? ??? ??? ??? ??? ?printf("&"); ?? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ? ?? ??? ??? ?} ?? ??? ?} ?? ??? ?printf("\n"); ?? ?} ?? ?return bs; }
5.物體的移動(dòng)和關(guān)卡的延續(xù)
int move(int stepx,int stepy){//老鼠和箱子的移動(dòng)? ?? ?int nx = mx + stepx; ?? ?int ny = my + stepy; ?? ?if (board[nx][ny] == ROAD || board[nx][ny] == TERM){ ?? ??? ?board[mx][my] -= MOUS; ?? ??? ?board[nx][ny] += MOUS; ?? ??? ?mx = nx; ?? ??? ?my = ny; ?? ??? ?return MM; ?? ?} ?? ?else if(board[nx][ny] == BOX || board[nx][ny] == BINT){//推著箱子走? ?? ??? ?int nnx = nx + stepx; ?? ??? ?int nny = ny + stepy;//箱子的坐標(biāo)? ?? ??? ?if(board[nnx][nny] == ROAD || board[nnx][nny] == TERM){ ?? ??? ??? ?board[nnx][nny] += BOX;//箱子到達(dá)新的地方? ?? ??? ??? ?board[nx][ny] -= BOX;//箱子從原來(lái)的地方離開(kāi) ?? ??? ??? ?board[mx][my] -= MOUS;//老鼠離開(kāi)? ?? ??? ? ? ?board[nx][ny] += MOUS;//老鼠到達(dá)的新的點(diǎn)? ?? ??? ? ? ?mx = nx; ?? ??? ? ? ?my = ny; ?? ??? ? ? ?return BM; ?? ??? ?} ?? ?} ?? ?return NM; }
6.回退功能的實(shí)現(xiàn)(最難部分)
void moveback(int stepx,int stepy){//回退? ?? ?int nx = mx+stepx; ?? ?int ny = my+stepy; ?? ?board[mx][my] -= MOUS; ?? ?board[nx][ny] += MOUS; ?? ?if(acts[newindex].sta == BM){ ?? ??? ?int bx = mx-stepx; ?? ??? ?int by = my-stepy; ?? ??? ?board[bx][by] -=BOX; ?? ??? ?board[mx][my] +=BOX; ?? ?} ?? ?mx = nx; ?? ?my = ny; } ? void back(void){ ?? ?if(stepsize >0){ ?? ??? ?switch(acts[newindex].dir){ ?? ??? ??? ?case UP: ?? ??? ??? ??? ?moveback(+1,0); ?? ??? ??? ??? ?break; ?? ??? ??? ?case DOWN: ?? ??? ??? ??? ?moveback(-1,0); ?? ??? ??? ??? ?break; ?? ??? ??? ?case LEFT: ?? ??? ??? ??? ?moveback(0,+1); ?? ??? ??? ??? ?break; ?? ??? ??? ?case RIGHT: ?? ??? ??? ??? ?moveback(0,-1); ?? ??? ??? ??? ?break;? ?? ??? ?} ?? ??? ?--stepsize; ?? ??? ?--newindex; ?? ??? ?if(newindex == -1){ ?? ??? ??? ?newindex = MAX_BACK_STEP -1; ?? ??? ?} ?? ?} }
7.游戲運(yùn)行主要部分
void play(int level){ ?? ?while(1){ ?? ??? ?system("cls");//清屏? ?? ??? ?int ret = show(); ?? ??? ?if(ret == bcnt){//箱子和被推到終點(diǎn)的箱子數(shù)一樣時(shí)? ?? ??? ??? ?printf("恭喜過(guò)關(guān),按任意鍵進(jìn)入下一關(guān)??!"); ?? ??? ??? ?getch(); ?? ??? ??? ?return;? ?? ??? ?} ?? ??? ?int key = getch(); ?? ??? ?if(key == IGN){ ?? ??? ??? ?key = getch(); ?? ??? ?} ?? ??? ?if(key == QUIT){//退出? ?? ??? ??? ?printf("GAME OVER\n"); ?? ??? ??? ?exit(0); ?? ??? ?}? ?? ??? ?else if(key == RESET){//重新開(kāi)始? ?? ??? ??? ?load(level);//重新加載地圖? ?? ??? ?} ?? ??? ?else if(key == BACK){//回退功能? ?? ??? ??? ?back();? ?? ??? ?} ?? ??? ?ret = NM; ?? ??? ?switch(key){ ?? ??? ??? ?case UP: ?? ??? ??? ??? ?ret = move(-1,0); ?? ??? ??? ??? ?break; ?? ??? ??? ?case DOWN: ?? ??? ??? ??? ?ret = move(+1,0); ?? ??? ??? ??? ?break; ?? ??? ??? ?case LEFT: ?? ??? ??? ??? ?ret = move(0,-1); ?? ??? ??? ??? ?break; ?? ??? ??? ?case RIGHT: ?? ??? ??? ??? ?ret = move(0,+1); ?? ??? ??? ? ? ?break;?? ??? ??? ??? ? ?? ??? ?} ?? ??? ?if(ret == MM || ret == BM){//保存有效動(dòng)作 用于回退 ? ?? ??? ??? ?struct Act act = {key,ret}; //記錄動(dòng)作 ?? ??? ??? ?++newindex; ?? ??? ??? ?if(newindex>= MAX_BACK_STEP){ ?? ??? ??? ??? ?newindex = 0; ?? ??? ??? ?} ?? ??? ??? ?acts[newindex] = act; ?? ??? ??? ?if(stepsize<MAX_BACK_STEP){ ?? ??? ??? ??? ?++stepsize;//可以退回的步數(shù)+1? ?? ??? ??? ?} ?? ??? ?} ?? ?} } ? //運(yùn)行函數(shù)? void run(void){ ?? ?int level; ?? ?for(level=1;level<=MAX_LEVEL;level++){ ?? ??? ?load(level); ?? ??? ?play(level); ?? ?} } //主函數(shù)? int main(int argc, char *argv[]) { ?? ?run(); ?? ?return 0; }
8.參考關(guān)卡文件(可使用windos記事本以.txt 形式保存,第一列均為空格)
具體解釋存在于代碼中。如有不足,請(qǐng)指正!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
數(shù)據(jù)結(jié)構(gòu)之堆的具體使用
本文主要介紹了數(shù)據(jù)結(jié)構(gòu)之堆的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02淺談C++內(nèi)存分配及變長(zhǎng)數(shù)組的動(dòng)態(tài)分配
下面小編就為大家?guī)?lái)一篇淺談C++內(nèi)存分配及變長(zhǎng)數(shù)組的動(dòng)態(tài)分配。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09用VC++6.0實(shí)現(xiàn)石頭剪刀布游戲的程序
最先看到這個(gè)游戲代碼是python版的,后來(lái)看到有小伙伴用VC++重寫(xiě)了一遍,運(yùn)行之后發(fā)現(xiàn)有些小bug,便嘗試這修復(fù)了一下,并增加了些小功能,這里分享給大家。2015-03-03C++定時(shí)器實(shí)現(xiàn)和時(shí)間輪介紹
這篇文章主要介紹了C++定時(shí)器實(shí)現(xiàn)和時(shí)間輪介紹,定時(shí)器可以由很多種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn),比如最小堆、紅黑樹(shù)、跳表、甚至數(shù)組都可以,其本質(zhì)都是拿到最小時(shí)間的任務(wù),然后取出該任務(wù)并執(zhí)行,更多相關(guān)內(nèi)容介紹,需要的小伙伴可以參考一下2022-09-09C++中的Lambda表達(dá)式及表達(dá)式語(yǔ)句
這篇文章主要介紹了C++中的Lambda表達(dá)式及表達(dá)式語(yǔ)句,表達(dá)式這個(gè)概念在C++中屬于比較細(xì)節(jié)的知識(shí)了,很多時(shí)候我們只用知道怎么用,對(duì)于編譯器內(nèi)部怎么處理我們并不關(guān)心;并且關(guān)于左值和右值這個(gè)概念,也是C++比較深的一個(gè)小知識(shí)點(diǎn),需要的朋友可以參考一下2021-12-12c++ 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別
內(nèi)聯(lián)函數(shù)是c++為了提高程序的運(yùn)行速度做的改進(jìn),那么內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別是什么,本文就來(lái)詳細(xì)的介紹一下,感興趣的朋友可以了解一下2021-05-05