貪喫蛇的純C語言實現過程

花了點時間,用C語言實現了一個貪喫蛇小遊戲,開發工具是VS2010。

以下是代碼代碼鏈接,我放在了github上,需要的可自行下載:

https://github.com/zhengzebin525/basic_algorithm

本文會着重於思路講解,最後會放上完整代碼。

先來看看運行後的效果圖:

總體來說,貪喫蛇小遊戲大體需要實現以下幾個最主要的函數功能:

1、遊戲區域展示;

2、運用鏈表操作初始化小蛇

3、在遊戲區域內隨機出現方塊食物

4、利用API函數獲取用戶的按鍵狀態

5、根據按鍵狀態控制小蛇的不同移動方向,小蛇移動中一旦喫到食物,分數增加;

6、遊戲的錯誤函數,比如小蛇喫到自己,撞牆等;

那麼接下來,就是對以上六大部分進行詳細說明。

第一部分:遊戲區域展示

//遊戲區域展示
void Area_Show()
{
	int num;
	for(num=0;num<70;num+=2)        //如果改成num++的話,上下 邊框會出現錯誤
	{
		Goto_Coord(num,0);
		printf("■");
		Goto_Coord(num,26);
		printf("■");
	}
	for(num=0;num<=26;num++)
	{
		Goto_Coord(0,num);
		printf("■");
		Goto_Coord(70,num);
		printf("■");
	}
}

這是個比較簡單的功能,利用方塊“■”來劃定遊戲的區域,而Goto_Coord(num,0)用於配置文本顯示的座標,這是個自定義函數,用到了GetStdHandle()和SetConsoleCursorPosition()這兩個window自帶的API函數,前一個用來獲取標準輸入/標準輸出/標準錯誤中句柄,後一個用來定位要顯示的座標。

句柄分別有:標準輸入:STD_INPUT_HANDLE、標準輸出:STD_OUTPUT_HANDLE、標準錯誤:STD_ERROR_HANDLE。

很明顯,因爲是要在屏幕上顯示,所以是獲取標準輸出STD_OUTPUT_HANDLE的句柄。

//定位輸出座標
void Goto_Coord(int x,int y)        
{
    COORD pos;
    pos.X = x;
    pos.Y = y;
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(handle,pos);
}

第二部分:運用鏈表操作初始化小蛇

void Snake_Init()
{
	snake *newnode = (snake *)malloc(sizeof(struct node));
	newnode->x = 10;    //賦予初始座標
	newnode->y = 10;    //賦予初始座標
	newnode->next = NULL;
	
	for(int i=1;i<snake_len_init;i++)
	{
		head = (snake*)malloc(sizeof(struct node));
		head->x = 10 + 2*i;
		head->y = 10;
		head->next = newnode;
		newnode = head;
	}
	while(newnode!= NULL)
	{
		Goto_Coord(newnode->x,newnode->y);
		printf("■");
		newnode = newnode->next;
	}
}

初始化小蛇是用若干個方塊組成的,所以需要存儲每個方塊的數據比如內存信息,顯示座標,並用鏈表將方塊聯繫起來,最後一併打印出來,從而呈現方塊小蛇的樣子。

爲了跟遊戲區域對應,因此橫座標是偶數單位增加,縱座標是奇數單位增加。

因此肯定會有一個結構體,來存儲小蛇每個方塊的數據信息:

typedef struct node
{
    int x;          //橫座標
    int y;          //縱座標
    int color;    //方塊顏色
    struct node *next;    
}snake;
 

 

第三部分:在遊戲區域內隨機出現方塊食物

int Food_Show()
{
	int color_num;
	snake *temp1 = NULL,*temp2 = NULL;
	food1 = (snake *)malloc(sizeof(struct node));
	food2 = (snake *)malloc(sizeof(struct node));
	if(food1 == NULL || food2 == NULL)
	{
		return FALSE;
	}
	srand((unsigned)time(NULL));    //產生隨機數必須要的種子

	//產生第一個食物
	while((food1->x%2)!= 0 || food1->x == 70)       //食物x座標不是偶數,跟邊界沒有對齊
	{	
		food1->x = rand()%70 + 2;
	}
	do
	{
		food1->y = rand()%26 + 1;
	}
	while(food1->y == 26);
	temp1 = head;
	while(temp1 != NULL)
	{
		if(food1->x == temp1->x && food1->y == temp1->y)
		{
			free(food1);
			Food_Show();
		}
		temp1 = temp1->next;
	}
	Goto_Coord(food1->x,food1->y);
	color_num = rand()%6;
	food1->color = color_table[color_num];
	color(food1->color);
	printf("■");

	//產生第二個食物
	while((food2->x%2)!= 0 || food2->x == 70)       //食物x座標不是偶數,跟邊界沒有對齊
	{	
		food2->x = rand()%70 + 2;
	}
	do
	{
		food2->y = rand()%26 + 1;
	}
	while(food2->y == 26);
	temp2 = head;
	while(temp2 != NULL)
	{
		if(food2->x == temp2->x && food2->y == temp2->y)
		{
			free(food2);
			Food_Show();
		}
		temp2 = temp2->next;
	}
	Goto_Coord(food2->x,food2->y);
	color_num = rand()%6;
	food2->color = color_table[color_num];
	color(food2->color);
	printf("■");
	
}

每個食物的出現,都是一小塊內存,因此malloc()申請內存是必須的步驟,此處需要注意的是隨機的座標必須位於遊戲區域座標內,並且不能跟區域邊界方塊重疊,也不能跟小蛇身上的每一塊“蛇身”方塊重疊,而且我給每個食物隨機分配了不同的顏色,使得小蛇喫到不同的顏色就會有不一樣的分數加成。

第四部分:利用API函數獲取用戶的按鍵狀態

//遊戲控制
void Game_Control()
{
	Goto_Coord(80,18);
	color(0x07);
	printf("當前獲得分數:%d\n",total_score);
	

	//判斷按下了哪一個按鍵,並且避免上一次的按鍵狀態與其方向相反
	if(GetAsyncKeyState(VK_UP) && Key_Status != Key_Down)   
		Key_Status = Key_Up;
	else if(GetAsyncKeyState(VK_DOWN) && Key_Status != Key_Up)
		Key_Status = Key_Down;
	else if(GetAsyncKeyState(VK_LEFT) && Key_Status != Key_Right)
		Key_Status = Key_Left;
	else if(GetAsyncKeyState(VK_RIGHT) && Key_Status != Key_Left)
		Key_Status = Key_Right;
	else if(GetAsyncKeyState(VK_SPACE))      
	{
		Save_Status = Key_Status;	 //當按下了暫停健的時候,暫停前的運動方向狀態需要保存起來
		Key_Status = Key_Space;
	}
	else if(GetAsyncKeyState(VK_ESCAPE ))
		Key_Status = Key_Esc;
}

這一部分點主要在GetAsyncKeyState(int vkey)這個window的API函數,用於判斷某個物理按鍵是處於按下狀態(非0)還是沒按下狀態(0),而vkey 是256個虛擬按鍵中的一個,返回值是一個非0的數值。

常用的大概是以下幾個:

VK_SHIFT Shift鍵
VK_LSHIFT 左Shift鍵
VK_RSHIFT 右Shift鍵
VK_CONTROL Ctrl鍵
VK_LCONTROL 左Ctrl鍵
VK_RCONTROL 右Ctril鍵
VK_MENU Alt鍵
VK_LMENU 左Alt鍵
VK_RMENU 右Alt鍵
VK_LBUTTON 鼠標左鍵
VK_RBUTTON 鼠標右鍵
VK_ESCAPE ESC鍵
VK_RETURN回車鍵
VK_TABTAB鍵
VK_SPACE空格鍵
VK_UP↑鍵
VK_DOWN↓鍵
VK_LEFT←鍵
VK_RIGHT→鍵

比如if(GetAsyncKeyState(VK_UP) && Key_Status != Key_Down) ,前一個條件判斷用戶是否按下了↑鍵,而後一個條件則判斷上一次的按鍵狀態是不是↓鍵,這麼做是爲了避免小蛇由向上移動突變爲向下移動的情況出現。

第五部分:根據按鍵狀態控制小蛇的不同移動方向,小蛇移動中一旦喫到食物,分數增加

//蛇的移動
void Snake_Move()
{
	snake *nextnode = (snake *)malloc(sizeof(struct node));
	snake *temp = NULL;

	if(Key_Status == Key_Up)
	{
		nextnode->x = head->x;
		nextnode->y = (head->y) - 1;
		//Goto_Coord(80,28);
		//printf("蛇頭head的座標 %d,%d",head->x,head->y);
		if((nextnode->x == food1->x && nextnode->y == food1->y) ||
			(nextnode->x == food2->x && nextnode->y == food2->y))  //移動過程中喫到了食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Food_Score(food1->color);
			free(food1);
			Food_Show();
		}
		else     //移動過程沒有遇到食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp->next->next != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Goto_Coord(temp->next->x,temp->next->y);
			printf(" ");
			free(temp->next);
			temp->next = NULL;
		}
	}

此處只截取了小蛇向上移動的狀態代碼,小蛇一旦運動起來,第一步就需要配置下一步要顯示的方塊的座標,然後判斷此方塊有沒有與食物的座標重疊,重疊了就說明喫到了食物,獲得分數加成;沒重疊的話,就把新顯示的方塊作爲新的蛇頭添加進小蛇鏈表,蛇尾最後的方塊從鏈表上釋放消除掉,然後重新打印小蛇鏈表,這樣就出現了小蛇向上移動一步的現象。

利用Food_Score(food1->color)函數進行分數加成,這是個自定義函數,根據喫到的食物方塊顏色進行判斷,不同的顏色獲取不同的分數加成。

void Food_Score(int food_color)
{
    switch (food_color)
    {
        case red:
            total_score += 50;break;
        case orange:
            total_score += 40;break;
        case green:
            total_score += 30;break;
        case blue:
            total_score += 20;break;
        case purple:
            total_score += 10;break;
    }
}

第六部分:遊戲的錯誤函數,比如小蛇喫到自己,撞牆等

//穿牆錯誤函數
void Through_Walls()
{
	if(head->x == 0 || head->x == 70 ||
		head->y == 0 || head->y == 26)
	{
		system("cls");
		Goto_Coord(30,10);
		printf("抱歉,事故判斷,小蛇死亡撞牆\n");

		Goto_Coord(30,12);
		color(0x07);
		printf("當前獲得分數:%d\n",total_score);
		
		exit(0);
	}
}

只要判斷蛇頭方塊的座標與遊戲區域邊界方塊座標重疊,那就是撞牆的,撞得死死的。

//咬到自己錯誤函數
void Bit_Oneself()
{
	snake *temp;
	temp = head->next;
	while(temp!=NULL)
	{
		if(head->x == temp->x && head->y == temp->y)
		{
			system("cls");
			Goto_Coord(30,10);
			printf("抱歉,事故判斷,小蛇咬死了自己\n");

			Goto_Coord(30,12);
			color(0x07);
			printf("當前獲得分數:%d\n",total_score);
			exit(0);
		}
		temp = temp->next;
	}
}

只要判斷蛇頭方塊的座標與蛇身任何一個方塊座標重疊,那小蛇就是咬到自己了,咬得死死的。

以下是完整代碼,直接copy能用的。

Gluttonous_Snake.h

#ifndef __GLUTTONOUS_SNAKE_H
#define __GLUTTONOUS_SNAKE_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <time.h>

#define FALSE 0
#define TRUE  1

#define	snake_len_init	3		//蛇的初始化長度爲3

#define	 Key_Up		1		//↑按鍵狀態
#define	 Key_Down	2		//↓按鍵狀態
#define  Key_Left	3		//←按鍵狀態
#define  Key_Right	4		//→按鍵狀態
#define  Key_Space	5
#define	 Key_Esc	6
 

#define	red		FOREGROUND_RED
#define orange	FOREGROUND_RED|FOREGROUND_RED|FOREGROUND_GREEN
#define green	FOREGROUND_GREEN
#define blue	FOREGROUND_BLUE
#define purple	FOREGROUND_RED|FOREGROUND_BLUE

typedef struct node
{
	int x;
	int y;
	int color;
	struct node *next;
}snake;


void Goto_Coord(int x,int y);
void color(int color);
void Area_Show();
void Side_Show();
void Snake_Init();
int Food_Show();
void Game_Init();
void Food_Score(int food_color);
void Game_Control();
void Snake_Move();
void Pause();
void Through_Walls();
void Bit_Oneself();


#endif

Gluttonous_Snake.cpp

#include "Gluttonous_Snake.h"

int snake_x,snake_y;
int food_score = 10;   //每個食物的分數
int total_score = 0;   //獲得的總分數
int highest_score = 0;     //最高分
int Key_Status = Key_Right;   //蛇一開始是向右行進
int Save_Status;
snake *head;
snake *newnode;       //中間變量,放在while(1)中會內存溢出
snake *food1,*food2;	

//顏色表
int color_table[6] = {
					red,		//紅			
					orange,		//橙
					green,		//綠
					blue,		//藍
					purple		//紫
					};

//定位輸出座標
void Goto_Coord(int x,int y)        
{
	COORD pos;
	pos.X = x;
	pos.Y = y;
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(handle,pos);
}

//設置文本顏色
void color(int color)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleTextAttribute(handle,color);
}

//遊戲區域展示
void Area_Show()
{
	int num;
	for(num=0;num<70;num+=2)        //如果改成num++的話,上下 邊框會出現錯誤
	{
		Goto_Coord(num,0);
		printf("■");
		Goto_Coord(num,26);
		printf("■");
	}
	for(num=0;num<=26;num++)
	{
		Goto_Coord(0,num);
		printf("■");
		Goto_Coord(70,num);
		printf("■");
	}
}

//側面說明展示
void Side_Show()     
{
	Goto_Coord(80,5);	
	printf("歡迎來到貪喫蛇遊戲\n");
	printf("\n");

	Goto_Coord(80,7);
	printf("↑ ↓ ← → 是上下左右移動\n");
	printf("\n");

	Goto_Coord(80,9);	
	printf("規則1:不能穿牆,不能喫自己\n");
	printf("\n");

	Goto_Coord(80,11);	
	printf("規則2:ESC退出,SPACE是暫停\n");
	printf("\n");

	Goto_Coord(80,13);	
	printf("規則2:喫的食物越多,分數越高\n");
	printf("\n");

	Goto_Coord(80,15);	
	printf("規則3:其中會出現喫到了也沒分數的假食物\n");
	printf("\n");
}

void Snake_Init()
{
	snake *newnode = (snake *)malloc(sizeof(struct node));
	newnode->x = 10;    //賦予初始座標
	newnode->y = 10;    //賦予初始座標
	newnode->next = NULL;
	
	for(int i=1;i<snake_len_init;i++)
	{
		head = (snake*)malloc(sizeof(struct node));
		head->x = 10 + 2*i;
		head->y = 10;
		head->next = newnode;
		newnode = head;
	}
	while(newnode!= NULL)
	{
		Goto_Coord(newnode->x,newnode->y);
		printf("■");
		newnode = newnode->next;
	}
}

int Food_Show()
{
	int color_num;
	snake *temp1 = NULL,*temp2 = NULL;
	food1 = (snake *)malloc(sizeof(struct node));
	food2 = (snake *)malloc(sizeof(struct node));
	if(food1 == NULL || food2 == NULL)
	{
		return FALSE;
	}
	srand((unsigned)time(NULL));    //產生隨機數必須要的種子

	//產生第一個食物
	while((food1->x%2)!= 0 || food1->x == 70)       //食物x座標不是偶數,跟邊界沒有對齊
	{	
		food1->x = rand()%70 + 2;
	}
	do
	{
		food1->y = rand()%26 + 1;
	}
	while(food1->y == 26);
	temp1 = head;
	while(temp1 != NULL)
	{
		if(food1->x == temp1->x && food1->y == temp1->y)
		{
			free(food1);
			Food_Show();
		}
		temp1 = temp1->next;
	}
	Goto_Coord(food1->x,food1->y);
	color_num = rand()%6;
	food1->color = color_table[color_num];
	color(food1->color);
	printf("■");

	//Goto_Coord(80,21);
	//printf("食物1座標 %d,%d",food1->x,food1->y);

	//產生第二個食物
	while((food2->x%2)!= 0 || food2->x == 70)       //食物x座標不是偶數,跟邊界沒有對齊
	{	
		food2->x = rand()%70 + 2;
	}
	do
	{
		food2->y = rand()%26 + 1;
	}
	while(food2->y == 26);
	temp2 = head;
	while(temp2 != NULL)
	{
		if(food2->x == temp2->x && food2->y == temp2->y)
		{
			free(food2);
			Food_Show();
		}
		temp2 = temp2->next;
	}
	Goto_Coord(food2->x,food2->y);
	color_num = rand()%6;
	food2->color = color_table[color_num];
	color(food2->color);
	printf("■");

	//Goto_Coord(80,23);
	//printf("食物2座標 %d,%d",food2->x,food2->y);
	
}


//遊戲界面初始化
void Game_Init()
{
	system("title 貪喫蛇");
	Goto_Coord(40,10);
	printf("歡迎來到貪喫蛇小遊戲\n");
	system("pause");
	system("cls");
	Goto_Coord(40,10);
	printf("希望能帶給你良好的遊戲體驗\n");
	system("pause");
	system("cls");

	Area_Show();	//遊戲區域初始化
	Side_Show();	//側面說明初始化
	Snake_Init();	//蛇初始化
    Food_Show();    //產生方塊食物
}

void Food_Score(int food_color)
{
	switch (food_color)
	{
		case red:
			total_score += 50;break;
		case orange:
			total_score += 40;break;
		case green:
			total_score += 30;break;
		case blue:
			total_score += 20;break;
		case purple:
			total_score += 10;break;
	}
}


//遊戲控制
void Game_Control()
{
	Goto_Coord(80,18);
	color(0x07);
	printf("當前獲得分數:%d\n",total_score);
	

	//判斷按下了哪一個按鍵,並且避免上一次的按鍵狀態與其方向相反
	if(GetAsyncKeyState(VK_UP) && Key_Status != Key_Down)   
		Key_Status = Key_Up;
	else if(GetAsyncKeyState(VK_DOWN) && Key_Status != Key_Up)
		Key_Status = Key_Down;
	else if(GetAsyncKeyState(VK_LEFT) && Key_Status != Key_Right)
		Key_Status = Key_Left;
	else if(GetAsyncKeyState(VK_RIGHT) && Key_Status != Key_Left)
		Key_Status = Key_Right;
	else if(GetAsyncKeyState(VK_SPACE))      
	{
		Save_Status = Key_Status;	 //當按下了暫停健的時候,暫停前的運動方向狀態需要保存起來
		Key_Status = Key_Space;
	}
	else if(GetAsyncKeyState(VK_ESCAPE ))
		Key_Status = Key_Esc;
}

//蛇的移動
void Snake_Move()
{
	snake *nextnode = (snake *)malloc(sizeof(struct node));
	snake *temp = NULL;

	if(Key_Status == Key_Up)
	{
		nextnode->x = head->x;
		nextnode->y = (head->y) - 1;
		//Goto_Coord(80,28);
		//printf("蛇頭head的座標 %d,%d",head->x,head->y);
		if((nextnode->x == food1->x && nextnode->y == food1->y) ||
			(nextnode->x == food2->x && nextnode->y == food2->y))  //移動過程中喫到了食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Food_Score(food1->color);
			free(food1);
			Food_Show();
		}
		else     //移動過程沒有遇到食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp->next->next != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Goto_Coord(temp->next->x,temp->next->y);
			printf(" ");
			free(temp->next);
			temp->next = NULL;
		}
	}

	
	if(Key_Status == Key_Down)
	{
		nextnode->x = head->x;
		nextnode->y = (head->y) + 1;
		//Goto_Coord(80,28);
		//printf("蛇頭head的座標 %d,%d",head->x,head->y);
		if((nextnode->x == food1->x && nextnode->y == food1->y) ||
			(nextnode->x == food2->x && nextnode->y == food2->y))  //移動過程中喫到了食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Food_Score(food1->color);
			free(food1);
			Food_Show();
		}
		else     //移動過程沒有遇到食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp->next->next != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Goto_Coord(temp->next->x,temp->next->y);
			printf(" ");
			free(temp->next);
			temp->next = NULL;
		}
	}


	if(Key_Status == Key_Left)
	{
		nextnode->x = (head->x) - 2;
		nextnode->y = head->y;
		//Goto_Coord(80,28);
		//printf("蛇頭head的座標 %d,%d",head->x,head->y);
		if((nextnode->x == food1->x && nextnode->y == food1->y) ||
			(nextnode->x == food2->x && nextnode->y == food2->y))  //移動過程中喫到了食物
		{
			
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Food_Score(food1->color);
			free(food1);
			Food_Show();
		}
		else     //移動過程沒有遇到食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp->next->next != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Goto_Coord(temp->next->x,temp->next->y);
			printf(" ");
			free(temp->next);
			temp->next = NULL;
		}
	}
	
	if(Key_Status == Key_Right)
	{
		nextnode->x = (head->x) + 2;
		nextnode->y = head->y;
		
		//Goto_Coord(80,28);
		//printf("蛇頭head的座標 %d,%d",head->x,head->y);
		if((nextnode->x == food1->x && nextnode->y == food1->y) ||
			(nextnode->x == food2->x && nextnode->y == food2->y))  //移動過程中喫到了食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Food_Score(food1->color);
			free(food1);
			Food_Show();
		}
		else     //移動過程沒有遇到食物
		{
			nextnode->next = head;
			head = nextnode;
			temp = head;
			while(temp->next->next != NULL)
			{
				Goto_Coord(temp->x,temp->y);
				printf("■");
				temp = temp->next;
			}
			Goto_Coord(temp->next->x,temp->next->y);
			printf(" ");
			free(temp->next);
			temp->next = NULL;
		}
	}
	while(Key_Status == Key_Space)               //按空格健暫停
	{
		Sleep(300);
		if(!(GetAsyncKeyState(VK_SPACE)))
		{
			Pause();                             //暫停函數
			break;
		}	
	}
	if(Key_Status == Key_Esc)
	{
		system("cls");
		Goto_Coord(40,10);
		printf("您已結束遊戲!\n");
	}


	Through_Walls();	//判斷是否撞牆
	Bit_Oneself();		//判斷是否咬到了自己
}

void Pause()
{
	while(1)
	{	
		system("title 暫停中····");
		Sleep(300);
		if(GetAsyncKeyState(VK_SPACE))       //第二次按空格的時候,解除暫停狀態
		{
			Sleep(200);
			Key_Status = Save_Status;
			break;
		}
	}
}

//穿牆錯誤函數
void Through_Walls()
{
	if(head->x == 0 || head->x == 70 ||
		head->y == 0 || head->y == 26)
	{
		system("cls");
		Goto_Coord(30,10);
		printf("抱歉,事故判斷,小蛇死亡撞牆\n");

		Goto_Coord(30,12);
		color(0x07);
		printf("當前獲得分數:%d\n",total_score);
		
		exit(0);
	}
}

//咬到自己錯誤函數
void Bit_Oneself()
{
	snake *temp;
	temp = head->next;
	while(temp!=NULL)
	{
		if(head->x == temp->x && head->y == temp->y)
		{
			system("cls");
			Goto_Coord(30,10);
			printf("抱歉,事故判斷,小蛇咬死了自己\n");

			Goto_Coord(30,12);
			color(0x07);
			printf("當前獲得分數:%d\n",total_score);
			exit(0);
		}
		temp = temp->next;
	}
}

main.cpp

#include "Gluttonous_Snake.h"
int sleep_time = 200;

int main()
{
	Game_Init();  //遊戲界面初始化
	
	while(1)
	{
		system("title 遊戲中····");
		Game_Control();      //遊戲控制,判斷按下的是哪一個按鍵
		Sleep(sleep_time);   //延時200ms
		Snake_Move();
	}
}

當然,這個小遊戲個人覺得還有很多自己的設想沒有實現,以後會抽出時間來實現它。

總結:1、在初始化過程中,如果有某一參數只初始化依次,該參數直接使用常量,如果使用變量,還需要佔用一定的存儲空間,浪費內存;

            2、在鏈表操作中,用最少的步驟完成操作,不要花裏胡哨,鏈表邏輯要清晰,多看幾遍,確保無誤;

                         3、遞歸函數越少用越好,在一個函數中最好不要超過一個遞歸函數;

                         4、如果需要在界面上顯示肉眼可見的運動,延時操作必不可少,畢竟系統的運行速度太快了;

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