生活随笔
收集整理的這篇文章主要介紹了
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
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()
{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;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;}int tempI
, tempJ
, temp
= 0 ;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
;int weatherPrintBox
= 0; 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
; 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++ 推箱子,中配版,支持玩家自己创造地图(无图形库)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。