零基礎教做貪喫蛇——(3)部分函數講解

在上一篇中,我們把這個項目的各個文件都創立了下,而且還在snake.h文件中把我們要用到的函數都列了出來,接下來我們來逐步完善各個函數。
在這裏插入圖片描述

gotoxy函數

爲啥子不按照順序先從initMap開始講嘞?因爲initMap這個函數需要定點輸出,而且我之前說了,在這個項目中我不會使用“\n”這種來輸出界面,所以我們採用定點輸出的方式,爲了方便它的使用,當然是把它打包成一個函數啦。
這個函數沒啥子講的,只是死套模板罷了,只不過我們把x和y作爲函數的輸入就可以了:

void gotoxy(int x, int y)
{
	HANDLE hout;								//Defining handle objects
	COORD cor;									//Defining coordinate objects
	hout = GetStdHandle(STD_OUTPUT_HANDLE);		//Get the handle of the output screen buffer
	cor.X = y;
	cor.Y = x;
	SetConsoleCursorPosition(hout, cor);		//Move Cursor
}

這樣,我們在主函數中導入snake.h頭文件後就可以直接調用這個函數了,而且在snake.c文件中也是。

menu函數

如果你大概玩了下這個小遊戲你就會知道,我們在剛打開這個遊戲的時候,會有個問你玩遊戲還是退出的界面,這個函數就是用來顯示這個界面的。
在這裏插入圖片描述
不知大家還記不記得我們在snake.h裏面定義的一個ret變量,它就是在這裏用來當這個函數的返回值的。

int menu()
{
	gotoxy(12, 42);//移動到12,42的位置
	printf("歡迎來到貪喫蛇小遊戲....");
	gotoxy(14, 45);//移動到14,45的位置
	printf("開始遊戲請按(1)");
	gotoxy(16, 42);//移動到16,42的位置
	printf("按其他任意鍵退出遊戲QAQ");
	gotoxy(18,25);//移動到18,25的位置
	printf("反正閒着也是閒着,不如坐下來來一把緊張又刺激的貪喫蛇如何?┐(‘~`;)┌");
	int ch = getch();//使用ch接收鍵盤輸入的值,getch()作用參考第一章

	while (TRUE)
	{
		if (ch == 49)	//因爲它的 ASCII 值是1,因爲我們的ch是int型
		{
			ret = 1;//則把ret標記爲1,意爲用戶同意玩
			break;
		}
		else
		{
			break;
		}


	}
	system("cls");//把屏幕清空下,方便接下來的顯示界面
	return ret;//把ret的值返回
}

initMap函數

在這裏插入圖片描述
這個函數是用來顯示地圖界面的,它用來初始化蛇的各種信息,果子的座標,和遊戲邊框等地方,是非常重要的函數。我的註釋會打的非常詳細,幫助大家理解

void initMap(void)
{
	ch = UP;//默認的ch爲向前
	Direction = UP;//默認方向爲向前
	//初始化食物
	srand(time(NULL));	//使用當前時間進行隨機數發生器的初始化								
	food.x = rand() % (FRAME_HEIGHT - 2) + 1;//rand( )隨機函數, 食物的x座標爲1到界面最右邊少一個位置中的任意一個值。FRAME_HEIGHT 和FRAME_WIDTH都是我們之前已經宏定義後的值。
	food.y = rand() % (FRAME_WIDTH - 2) + 1;
	gotoxy(food.x, food.y);//定位到我們隨機出的座標
	printf("!");//使用!代表食物
	//初始化蛇
	snake.x[0] = FRAME_HEIGHT / 2;//用地圖的長和寬都除2,從而把蛇頭定位到地圖中央
	snake.y[0] = FRAME_WIDTH / 2;
	gotoxy(snake.x[0], snake.y[0]);//到地圖中央的地方
	printf("@");//用@表示蛇身
	snake.len = 3;//初始蛇的長度是3個
	snake.speed = 200;//默認蛇的速度是200
	for (k = 1; k<snake.len; k++)//從正中央的地點開始後3個把蛇的身子部分都顯示出來
	{
		snake.x[k] = snake.x[k - 1] + 1;
		snake.y[k] = snake.y[k - 1];
		gotoxy(snake.x[k], snake.y[k]);
		printf("@");
	}
	//初始化地圖
	for (j = 0; j<FRAME_WIDTH; j++)//初始化寬
	{
		gotoxy(0, j);
		printf("#");//是用#表示邊界
		gotoxy(FRAME_HEIGHT - 1, j);
		printf("#");
	}
	for (i = 1; i<FRAME_HEIGHT - 1; i++)//初始化長
	{
		gotoxy(i, 0);
		printf("#");
		gotoxy(i, FRAME_WIDTH - 1);
		printf("#");
	}
}

printFont函數

在這裏插入圖片描述
這個函數主要是顯示一些遊戲信息啊神馬的東西與遊戲內容無關,主要是加強遊戲體驗的東西。爲了方便,這個函數的入口參數就弄了倆,其他輸出地點的座標直接計算出來,emm至於計算公式,,不用太深究,,慢慢調出來的,主要是爲了美觀。

void printFont(int x, int y, int speed)
{
	int i = 1;//定義一個變量,後面計算用
	gotoxy(x, y);
	printf("反正閒着也是閒着,不如坐下來來一把緊張又刺激的貪喫蛇如何?");

	gotoxy(x + ADD, y);//ADD也是我們在snake.h裏面定義的一個常量,現在用作計算座標用,大家隨意處理即可
	if (speed == 200)//根據速度顯示數度級數
	{
		printf("現在的速度是:%d級", i);
	}
	else if (speed == 175)
	{
		printf("現在的速度等級是:%d級", i + 1);
	}
	else if (speed == 150)
	{
		printf("現在的速度等級是:%d級", i + 2);
	}
	else if (speed == 100)
	{
		printf("現在的速度等級是:%d級", i + 3);
	}
	else
	{
		printf("恭喜你,召喚師,現在是最高級");
	}
	gotoxy(x + 2 * ADD, y);
	printf("上下左右操作鍵分別是:w,s,a,d");

	gotoxy(x + 3 * ADD, y);
	printf("當喫到自己身體或者撞牆時遊戲結束");

	gotoxy(x + 4 * ADD, y);
	printf("按空格鍵暫停,在按空格鍵繼續");
}

updataFood函數

這個函數主要是用來更新了食物的,它用來判斷食物是否被喫,如果被喫掉了就再隨機出一個新的食物。。
至於怎麼判斷食物是否被喫掉了,很簡單,直接判斷蛇頭的座標是否和食物的座標一樣就可與了,,emm,,但是後來我玩這個遊戲的時候,發現這個bug,因爲食物是全圖生成的,如果生成的食物在蛇的身上,它會隨着蛇的移動,輸出的食物圖標“!”被覆蓋,隨後消失。而且不會生成新的食物。。。說白了,按照上面的邏輯,這個bug就是食物沒了,而且不再生成。

所以我把它的判斷邏輯小改了下——當食物的座標在蛇的身體中時,它才判定食物被喫掉了。

void updataFood()
{
    int iseat=0;//用作標記食物是否被喫,默認爲沒有被喫
    for(int i=0;i<snake.len;i++){//循環判斷,食物的座標是否以在蛇的身體中
        if(snake.x[i]==food.x&&snake.y[i]==food.y){
            iseat=1;//如果時,則記錄食物被吃了
            break;
        }
    }
	if (iseat)//當食物被吃了後,再次隨機新的食物
	{
		srand(time(NULL));//不明白的參考第一章
		food.x = rand() % (FRAME_HEIGHT - 2) + 1;//使用取餘的方式,把隨機的結果固定在地圖範圍中
		food.y = rand() % (FRAME_WIDTH - 2) + 1;
		gotoxy(food.x, food.y);
		printf("!");
		snake.len++;//由於食物被吃了,蛇的長度加一
		grow = 1;//是否增長標記爲是,這個變量也是snake.h宏定義過的
	}
}

好了,今天就先講解這麼多,剩下的明天再講吧,,,畢竟打字打的手有點疼在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章