贪吃蛇----

  1. 首先我们要考虑,在整个贪吃蛇的过程中,都需要定义什么变量;
  2. 比如:蛇身的组成,蛇所在的位置,我们假设蛇是一小块一小块连接起来的,所以有蛇吃到一个食物后,蛇会增长一小节,所以还需要链表;
  3. 蛇走的方向:”上下左右“
  4. 蛇的状态:”OK,撞墙,撞到自己,游戏结束“
  5. 整个游戏里面还需要的小部分:分数,休眠时间(控制蛇身的速度)等
#ifndef __SNACK_H__
#define __SNACK_H__
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<time.h>


#define WALL "@"
#define FOOD "$"
#define INIT_X 20
#define INIT_Y 10
typedef struct SnackNode//组成蛇身
{
	int x;
	int y;
	struct SnackNode* next;定义一个结构体指针,指向下一次个与当前节点数据类型相同的节点 
}SnackNode,*pSnackNode;*pSnackNode等价于struct SnackNode* 

enum Direction
{
	UP,
	DOWN,
	LEFT,
	RIGHT,
};

enum GameStatus
{
	OK,
	NORMAL_END,
	KILL_BY_WALL,
	KILL_BY_SELF,
};
typedef struct Snack
{
	pSnackNode _psanck;//维护蛇身的指针
	pSnackNode _pFood; //维护食物的指针
	int _TotalScore;   //总分数
	int _AddScore;     //增加的分数
	int _SleepTime;    //休眠时间
	enum Direction _Dir;//方向
    enum GameStatus _Status;
}Snack,*pSnack;
void GameStart(pSnack ps);
void WelcomeToGame();
void CreateMap();
void InitSnack(pSnack ps);
void CreateFood(pSnack ps);
void GameRun(pSnack ps);
void SnackMove(pSnack ps);


void SetPos(int x,int y);
pSnackNode BuyNode();
void Pause();
int NextHasFood(pSnackNode pn,pSnackNode pf);//下一个节点是否有食物
void EatFood(pSnack ps,pSnackNode pn);//吃到食物
void NoFood(pSnack ps,pSnackNode pn);//没有食物
void KillByWall(pSnack ps);//撞墙
void KillBySelf(pSnack ps);//撞到自己
void PrintHelpInfo();
void GameEnd(pSnack ps);




void CreateDiamond(pSnack ps);
#endif

  1. 游戏跑起来需要的一些函数
#include"snack.h"
void SetPos(int x,int y)//设置位置
{
	COORD pos = {0};
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//获取光标
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle,pos);//设置标准输出上光标的位置
}


void WelcomeToGame()
{
	system("mode con cols=100 lines=30"); //控制台窗口大小设置
	SetPos(38,14);
	printf("欢迎来到贪吃蛇小游戏!\n");
	SetPos(38,28);
	system("pause");//暂停
	system("cls");//清空屏幕
	SetPos(33,13);
	printf("用↑,↓,←,→来控制蛇的移动,F1为加速,F2为减速!");
	SetPos(33,15);
	printf("加速可以使分数增多!");
	SetPos(33,17);
	printf("按空格键可以暂停游戏!\n");
	SetPos(33,19);
	printf("按Esc键可以退出游戏!\n");
	SetPos(40,28);
	system("pause");
	system("cls");
}


void CreateMap()
{
	int i = 0;
	//上
	for(i=0;i<=58;i+=2)
	{
		SetPos(i,0);
		printf(WALL);
	}
	//下
	for(i=0;i<=58;i+=2)
	{
		SetPos(i,27);
		printf(WALL);
	}
	//左
	for(i=1;i<=26;i++)
	{
		SetPos(0,i);
		printf(WALL);
	}
	//右
	for(i=1;i<=26;i++)
	{
		SetPos(58,i);
		printf(WALL);
	}
}


pSnackNode BuyNode()
{
	pSnackNode pRet = (pSnackNode)malloc(sizeof(pSnackNode));
	if(pRet == NULL)
	{
		perror("BuyNode::malloc()");
		exit(EXIT_FAILURE);
	}
	pRet->x = 0;
	pRet->y = 0;
	pRet->next = NULL;
}


void InitSnack(pSnack ps)
{
	pSnackNode first;
	pSnackNode cur = NULL;
	int i = 0;
	first = BuyNode();
	first->x = INIT_X;
	first->y = INIT_Y;

	for(i=0;i<4;i++)
	{
		cur = BuyNode();
		cur->x = first->x+2;
		cur->y = first->y;
		cur->next = first;
		first = cur;
	}
	//cur = first;
	while(cur)
	{
		SetPos(cur->x,cur->y);
		printf(FOOD);
		cur = cur->next;
	}
	ps->_psanck = first;
	printf("\n");
}


void CreateFood(pSnack ps)
{
	pSnackNode pfood = BuyNode();
	pSnackNode cur = ps->_psanck;
	pfood->y = rand()%26+1;
	do
	{
		pfood->x = rand()%55+2;
	}while(pfood->x%2 != 0);

	while(cur)
	{
		if(cur->x == pfood->x && cur->y == pfood->y)
		{
             CreateFood(ps);
			 return;
		}
		cur = cur->next;
	}
	ps->_pFood = pfood;
	SetPos(pfood->x,pfood->y);
	printf(FOOD);

}


void GameStart(pSnack ps)
{
	//欢迎界面
	WelcomeToGame();
	//创建地图
	CreateMap();
	//初始化蛇
	InitSnack(ps);
	//初始化食物
	CreateFood(ps);
	//CreateDiamond(ps);


	ps->_AddScore = 10;
	ps->_TotalScore = 0;
	ps->_Dir = RIGHT;
	ps->_Status = OK;
	ps->_SleepTime = 200;
	
}

void Pause()
{
	while(1)
	{
		Sleep(100);
		if(GetAsyncKeyState(VK_SPACE))
		{
			break;
		}
	}
}
int NextHasFood(pSnackNode pn,pSnackNode pf)
{
	return ((pn->x==pf->x) && (pn->y==pf->y));
}
void EatFood(pSnack ps,pSnackNode pn)
{
	pSnackNode cur = NULL;
	pn->next = ps->_psanck;
	ps->_psanck = pn;
	ps->_TotalScore += ps->_AddScore;
	cur = ps->_psanck;
	while(cur)
	{
		SetPos(cur->x,cur->y);
		printf(FOOD);
		cur = cur->next;
	}
	CreateFood(ps);
}
void NoFood(pSnack ps,pSnackNode pn)
{
	pSnackNode cur = NULL;
	pn->next = ps->_psanck;
	ps->_psanck = pn;

	cur = ps->_psanck;
	while(cur->next->next)
	{
		SetPos(cur->x,cur->y);
		printf(FOOD);
		cur = cur->next;
	}
	SetPos(cur->x,cur->y);
	printf(FOOD);

	SetPos(cur->next->x,cur->next->y);
	printf(" ");
	//free(cur->next);
	cur->next = NULL;
}
void SnackMove(pSnack ps)
{
	pSnackNode pNextNode = BuyNode();
	SetPos(65,8);
	printf("总分:%d",ps->_TotalScore);
	SetPos(65,10);
	printf("食物得分:%d ",ps->_AddScore);
	switch(ps->_Dir)
	{
	case UP:
		{
			pNextNode->x = ps->_psanck->x;
			pNextNode->y = ps->_psanck->y-1;
			if(NextHasFood(pNextNode,ps->_pFood))
			{
				//下一个结点是食物
				EatFood(ps,pNextNode);
			}
			else
			{
				NoFood(ps,pNextNode);
			}
		}
		break;
	case DOWN:
	{
		pNextNode->x = ps->_psanck->x;
			pNextNode->y = ps->_psanck->y+1;
			if(NextHasFood(pNextNode,ps->_pFood))
			{
				//下一个结点是食物
				EatFood(ps,pNextNode);
			}
			else
			{
				NoFood(ps,pNextNode);
			}
	}
	break;
	case LEFT:
	{
		pNextNode->x = ps->_psanck->x-2;
			pNextNode->y = ps->_psanck->y;
			if(NextHasFood(pNextNode,ps->_pFood))
			{
				//下一个结点是食物
				EatFood(ps,pNextNode);
			}
			else
			{
				NoFood(ps,pNextNode);
			}
	}
	break;
	case RIGHT:
	{
		pNextNode->x = ps->_psanck->x+2;
			pNextNode->y = ps->_psanck->y;
			if(NextHasFood(pNextNode,ps->_pFood))
			{
				//下一个结点是食物
				EatFood(ps,pNextNode);
			}
			else
			{
				NoFood(ps,pNextNode);
			}
	}
	break;
	}
}
void KillByWall(pSnack ps)
{
	if(ps->_psanck->x==0 ||
		ps->_psanck->x==58 ||
		ps->_psanck->y==1 ||
		ps->_psanck->y==27)
	{
		ps->_Status = KILL_BY_WALL;
	}
}
void KillBySelf(pSnack ps)
{
	pSnackNode pNext = ps->_psanck->next;
	while(pNext)
	{
		if((pNext->x==ps->_psanck->x)&&(pNext->y==ps->_psanck->y))
		{
			ps->_Status = KILL_BY_SELF;
			return;
		}
		pNext = pNext->next;
	}
}
void PrintHelpInfo()
	{
		SetPos(65,12);
		printf("用↑,↓,←,→键来操作蛇的方向!\n");
		SetPos(65,17);
		printf("按空格键可以暂停游戏!\n");
		SetPos(65,19);
		printf("按Esc键可以退出游戏!\n");
	}
void GameRun(pSnack ps)
{
	PrintHelpInfo();
	do
	{
		//确定方向
		if(GetAsyncKeyState(VK_UP) && ps->_Dir != DOWN)
		{
			ps->_Dir = UP;
		}
		else  if(GetAsyncKeyState(VK_DOWN) && ps->_Dir != UP)
		{
			ps->_Dir = DOWN;
		}
		else  if(GetAsyncKeyState(VK_LEFT) && ps->_Dir != RIGHT)
		{
			ps->_Dir = LEFT;
		}
		else  if(GetAsyncKeyState(VK_RIGHT) && ps->_Dir != LEFT)
		{
			ps->_Dir = RIGHT;
		}
		else if(GetAsyncKeyState(VK_SPACE))
		{
			//暂停
			Pause();
		}
		else if(GetAsyncKeyState(VK_ESCAPE))
		{
			//结束
			ps->_Status = NORMAL_END;
			break;
		}
		else if(GetAsyncKeyState(VK_F1))
		{
			//加速
			if(ps->_SleepTime >= 40)
			{
		    	ps->_SleepTime -= 20;
				ps->_AddScore += 2;

			}
		}
		else if(GetAsyncKeyState(VK_F2))
		{
			//减速
			if(ps->_SleepTime <= 300)
			{
		    	ps->_SleepTime += 20;
				ps->_AddScore -= 2;

			}
			if(ps->_SleepTime >= 300)
			{
				ps->_AddScore = 1;

			}
		}

		Sleep(ps->_SleepTime);
		//蛇的移动

		SnackMove(ps);
		KillByWall(ps);
		KillBySelf(ps);
	}while(ps->_Status == OK);

}


void GameEnd(pSnack ps)
{
	pSnackNode cur = ps->_psanck;
	pSnackNode food = ps->_pFood;
	//SetPos(45,14);
	if(ps->_Status == NORMAL_END)
	{
		printf("游戏正常结束!\n");
		SetPos(65,28);
	    system("pause");
	}
	else if(ps->_Status == KILL_BY_SELF)
	{
		SetPos(22,25);
		printf("蛇撞上自己了,游戏OVER!\n");
		SetPos(65,28);
	    system("pause");
	}
		else if(ps->_Status == KILL_BY_WALL)
	{
		SetPos(22,25);
		printf("蛇撞上墙了,游戏OVER!\n");
		SetPos(65,28);
	    system("pause");
	}
	while(cur)
	{
		pSnackNode del = cur;
		cur = cur->next;
		//free(del);
		del = NULL;
	}
	//free(food);
	food = NULL;
}




  1. 测试一下吧
#include"snack.h"

void test()
{
	Snack snack = {0};   //创建的贪吃蛇
	srand((unsigned int)time(NULL));
	GameStart(&snack);
	GameRun(&snack);
	GameEnd(&snack);
}


int main()
{
	test();
	system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/WZL995/article/details/83118132