1. 程式人生 > 程式設計 >C語言實現推箱子游戲的地圖編輯器

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()函式可能在其他編譯器上編譯會出現錯誤,解決辦法是去掉函式前面的“_”。

同時,要將 檔案開啟函式fopen_s(&fp,FLPA,“r”);更改為fp = fopen(FLPA,“r”);
fcanf_s更改為fcanfscanf_s()更改為scanf

執行效果:

C語言實現推箱子游戲的地圖編輯器

程式碼實現:

//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);
}

如果對於程式程式碼註釋有我沒寫明白的地方,歡迎在評論區下方留言詢問,如果我看到會盡最大的努力為您解惑。

不足之處:

暫不明確,歡迎提出建議。

最後,感謝所有願意對我提出批評和建議的人,你們的支援是我堅持下去的強大動力。