C語言實現推箱子游戲的地圖編輯器
推箱子地圖編輯器,供大家參考,具體內容如下
由於我在寫推箱子的時候苦於沒有地圖可以試驗程式執行效果,而且去搜了好長時間都沒有找到一個儲存16*16地圖版本的推箱子關卡資料資訊的檔案。
於是想到了寫了一個地圖編輯器用來自己設計地圖的想法。
原本以為這個偉大的創意只有我才想的出來,結果搜尋後才發現還有很多人有著與我相同的想法。
但,其他人寫的編輯器大部分都不是C語言版本的,而這一個是C語言版本的。
另外說明一下,該編輯器的想法完全是我個人想法寫出來的,不敢保證編輯習慣符合別人的習慣。
但本著,能夠實現需求,程式就是正確的原則,我自己對這個程式還是比較有信心的。
執行使用程式碼前,請檢視程式碼最前面的詳細使用說明註釋,以免對您造成不便
如果您喜歡我的文章可以點贊支援一下。
如果您對我的程式有什麼意見和建議歡迎在評論區發表評論。
另外附上作者自寫的推箱子游戲程式碼 可以適配該編輯器:
推箱子游戲執行程式
下面進入技術環節:
使用C語言實現 16*16推箱子 地圖編輯器
編譯環境: Windows VS2019
其他大部分編譯環境,可通過檢視下文的“注意事項”將程式碼更正為其他平臺可正常編譯執行版本
需求:
通過移動游標在對應位置輸出方塊實現編輯地圖功能,編輯完成後按下z鍵將地圖儲存進txt中。
思路:
將螢幕上的游標座標*2與地圖陣列下標對應起來,在螢幕上進行輸出操作就是對對應陣列下標進行賦值操作,編輯完成後按下z鍵即可將地圖資訊儲存進文字檔案中。
做法:
首先輸出16*16的空地,getch函式即時接收鍵盤輸入資訊,wasd控制游標移動,輸入1-5可放置不同的地圖元素,z鍵將地圖資訊儲存進文字檔案並退出程式。
具體詳細做法請檢視程式碼。
使用到知識點:
迴圈、二維陣列、寫入檔案
難點:
無
說明:
1 ■ 代表牆,2 ★ 代表目標,3 ● 代箱子,4 ♀ 代表人物,else □ 代表空地
地圖大小為16*16。
數字代表的事物必須和遊戲中相匹配,也可以通過更改程式來代表其他事物,以適配遊戲程式。
使用編輯器之前應先將程式碼中的FLMOP巨集所代表的檔案路徑更改正確。
注意:
由於編譯器原因程式中_kbhit()和_getch()函式可能在其他編譯器上編譯會出現錯誤,解決辦法是去掉函式前面的“_”。
fcanf_s更改為fcanfscanf_s()更改為scanf
執行效果:
程式碼實現:
//C語言推箱子地圖編輯器 詳細使用說明: //1 ■ 代表牆,2 ★ 代表目標,3 ● 代箱子,4 ♀ 代表人物,else □ 代表空地 //推箱子exe檔案程式 使用本編輯器的前提條件是:使用二維陣列寫出整個遊戲結構、地圖大小為16*16、 \ 、數字與之所代表的事物相匹配。 //使用該編輯器之前必須先確定檔案路徑FLMOP巨集所替代的字串路徑在自己的電腦上準確無誤並可以訪問。 \ 否則會造成地圖編輯完成後無法儲存!!! //該編輯器在絕大多數情況下都可以正常使用並儲存。但如在遊戲程式中出現地圖位置錯亂的情況,在檢查遊戲程式 \ 問題無誤後請檢查編輯器所使用的地圖檔案內地圖資訊是否異常。 //如過您使用的是作者所配套使用的遊戲程式,且遊戲程式和地圖資訊都無異常,請嘗試調整遊戲程式內 \ BYT巨集(一關卡字數)所代表的字數資訊。該異常可能是檔案隨機讀寫函式錯誤的二進位制轉換導致的。 //以上錯誤情況頻率僅代表極少數情況,可放心使用 //作者:白家名 #include <stdio.h> #include <windows.h> #include <conio.h> //使用推箱子地圖編輯器,輕鬆編輯出多種多樣的複雜關卡 //wasd鍵控制游標,z鍵將地圖資訊儲存進檔案並結束程式 //1 ■ 代表牆,2 ★ 代表目標,3 ● 代箱子,4 ♀ 代表人物、else □ 代表空地 //注意:如使用作者的配套遊戲執行程式使用地圖,不可以地圖邊界作為限制人物活動的牆壁使用 #define N 16 //地圖寬高 #define FLMOP "C:\\Users\\ASUS\\Desktop\\編輯器地圖.txt" void gotoxy(int x,int y); //游標定位 void fxscdt(); //翻譯輸出地圖 void ckydgbhs(); //控制移動和設定元素函式 int map[N][N]; //地圖陣列 char ck; //讀方向鍵 int x,y; //游標座標(x*2) int main() //主函式控制所有 { system("title 推箱子地圖編譯器1.0"); system("mode con cols=78 lines=31"); fxscdt(); //輸出地圖和使用說明 while (1) { ckydgbhs(); //控制游標移動 gotoxy(42,2); //輸出游標位置資訊 printf(" "); gotoxy(42,2); printf("%d %d",x,y); //游標 gotoxy(x << 1,y); //i橫軸,j縱軸,橫座標乘2和陣列的下標相對應 Sleep(60); } gotoxy(0,40); return 0; } void dszcz() //編輯結束後輸出陣列 { gotoxy(0,21); printf("是否確認儲存並退出地圖編輯器?! z 確認"); char tch= _getch(); if (tch != 'z') return; //輸入z確認繼續 FILE* fp = NULL; //將地圖陣列儲存進所選檔案路徑中 fopen_s(&fp,FLMOP,"a+"); //追加方式開啟檔案 for (int i = 0; i < N; i++) //將地圖資訊寫入檔案 { for (int j = 0; j < N; j++) fprintf(fp,"%d ",map[i][j]); fprintf(fp,"\n"); } fprintf(fp,"\n"); fclose(fp); gotoxy(0,24); printf("恭喜!地圖資訊新增成功! %s",FLMOP); gotoxy(0,26); exit(0); } void ckydgbhs() //方向和設定元素 { ck = _getch(); //接收 switch (ck) { case 'w': y--; //游標移動 if (y < 0) //對游標的移動位置加以限制 { y = 0; return; } break; case 'a': x--; if (x < 0) { x = 0; return; } break; case 's': y++; if (y > 15) { y = 15; return; } break; case 'd': x++; if (x > 15) { x = 15; return; } break; case '1': printf("■"); break; case '2': printf("★"); break; case '3': printf("●"); break; case '4': printf("♀"); break; default: printf("□"); ck = '0'; //輸入其他ch為0空格 break; case 'z': dszcz(); //z結束編輯地圖 } if (ck != 'w' && ck != 'a' && ck != 's' && ck != 'd' && ck != 'z') //不是移動和儲存時,將ck值儲存進陣列中 map[y][x] = ck - '0'; } void fxscdt() //輸出初始地圖 { int i,j; //迴圈用變數 gotoxy(0,0); for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { switch (map[i][j]) { case 1: printf("■"); case 2: printf("★"); case 3: printf("●"); case 4: printf("♀"); default: printf("□"); } } printf("\n"); } gotoxy(42,0); printf("游標 現在的 x y 座標:"); gotoxy(42,5); printf("16 * 16 推箱子 地圖編輯器"); gotoxy(42,8); printf("wsad 鍵控制游標上下左右移動"); gotoxy(42,10); printf("按下 e 鍵可放置方塊,輸入1-5的數字"); gotoxy(42,12); printf("1 ■ 牆壁 \t2 ★ 目標"); gotoxy(42,14); printf("3 ● 箱子 \t4 ♀ 人"); gotoxy(42,16); printf("其他 □ 空地"); gotoxy(0,19); printf("確認路徑後無誤後 按下 z 鍵享受一鍵無憂儲存地圖!(a+)"); gotoxy(0,0); } void gotoxy(int x,int y) { COORD pos = { x,y }; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); }
如果對於程式程式碼註釋有我沒寫明白的地方,歡迎在評論區下方留言詢問,如果我看到會盡最大的努力為您解惑。
不足之處:
暫不明確,歡迎提出建議。
最後,感謝所有願意對我提出批評和建議的人,你們的支援是我堅持下去的強大動力。