贪吃蛇游戏

学习C语言也差不多学完了想做一个游戏,而贪吃蛇和俄罗斯方块都是非常经典的游戏,在网上也找到了许多相关的参考资料,便动手做了,这个游戏室控制台版的


游戏流程图

函数模块

函数名

函数功能

CursorPosition

光标定位函数

CreateSnake

蛇初始化函数

ShowWall

显示墙体

UpdateSnake

更新界面上的蛇体、分数、等级、食物

CollisionDetection

判断蛇是否咬到自己

RandFood

随机产生食物

Move

控制方向


程序代码

#include <stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>

#define CWALL   printf("■")//代替墙体符号
#define CSNAKE1 printf("●")//代替蛇头符号
#define CSNAKE  printf("○")//代替蛇身符号
#define CFOOD   printf("◇")//代替食物符号

//蛇结构
struct Snake
{
	int x,y;//坐标
	Snake *next;//蛇身体(结点)
};

//全局变量
int Food;
int Food_x;//食物坐标X
int Food_y;//食物坐标Y

int Direction;//方向变量(1:上  2:左  3:下  4:右)

int Grade;//等级(速度)

int Score;//得分

//蛇头节点
Snake* snake1 =(Snake*)malloc(sizeof(Snake));


//光标坐标定位函数
void CursorPosition(int x,int y)
{
	COORD pos;//坐标结构

	pos.X = x-1;//x坐标
	pos.Y = y-1;//y坐标

	//得到控制台的输出句柄
	HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);
	
	//将坐标设置成光标的坐标
	SetConsoleCursorPosition(Out,pos);
}

//蛇初始化创建函数
void CreatSnake()
{
	//蛇身体结点
	Snake* snake2= (Snake*)malloc(sizeof(Snake));

	//蛇头的坐标
	snake1->x=13;
	snake1->y=5;
	
	//蛇身体的坐标
	snake2->x=11;
	snake2->y=5;
	
	//将蛇身体接到蛇头后
	snake1->next=snake2;
	
	//清空蛇身体的指针域
	snake2->next=NULL;
}

//显示墙体
void ShowWall()
{
	int i;
	
	//列墙体
	for(i=2;i<=24;++i)
	{
		CursorPosition(1,i);
		CWALL;
		
		CursorPosition(61,i);
		CWALL;
		
		CursorPosition(79,i);
		CWALL;
	}
	
	//行墙体
	for(i=1;i<=80;i+=2)
	{
		CursorPosition(i,1);
		CWALL;
		
		CursorPosition(i,24);
		CWALL;
	}

}

//更新界面上的蛇体、分数、等级、食物
void UpdateSneak()
{
	Snake *p;
	
	p=snake1;
	
	CursorPosition(p->x,p->y);//将光标移到蛇头上
	CSNAKE1;//打印蛇头
	
	p=p->next;
	
	while(p!=NULL)
	{	
		CursorPosition(p->x,p->y);//将光标移到蛇身体的位置上
		CSNAKE;//显示蛇身体
		
		p=p->next;
	}
	
	CursorPosition(Food_x,Food_y);//将光标移到食物的位置上
	CFOOD;//显示食物
	
	CursorPosition(67,16);//将光标移到显示分数的位置上
	printf("得分: %d\n",Score);//显示分数
	
	CursorPosition(67,19);//将光标移到显示游戏等级的位置上
	printf("等级: %d\n",Grade);//显示游戏等级
}

//判断蛇是否碰到墙或者咬到自己
int CollisionDetection()
{
	Snake *p;
	
	p=snake1->next;
	
	//通过蛇头的横坐标和纵坐标判断蛇是否碰到墙
	if(snake1->x==1||snake1->x==61||snake1->y==1 || snake1->y==24)
	{
		return 1;
	}

	//通过蛇头的坐标和蛇身体的坐标判断蛇是否咬到自己
	while(!(p->x == snake1->x && p->y == snake1->y))
	{
		if(p->next==NULL)
		{
			return 0;
		}

		p=p->next;
	}
	
	return 1;
}

//随即产生食物
void RandFood()
{
	if(Food==0)
	{
		//随机种子(用于生成变化的随机数)
		srand((int)time(0));
		
		//通过食物的横坐标使得食物在游戏区域内
		Food_y = rand() % 20 + 3;
		
		//通过食物的纵坐标使得食物在游戏区域内
		int temp = rand() % 56 + 3;
		
		if(temp % 2 == 0)//当食物的纵坐标为0时
		{
			Food_x = temp + 1;//纵坐标加1
		}
		else 
		{
			Food_x = temp;
		}

		Food=1;
	}
}

//移动控制
void Move();

//游戏流程
void Game()
{
	while(1)
	{
		//当蛇咬到自己或者撞到墙
		if(1 == CollisionDetection())
		{
			return;//退出循环
		}

		//当按键盘上的上时
		if(GetAsyncKeyState(VK_UP) && Direction!=3)
		{
			Direction=1;	
			goto start;
		}
		
		//当按键盘上的左时
		if(GetAsyncKeyState(VK_LEFT) && Direction!=4)
		{
			Direction=2;
			goto start;
		}
		
		//当按键盘上的下时
		if(GetAsyncKeyState(VK_DOWN) && Direction!=1)
		{
			Direction=3;
			goto start;
		}
		
		//当按键盘上的右时
		if(GetAsyncKeyState(VK_RIGHT) && Direction!=2)
		{
			Direction=4;
			goto start;
		}

start:
		RandFood();//随机生成食物
		
		Move();//移动贪吃蛇
		
		UpdateSneak();//更新游戏中的数据
		
		Sleep(330-Grade*30);//控制贪吃蛇移到的速度
	}
}
//----------------------------------------------------------------------------
void main()
{
	while(1)
	{
		Score=0;
		
		Grade=0;
		
		Direction=4;
		
		system("cls");
		
		CursorPosition(30,12);
		printf("输入游戏等级:[1-10]\n");
		
		CursorPosition(38,14);
		printf("__\b\b");
		
		scanf("%d",&Grade);
		
		while(Grade<1 || Grade>10)
		{
			system("cls");
			
			CursorPosition(30,12);
			printf("输入游戏等级:[1-10]\n");
			
			CursorPosition(38,14);
			printf("__\b\b");
			
			scanf("%d",&Grade);
		}
		
		system("cls");
		
		ShowWall();//显示墙体
		
		CreatSnake();//创建一条贪吃蛇
		
		UpdateSneak();//更新游戏中的数据
		
		Game();
		
		system("cls");
		
		CursorPosition(29,12);
		printf("你输了!  得 %d 分\n",Score);
		
		CursorPosition(29,14);
		printf("按任意键继续/退出(q)\n");
		
		if(getch()=='q')
		{
			exit(1);
		}
		else
		{
			continue;
		}
	}
}

//-----------------------------------------------------------------------------
void Move()
{
	Snake* q;

	//定义一个临时结点
	Snake* temp = (Snake*)malloc(sizeof(Snake));
	
	if(1 == Direction)//向上移动
	{
		//当蛇头碰倒食物时
		if((snake1->x == Food_x) && (snake1->y ==Food_y+1))
		{
			//将临时结点的坐标变为食物坐标
			temp->x=Food_x;
			temp->y=Food_y;
			
			//将蛇头挂到临时结点的后面
			temp->next=snake1;
			
			//临时结点变成头结点(临时结点变成蛇头)
			snake1=temp;
			
			Food=0;//标志位,标志食物被蛇吃了
			
			//计算分数,分数分数的增加数为游戏的等级数
			Score+=(1*Grade);
		}
		else
		{	
			//要移动的方向向上(Windows中的坐标左上角为坐标原点,没有负数)
			temp->x = snake1->x;
			temp->y = snake1->y-1;
			
			//将蛇头接到新蛇头后面
			temp->next=snake1;
			
			//body1表示蛇头
			snake1=temp;
			
			//遍历结点到蛇尾
			q=snake1;
			while((q->next)->next !=NULL)
			{
				q=q->next;
			}

			//将光标移到蛇尾
			CursorPosition((q->next)->x,(q->next)->y);
			printf(" ");
			
			//去掉蛇尾,并且释放蛇尾结点的内存
			free(q->next); 
			q->next=NULL;
		}
	}

	if(Direction==2)//向左移动
	{
		//当蛇头碰倒食物时
		if((snake1->x == Food_x+2) && (snake1->y == Food_y))
		{
	      //将临时结点的坐标变为食物坐标
			temp->x=Food_x;
			temp->y=Food_y;
			
	       //将蛇头挂到临时结点的后面
			temp->next=snake1;
			
	       //临时结点变成头结点(临时结点变成蛇头)
			snake1=temp;
			
			Food=0;//标志位,标志食物被蛇吃了
			
	        //计算分数,分数分数的增加数为游戏的等级数
			Score+=(1*Grade);
		}
		else
		{	
			temp->x=snake1->x-2;
			temp->y=snake1->y;
			temp->next=snake1;
			snake1=temp;
			
			//遍历结点到尾结点
			q=snake1;
			while((q->next)->next!=NULL)
			{
				q=q->next;
			}
			
			//将光标移到蛇尾
			CursorPosition((q->next)->x,(q->next)->y);
			printf(" ");
			
			//去掉蛇尾,并且释放蛇尾结点的内存
			free(q->next);
			q->next=NULL;
		}

	}
		
	if(Direction==3)//向下移动
	{
		//当蛇头碰倒食物时
		if((snake1->x == Food_x) && (snake1->y == Food_y-1))
		{
			//将临时结点的坐标变为食物坐标
			temp->x=Food_x;
			temp->y=Food_y;

			//将蛇头挂到临时结点的后面
			temp->next=snake1;

			//临时结点变成头结点(临时结点变成蛇头)
			snake1=temp;

			Food=0;//标志位,标志食物被蛇吃了
			
			//计算分数,分数分数的增加数为游戏的等级数
			Score+=(1*Grade);
		}
		else
		{	
			//要移动的方向向下(Windows中的坐标左上角为坐标原点,没有负数)
			temp->x=snake1->x;
			temp->y=snake1->y+1;

			//将蛇头接到新蛇头后面
			temp->next=snake1;
			
			//body1表示蛇头
			snake1=temp;
			
			//遍历结点到尾结点
			q=snake1;
			while((q->next)->next!=NULL)
			{	
				q=q->next;
			}
			
			//将光标移到蛇尾
			CursorPosition((q->next)->x,(q->next)->y);
			printf(" ");
			
			//去掉蛇尾,并且释放蛇尾结点的内存
			free(q->next);
			q->next=NULL;
		}
	}
		
	if(Direction==4)//向右移动
	{
		//当蛇头碰倒食物时
		if((snake1->x == Food_x-2) && (snake1->y == Food_y))
		{	
			//将临时结点的坐标变为食物坐标
			temp->x=Food_x;
			temp->y=Food_y;

			//将蛇头挂到临时结点的后面
			temp->next=snake1;
			
			//临时结点变成头结点(临时结点变成蛇头)
			snake1=temp;
			
			Food=0;//标志位,标志食物被蛇吃了

			//计算分数,分数分数的增加数为游戏的等级数
			Score+=(1*Grade);
		}
		else
		{
			temp->x=snake1->x+2;
			temp->y=snake1->y;
			temp->next=snake1;
			snake1=temp;
			
			//遍历结点到蛇尾
			q=snake1;
			while((q->next)->next!=NULL)
			{	
				q=q->next;
			}

			//将光标移到蛇尾
			CursorPosition((q->next)->x,(q->next)->y);
			printf(" ");
			
			//去掉蛇尾,并且释放蛇尾结点的内存
			free(q->next); 
			q->next=NULL;
		}
   }
}


执行结果:



单击此处下载贪吃蛇



  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值