目錄
前言
代碼撰寫思路
1.游標移動函式
2.地圖
3.人物的移動(核心)
4.選單、結束陳述句
5.附完整代碼:
總結
優點:
缺點:
前言
筆者乃初學C語言,萌新一枚,深感C語言之博大,自嘆所學之淺薄,今突發奇想,嘗試用最簡單之所學,撰寫了一款走迷宮小游戲,望各位大佬看后能在忍俊不禁之余,多多指教,

代碼撰寫思路
1.游標移動函式
考慮到此程式運行程序中,需要不斷在界面不同位置列印輸出各種陳述句和字符,因此先通過撰寫自定義函式的方式,實作將游標移動至指定位置,呼叫時只需將游標所需移動位置的橫豎坐標輸入,
注:橫坐標x從左向右,縱坐標y從上向下,初始值為(0,0),如圖所示:

由于筆者的作業系統是windows,因此為檔案添加了“windows.h”的頭檔案,其中包含了其他的 Windows 頭檔案,這些頭檔案的部分也包含了其他頭檔案:
具體代碼如下:
void goto_xy(int x,int y) //移動游標到指定位置
{
HANDLE hout;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos={x,y};
SetConsoleCursorPosition(hout,pos);
}
2.地圖
定義一個靜態全域二維陣列map_way[20][20],其中我將用“0”代表通路,“1”代表墻壁,“2”代表陷阱,“3”代表終點,當呼叫自定義函式map時,將列印出地圖,
代碼如下(示例):
static int map_way[20][20]={{1,1,1,1,1,1,1,1,1,1},{0,0,0,1,0,0,0,0,0,1},{1,1,0,0,0,2,1,1,0,1},{1,0,0,1,1,1,1,0,0,1},{1,2,1,1,0,0,0,0,1,1},{1,0,0,0,0,1,0,1,0,3},{1,0,1,1,1,1,0,1,0,1},{1,0,1,0,0,0,2,1,0,1},{1,0,0,0,1,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1}};
void map()
{
int i,j;
goto_xy(0,0);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
if(map_way[i][j]==1)
printf("▓");//墻壁
else if(map_way[i][j]==2)
printf("※");//陷阱
else if(map_way[i][j]==3)
printf("★");//終點
else
printf(" ");//通路
}
printf("\n");
}
}
呼叫函式效果如圖所示:

3.人物的移動(核心)
定義兩個全域變數man_x、man_y,分別代表當前人物所處坐標,這里我們需要對其初始化,因地圖設計,入口位置為(0,1),所以初始化為man_x=0,man_y=1,當呼叫自定義函式move時,通過輸入w、s、a、d,控制人物的上、下、左、右移動,當人物的坐標與之前定義的地圖中各位置相重合時,執行不同的指令,
注:要考慮到字符的全角與半角,即像“▓”、“※”、“★”的這些字符,會占兩個標準字符位置,故在呼叫游標移動函式及轉義字符“\b”時,要考慮到
具體代碼如下:
int man_x=0,man_y=1;
int move() //為了能在運行程序中通過回傳值的方式,提前退出當前函式,故將函式定義為了int型
{
int i,j;
char anjian;
goto_xy(man_x,man_y);
printf("☆");
while(1)
{
goto_xy(30,0); //指定位置讀入
anjian=getchar();
switch(anjian) //讀入不同的字符,對應人物不同的移動方向
{
case 'a':
if(map_way[man_y][man_x-1]==1) //與墻壁相沖突
{
goto_xy(30,5);
printf("撞墻!"); //列印提示陳述句
break;
}
else if(map_way[man_y][man_x-1]==2) //掉入陷阱
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!"); //列印提示陳述句
return 0; //退出
}
else if(map_way[man_y][man_x-1]==3) //到達終點
{
goto_xy(30,4);
printf("恭喜你,成功通關!"); //列印提示陳述句
return 0; //退出
}
else //將人物向指定位置移動
{
goto_xy(man_x*2,man_y); //代表人物的字符☆占兩個標準字符位置,應此要乘2
printf(" \b\b☆"); //原因同上
man_x--;
goto_xy(30,5);
printf(" "); //抹去之前列印的提示陳述句
break;
}
case 'd':
if(map_way[man_y][man_x+1]==1)
{
goto_xy(30,5);
printf("撞墻!");
break;
}
else if(map_way[man_y][man_x+1]==2)
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!");
return 0;
}
else if(map_way[man_y][man_x+1]==3)
{
goto_xy(30,4);
printf("恭喜你,成功通關!");
return 0;
}
else
{
goto_xy(man_x*2,man_y);
printf(" ");
printf("☆");
man_x++;
goto_xy(30,5);
printf(" ");
break;
}
case 'w':
if(map_way[man_y-1][man_x]==1)
{
goto_xy(30,5);
printf("撞墻!");
break;
}
else if(map_way[man_y-1][man_x]==2)
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!");
return 0;
}
else if(map_way[man_y-1][man_x]==3)
{
goto_xy(30,4);
printf("恭喜你,成功通關!");
return 0;
}
else
{
goto_xy(man_x*2,man_y);
printf(" ");
goto_xy(man_x*2,man_y-1);
printf("☆");
man_y--;
goto_xy(30,5);
printf(" ");
break;
}
case 's':
if(map_way[man_y+1][man_x]==1)
{
goto_xy(30,5);
printf("撞墻!");
break;
}
else if(map_way[man_y+1][man_x]==2)
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!");
return 0;
}
else if(map_way[man_y+1][man_x]==3)
{
goto_xy(30,4);
printf("恭喜你,成功通關!");
return 0;
}
else
{
goto_xy(man_x*2,man_y);
printf(" ");
goto_xy(man_x*2,man_y+1);
printf("☆");
man_y++;
goto_xy(30,5);
printf(" ");
break;
}
}
}
}
4.選單、結束陳述句
撰寫選單函式,呼叫時將列印出游戲名稱、各符號所代表的含義、操作方法等等,
撰寫結束陳述句函式,在程式運行最后呼叫,
具體代碼如下:
void menu()
{
goto_xy(0,12);
printf("《迷宮》");
goto_xy(0,13);
printf("上:w\t墻壁: \"▓\"\n下:s\t陷阱:\"※\"\n左:a\t終點:\"★\"\n右:d\t人物:\"☆\"\n(注:由于水平有限,每按一次移動按鍵都需按一下回車)");
}
void end()
{
goto_xy(30,5);
printf("GAME OVER!");
goto_xy(0,18);
}
呼叫函式效果如圖所示:

5.附完整代碼:
#include<stdio.h>
#include<windows.h>
static int map_way[20][20]={{1,1,1,1,1,1,1,1,1,1},{0,0,0,1,0,0,0,0,0,1},{1,1,0,0,0,2,1,1,0,1},{1,0,0,1,1,1,1,0,0,1},{1,2,1,1,0,0,0,0,1,1},{1,0,0,0,0,1,0,1,0,3},{1,0,1,1,1,1,0,1,0,1},{1,0,1,0,0,0,2,1,0,1},{1,0,0,0,1,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1}};
int man_x=0,man_y=1;
void goto_xy(int x,int y) //移動游標到指定位置
{
HANDLE hout;
hout=GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos={x,y};
SetConsoleCursorPosition(hout,pos);
}
void menu()
{
goto_xy(0,12);
printf("《迷宮》");
goto_xy(0,13);
printf("上:w\t墻壁: \"▓\"\n下:s\t陷阱:\"※\"\n左:a\t終點:\"★\"\n右:d\t人物:\"☆\"\n(注:由于水平有限,每按一次移動按鍵都需按一下回車)");
}
void end()
{
goto_xy(30,5);
printf("GAME OVER!");
goto_xy(0,18);
}
void map()
{
int i,j;
goto_xy(0,0);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
if(map_way[i][j]==1)
printf("▓");//墻壁
else if(map_way[i][j]==2)
printf("※");//陷阱
else if(map_way[i][j]==3)
printf("★");//終點
else //if(map_way[i][j]==0)
printf(" ");//通路
}
printf("\n");
}
}
int move() //為了能在運行程序中通過回傳值的方式,提前退出當前函式,故將函式定義為了int型
{
int i,j;
char anjian;
goto_xy(man_x,man_y);
printf("☆");
while(1)
{
goto_xy(30,0); //指定位置讀入
anjian=getchar();
switch(anjian) //讀入不同的字符,對應人物不同的移動方向
{
case 'a':
if(map_way[man_y][man_x-1]==1) //與墻壁相沖突
{
goto_xy(30,5);
printf("撞墻!"); //列印提示陳述句
break;
}
else if(map_way[man_y][man_x-1]==2) //掉入陷阱
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!"); //列印提示陳述句
return 0; //退出
}
else if(map_way[man_y][man_x-1]==3) //到達終點
{
goto_xy(30,4);
printf("恭喜你,成功通關!"); //列印提示陳述句
return 0; //退出
}
else //將人物向指定位置移動
{
goto_xy(man_x*2,man_y); //代表人物的字符☆占兩個標準字符位置,應此要乘2
printf(" \b\b☆"); //原因同上
man_x--;
goto_xy(30,5);
printf(" "); //抹去之前列印的提示陳述句
break;
}
case 'd':
if(map_way[man_y][man_x+1]==1)
{
goto_xy(30,5);
printf("撞墻!");
break;
}
else if(map_way[man_y][man_x+1]==2)
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!");
return 0;
}
else if(map_way[man_y][man_x+1]==3)
{
goto_xy(30,4);
printf("恭喜你,成功通關!");
return 0;
}
else
{
goto_xy(man_x*2,man_y);
printf(" ");
printf("☆");
man_x++;
goto_xy(30,5);
printf(" ");
break;
}
case 'w':
if(map_way[man_y-1][man_x]==1)
{
goto_xy(30,5);
printf("撞墻!");
break;
}
else if(map_way[man_y-1][man_x]==2)
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!");
return 0;
}
else if(map_way[man_y-1][man_x]==3)
{
goto_xy(30,4);
printf("恭喜你,成功通關!");
return 0;
}
else
{
goto_xy(man_x*2,man_y);
printf(" ");
goto_xy(man_x*2,man_y-1);
printf("☆");
man_y--;
goto_xy(30,5);
printf(" ");
break;
}
case 's':
if(map_way[man_y+1][man_x]==1)
{
goto_xy(30,5);
printf("撞墻!");
break;
}
else if(map_way[man_y+1][man_x]==2)
{
goto_xy(30,4);
printf("很遺憾,你掉入了陷阱!");
return 0;
}
else if(map_way[man_y+1][man_x]==3)
{
goto_xy(30,4);
printf("恭喜你,成功通關!");
return 0;
}
else
{
goto_xy(man_x*2,man_y);
printf(" ");
goto_xy(man_x*2,man_y+1);
printf("☆");
man_y++;
goto_xy(30,5);
printf(" ");
break;
}
}
}
}
int main()
{
menu();
map();
move();
end();
system("pause");//若要生成可執行檔案,加上此句可確保不會閃退
return 0;
}
運行效果圖:

總結
優點:
1.地圖搭建較為容易,只需改變定義的二維陣列map_way,即可改變地圖,(但需考慮到選單等界面布局,不然只增大地圖易導致部分輸出內容重疊,產生未知錯誤)
2.采用數字代替特殊字符的方式,降低撰寫難度,增強代碼的可讀性,
3.涉及到的知識簡單易懂,除了自定義的游標移動函式外,并未涉及到諸如指標、鏈表、檔案等較為深奧的東西,(筆者在為自己的菜找借口)
缺點:
1.未能實作地圖的隨機生成,搭建地圖的方式僵硬呆板,若要搭建更大的地圖,例如40×40的地圖,則需初始化總計1600個數字,作業量無疑是巨大的,
2.在輸入控制人物移動的字符時,仍需輸入一個字符按一下enter鍵,無疑影響游戲體驗,
3.游戲界面只是基本的字符,沒有復雜美觀的圖案,看起來單調乏味,


轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/288886.html
標籤:其他
上一篇:HCNA Routing&Switching之靜態路由
下一篇:運籌學之動態規劃部分
