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.地圖顯示及記錄模塊
//顯示地圖,記錄箱子到達終點?
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;//箱子的坐標?
?? ??? ?if(board[nnx][nny] == ROAD || board[nnx][nny] == TERM){
?? ??? ??? ?board[nnx][nny] += BOX;//箱子到達新的地方?
?? ??? ??? ?board[nx][ny] -= BOX;//箱子從原來的地方離開
?? ??? ??? ?board[mx][my] -= MOUS;//老鼠離開?
?? ??? ? ? ?board[nx][ny] += MOUS;//老鼠到達的新的點?
?? ??? ? ? ?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)之堆的具體使用,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-02-02
淺談C++內(nèi)存分配及變長數(shù)組的動態(tài)分配
下面小編就為大家?guī)硪黄獪\談C++內(nèi)存分配及變長數(shù)組的動態(tài)分配。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-09-09
c++ 內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別
內(nèi)聯(lián)函數(shù)是c++為了提高程序的運行速度做的改進,那么內(nèi)聯(lián)函數(shù)和普通函數(shù)的區(qū)別是什么,本文就來詳細的介紹一下,感興趣的朋友可以了解一下2021-05-05

