日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++ 推箱子,中配版,支持玩家自己创造地图(无图形库)

發布時間:2024/1/18 c/c++ 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 推箱子,中配版,支持玩家自己创造地图(无图形库) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

游戲功能介紹:

1、玩家上下左右移動的正確實現。
2、玩家推箱子,箱子位置的變化,以及玩家是否能夠推動的判斷。
3、勝利檢測。(判斷游戲是否勝利)
4、選關模塊,方便玩家選擇自己想要游玩的關卡進行游玩。
5、游戲介紹模塊。
6、游戲目錄模塊。

鄭重聲明:

1、該游戲代碼屬于原創。尤其是其中的文件檢索功能,應該在目前網絡上,還未出現過和我一樣的關卡文件參數格式。
2、采用類和對象的方式來書寫,可以供學習面向對象的朋友,提高oo思想。
3、希望看見這篇博客的朋友能夠充分學習其中的知識點,提升自己,同時也歡迎各位朋友在下方評論區評論以及下來的討論。
4、代碼剛剛寫完,而且制作的第3關和第4關,是引用到網上的推箱子的地圖,作者因為實力有限而沒有在第3關和第4關獲勝,所以若有bug,請朋友們指正。

下載鏈接:

1、游戲下載鏈接:點擊藍色字前往下載
2、源代碼下載鏈接:點擊藍色字前往下載

注意:
1、游戲下載需要三個積分。
2、源代碼下載還是老規矩。(粉絲即可)

效果視頻展示:

展示

地圖制作方式 以及 地圖添加方式:

地圖制作方式:

地圖制作

地圖添加方式:

游戲組建添加方式(推箱子游戲)

代碼分析:

1、宏定義:

#define SIZE 10 //宏意義地圖大小。 #define NUMBER 10 //宏定義最大箱子數目。(可以根據玩家自己制作的地圖,而修改最大箱子數。)(個人認為10個箱子應該夠了。)

2、創建類和對象:

這里面創建了兩個內,一個是箱子的類,另一個是玩家的類。

這兩個類里面都會分別記錄對象的橫縱坐標。

玩家這個類里面有兩個行為,一個是移動,另一個是推箱子。
箱子這個類里面有一個行為,那就是移動。

特別聲明,箱子的類必須定義在玩家類的前面,因為在玩家推的行為里面會涉及到箱子的移動行為。

class Box { public:int placeI; //記錄箱子的橫坐標。int placeJ; //記錄箱子的縱坐標。Box(); //該類的構造器。int move( int command );//箱子的移動行為。 };class Player { public:int placeI; //記錄玩家橫坐標int placeJ; //記錄玩家縱坐標Player(); //該類的構造器。int move( int command ); //玩家的移動行為。int push( int command , Box box[] , int ); //玩家的推箱子行為。 };//玩家類的構造器。 Player::Player() {//玩家的位置為(-1,-1),由于這個點在地圖上并不存在,所以在運行過程中,若玩家的位置依舊為(-1,-1),那么可以表示文件讀取錯誤。placeI = -1;placeJ = -1; }//箱子類的構造器。 Box::Box() {//和玩家的構造器一樣。placeI = -1;placeJ = -1; }int Player::move( int command ) {switch ( command ){//表示玩家位置向上移動一格。case 1:placeI -= 1;break;//表示玩家位置向左移動一格。case 2:placeJ -= 1;break;//表示玩家位置向下移動一格。case 3:placeI += 1;break;//表示玩家位置向右移動一格。case 4:placeJ += 1;default:break;}return 0; }int Player::push( int command , Box box[] , int I ) {int tempI = placeI , tempJ = placeJ;//讓新產生的這兩個變量指向玩家所站的地方。(這兩個變量一起看的話是一個坐標。)//將該坐標向玩家將要移動的方向移動一格。switch ( command ){case 1:tempI -= 1;break;case 2:tempJ -= 1;break;case 3:tempI += 1;break;case 4:tempJ += 1;break;default:break;}//檢測該坐標指向的方塊是哪一個箱子。int temp = 0;//用于檢索box里面的每個元素。while( temp < I ){if( box[temp].placeI == tempI && box[temp].placeJ == tempJ )//如果是該箱子。{box[temp].move( command );//調用箱子移動的行為。break;}temp++;}move( command );//玩家移動。return 0; }int Box::move( int command ) {//和玩家到移動行為一樣。switch ( command ){case 1:placeI -= 1;break;case 2:placeJ -= 1;break;case 3:placeI += 1;break;case 4:placeJ += 1;break;default:break;}return 0; }

聲明所需的子函數:

子函數有點多,希望朋友們不要畏懼困難。
相反,我們要迎難而上。

gettingData()子函數,是用于檢索地圖并且加載到內存中的一個函數。
在視頻中已經講到了,我們的程序是可以允許玩家自行創造地圖的,所以我們必須要從程序外部將地圖讀取進來。

printMap()是一個打印函數,這毋庸置疑。

getCommand()用于接收玩家在鍵盤中的輸入。

void detect()檢測玩家將要走向方向的前兩個方塊的內容。

int menu()主菜單函數。

int levelChoose()選關函數。

voluationForStar()初始化中點坐標函數。

weatherPass()判斷是否勝利函數。

int gettingData( int smallSquare[SIZE][SIZE] , int number , Player *player , Box box[NUMBER] , int *I , int star[NUMBER][2] ); //用于檢索游戲數據void printMap( int smallSquare[SIZE][SIZE] , Player player , Box box[NUMBER] , int I); //打印地圖int getCommand();//接收用戶輸入。void detect( Player *player , Box box[] , int smallSquare[SIZE][SIZE] ,int *pointerFirst , int *pointerSecond , int command , int I ); //用于探測玩家指向方向前兩塊區域的內容。int menu( ); //創建菜單函數int levelChoose( );//關卡選擇void introduce(); //游戲介紹void voluationForStar( int star[NUMBER][2] );int weatherPass( int star[NUMBER][2] , Box box[NUMBER] , int );

檢索游戲地圖函數:

這個涉及 C++的文件操作。
該函數對于有興趣制作地圖的朋友來說,建議好好學習。

int gettingData( int smallSquare[SIZE][SIZE] ,int number , Player *player , Box box[NUMBER] , int *I , int star[NUMBER][2] ) {char gameLevel[12] = { 'N' , 'u' , 'm' , 'b' , 'e' , 'r' ,0 , '.' , 't' , 'x' , 't' , 0 }; //用于檢索游戲數據。gameLevel[6] = number + 48 ; //整型轉化為字符型,需要統一一下。std::ifstream fileOfGettingGameData;fileOfGettingGameData.open( gameLevel ); //打開游戲配置if( !fileOfGettingGameData ){system("cls");std::cout << "未檢測到關卡" << number << "的存在" << "\n請檢查您在選擇關卡時是否輸入正確。" << std::endl;system("pause");return 0;}/*else{std::cout << "關卡初始化成功" << std::endl; Sleep( 500 );}*///初始化地圖,(檢索游戲文件)int tempI , tempJ , temp = 0 ;//temp用于終點的計數。for( tempI = 0 ; tempI < SIZE ; tempI++ ){for( tempJ = 0 ; tempJ < SIZE ; tempJ++ ){fileOfGettingGameData >> smallSquare[tempI][tempJ];//人物位置單獨計算if( 3 == smallSquare[tempI][tempJ] ){player->placeI = tempI;player->placeJ = tempJ;smallSquare[tempI][tempJ] = 2 ;}//箱子位置單獨計算if( 1 == smallSquare[tempI][tempJ] ){box[ (*I) ].placeI = tempI;box[ (*I) ].placeJ = tempJ;smallSquare[tempI][tempJ] = 2 ;(*I)++;}//終點位置單獨計算if( 4 == smallSquare[tempI][tempJ] ){star[temp][0] = tempI;star[temp][1] = tempJ;temp++;}}}return 1; }

打印地圖函數:

system(“cls”);
該語句可以實現win32的清屏。
在函數定義在windows.h頭文件中。

void printMap( int smallSquare[SIZE][SIZE] , Player player , Box box[NUMBER] , int I ) {int tempI , tempJ , temp ;//temp用于檢索數列boxint weatherPrintBox = 0; //0表示沒有打印箱子,1表示打印了。system("cls");printf(" 0 1 2 3 4 5 6 7 8 9\n");for( tempI = 0 ; tempI < SIZE ; tempI++ ){printf("%d" , tempI);for( tempJ = 0 ; tempJ < SIZE ; tempJ++ ){weatherPrintBox = 0;for( temp = 0 ; temp < I ; temp++ ){if( tempI == box[temp].placeI && tempJ == box[temp].placeJ ){printf("■"); //打印箱子。weatherPrintBox = 1;break;}}if( tempI == player.placeI && tempJ == player.placeJ ){std::cout << "▼"; //打印人物。}else if( 2 == smallSquare[tempI][tempJ] && 0 == weatherPrintBox )//&&運算符后面的語句表示:如果打印了箱子就不必再打印箱子下面的道路。{std::cout << " "; //打印道路。}else if( 0 == smallSquare[tempI][tempJ] ){std::cout << "▓"; //打印墻壁。}else if( 4 == smallSquare[tempI][tempJ] && 0 == weatherPrintBox )//&&運算符后面的語句表示:如果打印了箱子就不必再打印箱子下面的終點。{std::cout << "☆"; //打印終點。}}std::cout << "\n";} }

獲取玩家指令的函數:

_getch();
這個函數定義在conio.h
如果有朋友知道,其他的表示方式,比如說:cin.get();也是可以相互替換的。

int getCommand() {int commandReturn = -1; //表示沒有輸入switch( _getch() ){case 'W':case 'w':commandReturn = 1; //表示向上break;case 'A':case 'a':commandReturn = 2; //表示向左break;case 'S':case 's':commandReturn = 3; //表示向下break;case 'D':case 'd':commandReturn = 4; //表示向右break;case 'B':case 'b':commandReturn = 5; //表示返回選關界面break;case 10 :case 13 :commandReturn = 6; //表示回車break;default:commandReturn = -2; //表示用戶錯誤輸入break;}return ( commandReturn ); }

探測玩家指向方向前兩格方塊內容的函數:

這是代碼里面比較復雜的一塊。
不講了。

void detect( Player *player , Box box[] , int smallSquare[SIZE][SIZE] , int *pointerFirst , int *pointerSecond , int command , int I ) {int tempFirstI , tempFirstJ , tempSecondI , tempSecondJ ; //用于記錄玩家位置的前兩個位置的坐標。int temp; //用于檢索box里的每一個元素。switch ( command ){case 1://計算玩家朝向的兩個方向的方塊的坐標,并且將其賦值。tempFirstI = player->placeI - 1;tempFirstJ = player->placeJ;tempSecondI = player->placeI - 2;tempSecondJ = player->placeJ;if( tempFirstI >= 0 && tempFirstJ >= 0 ) //檢索范圍未超出地圖的情況。{*pointerFirst = smallSquare [tempFirstI][tempFirstJ];}//范圍超出地圖的區塊,將其按墻壁計算。else{*pointerFirst = 0;}if( tempSecondI >= 0 && tempSecondJ >= 0 ) //檢索范圍未超出地圖的情況。{*pointerSecond = smallSquare[tempSecondI][tempSecondJ];}//范圍超出地圖的區塊,將其按墻壁計算。else{*pointerSecond = 0;}//檢索玩家所指向方向的前兩個方塊是否為箱子for( temp = 0 ; temp < I ; temp++ ){if( box[temp].placeI == tempFirstI && box[temp].placeJ == tempFirstJ ){*pointerFirst = 1;}else if( box[temp].placeI == tempSecondI && box[temp].placeJ == tempSecondJ ){*pointerSecond = 1;}}break; /************其后的注釋與上面保持一樣,請朋友們融會貫通。(寫長一點,給自己營造一種感覺,自己都寫了那么多行了。噓~~~~~~~~)*****************************/case 2:tempFirstI = player->placeI;tempFirstJ = player->placeJ - 1;tempSecondI = player->placeI;tempSecondJ = player->placeJ - 2;if( tempFirstI >= 0 && tempFirstJ >= 0 ) //檢索范圍未超出地圖的情況。{*pointerFirst = smallSquare [tempFirstI][tempFirstJ];}//范圍超出地圖的區塊,將其按墻壁計算。else{*pointerFirst = 0;}if( tempSecondI >= 0 && tempSecondJ >= 0 ){*pointerSecond = smallSquare[tempSecondI][tempSecondJ];}else{*pointerSecond = 0;}for( temp = 0 ; temp < I ; temp++ ){if( box[temp].placeI == tempFirstI && box[temp].placeJ == tempFirstJ ){*pointerFirst = 1;}else if( box[temp].placeI == tempSecondI && box[temp].placeJ == tempSecondJ ){*pointerSecond = 1;}}break;case 3:tempFirstI = player->placeI + 1;tempFirstJ = player->placeJ;tempSecondI = player->placeI + 2;tempSecondJ = player->placeJ;if( tempFirstI >= 0 && tempFirstJ >= 0 ) //檢索范圍未超出地圖的情況。{*pointerFirst = smallSquare [tempFirstI][tempFirstJ];}//范圍超出地圖的區塊,將其按墻壁計算。else{*pointerFirst = 0;}if( tempSecondI >= 0 && tempSecondJ >= 0 ){*pointerSecond = smallSquare[tempSecondI][tempSecondJ];}else{*pointerSecond = 0;}for( temp = 0 ; temp < I ; temp++ ){if( box[temp].placeI == tempFirstI && box[temp].placeJ == tempFirstJ ){*pointerFirst = 1;}else if( box[temp].placeI == tempSecondI && box[temp].placeJ == tempSecondJ ){*pointerSecond = 1;}}break;case 4:tempFirstI = player->placeI;tempFirstJ = player->placeJ + 1;tempSecondI = player->placeI;tempSecondJ = player->placeJ + 2;if( tempFirstI >= 0 && tempFirstJ >= 0 ) //檢索范圍未超出地圖的情況。{*pointerFirst = smallSquare [tempFirstI][tempFirstJ];}//范圍超出地圖的區塊,將其按墻壁計算。else{*pointerFirst = 0;}if( tempSecondI >= 0 && tempSecondJ >= 0 ){*pointerSecond = smallSquare[tempSecondI][tempSecondJ];}else{*pointerSecond = 0;}for( temp = 0 ; temp < I ; temp++ ){if( box[temp].placeI == tempFirstI && box[temp].placeJ == tempFirstJ ){*pointerFirst = 1;}else if( box[temp].placeI == tempSecondI && box[temp].placeJ == tempSecondJ ){*pointerSecond = 1;}}break;default:break;} }

還有幾個函數,我并沒有在這里展示,不過有興趣的朋友可以下載源代碼好好學習。
主要是博主實在寫不動了。
你呢,還希望大家能夠通過我的代碼,不斷提高自己的編程能力,不斷的提升。
游戲和源碼的下載鏈接在上面,有大家可以下載下來反復學習喲。

其次看在小博主我寫了這么多的份上,你不點個贊再走嗎?

總結

以上是生活随笔為你收集整理的C++ 推箱子,中配版,支持玩家自己创造地图(无图形库)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。