用C語言數組編寫貪喫蛇

以下是觀看B站up主後整理的筆記,點擊進入老師的視頻

一.製作開始界面

void one_interface() {
	printf("\n\n\n");
	printf("\t\t\t\t\t\t--------------------\n");
	printf("\n");
	printf("\t\t\t\t\t\t歡迎來到貪喫蛇遊戲\n");
	printf("\n");
	printf("\t\t\t\t\t\t請按下空格進入遊戲\n");
	printf("\n");
	printf("   \t\t\t\t\t      根據 w a s d方向鍵控制\n");
	printf("--------------------------------------------------------------------------------------------------------------\n");
}

二.製作音樂播放器

注:音頻必須時wav,且要和可執行程序放在一起在這裏插入圖片描述

#include<mmsystem.h>//音頻頭文件
#pragma comment(lib, "WINMM.LIB")//音頻必加
void myPlaySound()
{
	PlaySound("1.wav", NULL, SND_FILENAME | SND_ASYNC);
}

三.製作空格進入遊戲界面

#include<conio.h>//_getch頭文件
void _space()
{
	while (1)
	{
		char charSpace;
		charSpace = _getch();//輸入自動讀進charSpace
		if (' ' == charSpace)
		{
			break;
		}
	}
}

四.製作關閉音樂

void stop_MyPlaySound()
{ 
	PlaySound( NULL,0,0);
}

五.製作遊戲界面

(1)另取一個頭文件head.h:將數組myArray[20][42]放進去,然後在源文件裏獲取頭文件#include"head.h"

char myArray[20][42] = { "■■■■■■■■■■■■■■■■■■■■\n",//一個■佔用兩字節
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■                                    ■\n",
							 "■■■■■■■■■■■■■■■■■■■■\n" };

(2)在源文件輸出

void two_interface()
{
	int i = 0;
		for (i = 0;i < 20; i++)
		{
			printf(myArray[i]);
		}
}

六.製作蛇身位置

(1)定義座標(2)定義方向 enum { East = 2, South = 1, West = -2, North =- 1 };//枚舉方向
疑惑點:爲什麼y是行,x2x\ast2是列。
答:將myArray數組用座標表示,y的數就相當於行數,由於方塊佔兩字節,所以x的數等於x2x\ast2
ArraySnake[20][3]的數組

y x*2 enum 蛇頭
y x*2+2 enum 蛇身
y x*2+4 enum 蛇尾

head.h中定義int arraySnake[x_pos][3] = { 0 };

//蛇的座標
void set_snakePos()
{
	int x=-1,y=-1;//設置座標
	srand((unsigned int)time (NULL));//獲得隨機數
	x = rand() % 14+3;
	y = rand() % 14+3;
	//設置🐍的數組
	arraySnake[0][0] = y;//行
	arraySnake[0][1] = x*2;//列
	arraySnake[0][2] = West;
	//蛇頭
	arraySnake[1][0] = y;
	arraySnake[1][1] = x*2+2;
	arraySnake[1][2] = West;
	//蛇身
	arraySnake[2][0] = y;
	arraySnake[2][1] = x*2+4;
	arraySnake[2][2] = West;
	//蛇尾
	set_snake();
}

七.製作蛇身

myArray[20][42]數組

myArray[y][x*2] myArray[y][x*2+4] myArray[y][x*2+6]
y行x*2列 y行x*2+4列 y行x*2+6列

通過數組形成一條這樣子的蛇:◆◆◆

#pragma warning (disable : 4996)//strncpy不安全,得加上
//蛇身
void set_snake()
{
	for (int i = 0; arraySnake[i][0] != 0; i++)
	{
		strncpy(&myArray[arraySnake[i][0]][arraySnake[i][1]], "◆",2 );//拷貝
	}
}

八.製作蛇跑

解釋:因爲x_pos值二十,所以只能取0~19的下標,然後從第19個數開始遍歷,等到獲取有效數字就向前移動,否則過濾掉。

y x2x*2 方向
19

head.h中定義int snakeDir = West;

void set_snakeRun()
{
	int i = x_pos - 1;
	set_direction();
	delete_ophiurid();//刪除原來的蛇
	
	for (i;i>=1;i--)
	{
		//過濾掉非法🐍
		if (0 == arraySnake[i][1])
		{
			continue;
		}
		//把前一個結點的值,賦值給當前結點
		arraySnake[i][0] = arraySnake[i-1][0];//行
		arraySnake[i][1] = arraySnake[i-1][1];//列
		arraySnake[i][2] = arraySnake[i-1][2];//方向
	}
	//初始向西移動
	arraySnake[0][2] = snakeDir;
	if (West== arraySnake[0][2]||East== arraySnake[0][2])
	{
		arraySnake[0][1] += arraySnake[0][2];//列加二或減二
	}
	else
	{
		arraySnake[0][0] += arraySnake[0][2];//行加二或減二
	}
	set_snake();
	
}

解析:
   原本蛇是◆◆◆這樣子的,然後蛇頭向前移兩字節,原來蛇頭不變,蛇身變成蛇頭,蛇尾不變(如果設置拷貝的蛇頭是‘’█‘’,那麼蛇出來是█ █ █ ◆)

剛開始

蛇頭
蛇身
蛇尾

arraySnake數組移動下標後:
解析:就相當域蛇身獲取了蛇頭元素,蛇尾獲取了蛇身的元素

蛇頭
蛇頭
蛇身
蛇尾

座標加2,myArray 數組移動後
然後放到main函數裏面while(1)循環,座標x一直加2,蛇頭一直向前

蛇頭
蛇頭
蛇頭
蛇身

九.製作消去蛇尾

注意:先消去蛇尾在跑set_snakeRun()
原因:把舊蛇換成空格,那麼畫新蛇的時候就剛好吧原來蛇頭蛇身的位置覆蓋掉,消去蛇尾

//消除尾節點
void delete_ophiurid()
{
	for (int i = 0; arraySnake[i][0] != 0; i++)
	{
		strncpy(&myArray[arraySnake[i][0]][arraySnake[i][1]], "  ", 2);//空兩格,因爲正方體是佔兩個節點
	}
}

十.製作按鍵移動方向

知識點:short 兩字節,高字節0000 0010(可以一直按返回!0),低字節 0000 0001(只要按一下就一直返回1)
先在head.h裏設置一個全局變量snakeDir=East;
然後在第八步驟設置方向那裏設置snakeDir=arraySnake[0][2].

void set_direction()
{
	//_getch同步檢測:必須得輸入才能運行,每次循環都得輸入
	if (GetAsyncKeyState('W'))//異步檢測:如果輸入字母就改變阿,不輸入就跳過這個函數🐍繼續動
	{
		if (South != arraySnake[0][2])//如果蛇頭不向南移動,纔可以點擊s鍵向北,否則無效
		{
			snakeDir = North;
		}
	}
	else if (GetAsyncKeyState('A'))
	{
		if (East != arraySnake[0][2])
		{
			snakeDir = West;
		}
	}
	else if (GetAsyncKeyState('S'))
	{
		if (North != arraySnake[0][2])
		{
			snakeDir = South;
		}
	}
	else if (GetAsyncKeyState('D'))
	{
		if (West != arraySnake[0][2])
		{
			snakeDir = East;
		}
	}
}

十一.蛇死亡

head.h中定義#define true 1 #define false 0

bool set_snakeDead()
{
	
	if (East == arraySnake[0][2] || West == arraySnake[0][2])
	{
		if ( 0 == strncmp(&myArray[arraySnake[0][0]][arraySnake[0][1] + arraySnake[0][2]], "■", 2))
		{
			return false;
		}
		else if(0 == strncmp(&myArray[arraySnake[0][0] + arraySnake[0][2]][arraySnake[0][1]], "◆", 2))
		{
			return false;
		}
	}
	else
	{
		if ( 0 == strncmp(&myArray[arraySnake[0][0] + arraySnake[0][2]][arraySnake[0][1]], "■", 2))
		{
			return false;
		}
		else if (0 == strncmp(&myArray[arraySnake[0][0] + arraySnake[0][2]][arraySnake[0][1]], "◆", 2) )
		{
			return false;
		}
	}
	return true;

}

十二.食物生成

head.h中定義#define x_pos 20 int g_Nx ,g_Ny ; typedef int bool;//定義bool類型的變量 bool g_proFood = true;

void set_snakeFood()
{
	//如果有食物就返回,沒有點添加食物
	if (false == g_proFood)
	{
		return ;
	}
	//設置座標
	srand((unsigned int)time(NULL));//獲得隨機數
	g_Nx = rand() % 16 +2;
	g_Ny = rand() % 16 + 2;
	bool a_pos = true;
	while (1)
	{
		for (int i = 0; arraySnake[i][0] != 0; i++)
		{
			if (g_Nx * 2 == arraySnake[i][1] &&g_Ny == arraySnake[i][0])
			{
				a_pos = false;
			}
		}
		if (true == a_pos)
		{
			break;
		}
	}
	strncpy(&myArray[g_Ny][g_Nx*2], "●", 2);//不要忘記乘二,卡在這裏好久了
	//添加食物後變成false
	g_proFood = false;
}

十三.蛇長大

head.h中定義蛇長大的成員變量int g_x = 2;

void set_snakeUp()
{
	
	//如果蛇頭和食物座標相同1。蛇增長
	if (g_Nx*2 == arraySnake[0][1] && g_Ny == arraySnake[0][0])
	{
		//蛇長大
		/*不明白的地方:爲什麼arraySnake[g_x][0];
							  arraySnake[g_x][0]-2;
							  arraySnake[g_x][0];這也能編譯出來*/
		if (East==arraySnake[g_x][2])
		{
			arraySnake[g_x+1][0] = arraySnake[g_x][0];//行
			arraySnake[g_x+1][1] = arraySnake[g_x][1]-2;//列
			arraySnake[g_x+1][2] = arraySnake[g_x][2];//方向
		}
		else if (West == arraySnake[g_x][2])
		{
			arraySnake[g_x + 1][0] = arraySnake[g_x][0];//行
			arraySnake[g_x + 1][1] = arraySnake[g_x][1] + 2;//列
			arraySnake[g_x + 1][2] = arraySnake[g_x][2];//方向
		}
		else if (South == arraySnake[g_x][2])
		{
			arraySnake[g_x + 1][0] = arraySnake[g_x][0]+1;//行
			arraySnake[g_x + 1][1] = arraySnake[g_x][1];//列
			arraySnake[g_x + 1][2] = arraySnake[g_x][2];//方向
		}
		else if (North == arraySnake[g_x][2])
		{
			arraySnake[g_x + 1][0] = arraySnake[g_x][0]-1;//行
			arraySnake[g_x + 1][1] = arraySnake[g_x][1] ;//列
			arraySnake[g_x + 1][2] = arraySnake[g_x][2];//方向
		}
		g_x++;
		//如果蛇吃了食物就沒有食物了,返回true給set_snakeFood()添加食物
		g_proFood = true;
		g_score++;
	}
}

十四.設置分數

head.h中定義分數變量int g_score = 0;

void set_score()
{
	COORD rd;
	rd.X = 45;
	rd.Y = 2;
	//設置位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),rd);
	//打印
	printf("score\n");
	rd.X = 47;
	rd.Y = 4;
	//設置位置
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), rd);
	//打印
	printf("%d\n",g_score);
}

十五.main函數運行

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>//_getch頭文件
#include <time.h>//獲取時間數函數
#include"head.h"
#include<windows.h>//定義局部變量
#include<mmsystem.h>//音頻頭文件
#pragma comment(lib, "WINMM.LIB")//音頻必加
#pragma warning (disable : 4996)//strncpy不安全,得加上
int main(void)
{
	one_interface();//初始界面
	myPlaySound();//音頻
	_space();//點擊空格鍵進入遊戲界面
	system("cls");//清屏
	printf("\t\t\t\t\t\t歡迎進入遊戲\n");
	Sleep(2000);
	stop_MyPlaySound();// 先消去再跑,順序不能亂
	set_snakePos();//這個函數必須放在界面上面才能顯示
	
	while (1)
	{
		system("cls");
		
		set_snakeFood();//產生食物
		set_snakeUp();//蛇變長
		if (false == set_snakeDead())//蛇死亡
		{
			printf("snake dead");
			break;
		}
		set_snakeRun();//蛇跑
		two_interface();//遊戲界面
		set_score();//得分
		Sleep(500);
		
	}
	system("pause");
	return 0;
}

十六.運行結果

在這裏插入圖片描述

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