C語言實現(xiàn)簡單的推箱子小游戲
本文實例為大家分享了C語言實現(xiàn)簡單推箱子小游戲的具體代碼,供大家參考,具體內(nèi)容如下
此推箱子游戲可以實現(xiàn)人物移動,箱子移動,人物不出框,自義定文件關(guān)卡,重新開始以及回退復(fù)位等功能的實現(xiàn),由于系統(tǒng)或版本問題,關(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 ?//門? #define MOUS 4 ?//老鼠? #define IGN ?224 //無效的鍵值? #define LEFT ?75 //上下左右相對應(yīng)的鍵值? #define RIGHT 77 #define UP ? ?72 #define DOWN ?80 #define MINT MOUS+TERM ? //老鼠在門上 #define BINT BOX+TERM ? ?//箱子在門上? #define QUIT 'q'//退出? #define RESET 'r'//重新開始? #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)生一個新的動作? int board[MAX_ROWS][MAX_CLOS] = {}; int row, col; int mx = 0,my = 0;//記錄老鼠位置? int bcnt = 0;//記錄箱子
3.地圖文件開啟
void load(int level){//將地圖文件存放在Dev-CC文件夾下? ?? ?char fileName[FILE_NAME_LEN] = ""; ?? ?sprintf(fileName,"%d.txt",level); ?? ?FILE *fp = fopen(fileName,"r");//只讀形式打開文件? ?? ?if(fp == NULL){ ?? ??? ?printf("%s文件打開失敗\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á)終點? 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]){//畫出地圖? ?? ??? ??? ??? ?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.物體的移動和關(guān)卡的延續(xù)
int move(int stepx,int stepy){//老鼠和箱子的移動? ?? ?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;//箱子從原來的地方離開 ?? ??? ??? ?board[mx][my] -= MOUS;//老鼠離開? ?? ??? ? ? ?board[nx][ny] += MOUS;//老鼠到達(dá)的新的點? ?? ??? ? ? ?mx = nx; ?? ??? ? ? ?my = ny; ?? ??? ? ? ?return BM; ?? ??? ?} ?? ?} ?? ?return NM; }
6.回退功能的實現(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.游戲運行主要部分
void play(int level){ ?? ?while(1){ ?? ??? ?system("cls");//清屏? ?? ??? ?int ret = show(); ?? ??? ?if(ret == bcnt){//箱子和被推到終點的箱子數(shù)一樣時? ?? ??? ??? ?printf("恭喜過關(guā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){//重新開始? ?? ??? ??? ?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){//保存有效動作 用于回退 ? ?? ??? ??? ?struct Act act = {key,ret}; //記錄動作 ?? ??? ??? ?++newindex; ?? ??? ??? ?if(newindex>= MAX_BACK_STEP){ ?? ??? ??? ??? ?newindex = 0; ?? ??? ??? ?} ?? ??? ??? ?acts[newindex] = act; ?? ??? ??? ?if(stepsize<MAX_BACK_STEP){ ?? ??? ??? ??? ?++stepsize;//可以退回的步數(shù)+1? ?? ??? ??? ?} ?? ??? ?} ?? ?} } ? //運行函數(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 形式保存,第一列均為空格)
具體解釋存在于代碼中。如有不足,請指正!
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
數(shù)據(jù)結(jié)構(gòu)之堆的具體使用
本文主要介紹了數(shù)據(jù)結(jié)構(gòu)之堆的具體使用,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02淺談C++內(nèi)存分配及變長數(shù)組的動態(tài)分配
下面小編就為大家?guī)硪黄獪\談C++內(nèi)存分配及變長數(shù)組的動態(tài)分配。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09c++ 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別
內(nèi)聯(lián)函數(shù)是c++為了提高程序的運行速度做的改進,那么內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別是什么,本文就來詳細(xì)的介紹一下,感興趣的朋友可以了解一下2021-05-05