贪吃蛇的纯C语言实现过程

花了点时间,用C语言实现了一个贪吃蛇小游戏,开发工具是VS2010。

以下是代码代码链接,我放在了github上,需要的可自行下载:

https://github.com/zhengzebin525/basic_algorithm

本文会着重于思路讲解,最后会放上完整代码。

先来看看运行后的效果图:

贪吃蛇的纯C语言实现过程_第1张图片

总体来说,贪吃蛇小游戏大体需要实现以下几个最主要的函数功能:

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;ix = 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 
#include 
#include 
#include 
#include 

#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;ix = 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、如果需要在界面上显示肉眼可见的运动,延时操作必不可少,毕竟系统的运行速度太快了;

你可能感兴趣的:(贪吃蛇的纯C语言实现过程)