贪吃蛇小游戏程序(C语言)

2021年3月31日 15点热度 0条评论 来源: 跋扈洋

这次来分享一个我写的贪吃蛇小游戏程序(C语言)

*最近暑假无事开始用C语言写一些小游戏小游戏程序,这个贪吃蛇当然是经典中的经典,所以先开始写。*

一:文件引用

#include<redio.h>//输入输出
#include<time.h>//用于获取随机数
#include<windows.h>//控制DOS界面
#include<stdlib.h>//定义了一些宏和通用工具函数
#include<conio.h>  //     接收键盘输入输出

二:宏定义

#define W 1       //上
#define S 2      //下
#define A 3     //左
#define D 4    //右

三:定义全局变量

typedef struct snake				//蛇身的一个节点
{
	int x;							//节点的X坐标
	int y;							//节点的Y坐标
	struct snake *next;				//蛇身的下一个节点

}snake;
int score=0,add=0;					//总得分和每次吃食物得分
int HighScore=0;					//最高分
int status,sleeptime=200;			//蛇前进状态,每次运行的时间间隔
snake  *head,*food;					//蛇头指针,食物指针
snake *q;							//遍历蛇的时候用到的指针
int endgamestatus=0;      			//游戏结束的情况,1:撞到墙;2:咬到自己;3:主动退出游戏
HANDLE hOut;

四:函数声明

    /**************************函数声明***************************/
    
  void gotoxy(int x,int y);			//设置光标位置
int  color(int c);					//更改文字颜色
void printsnake();					//字符画--蛇
void welcome();						//开始界面
void createMap();					//绘制地图
void scoreandtips();				//游戏界面右侧的积分和小提示
void initsnake();					//初始化蛇身,花蛇身
void createfood();					//创建并随机出现食物
int  biteself();					//判断是否咬到自己
void cantcrosswall();				//设置蛇撞到墙的情况
void speedup();						//加速
void speeddown();					//减速
void snakemove();					//控制蛇前进方向
void keyjianpan();					//控制键盘按键
void Lostdraw();						//游戏结束界面
void endgame();					    //游戏结束
void choose();						//游戏失败之后的选择
void File_out();					//在文件中读取最高分
void File_in();						//储存最高分文件
void explation();					//游戏说明

五:游戏欢迎界面

/********************游戏欢迎界面***********************/
int color(int c)      //颜色函数
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),c);//更改文字颜色
	return 0;
}

void gotoxy(int x,int y)    //设置光标位置
{
	COORD c;
	c.X=x;
	c.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);
}
void printsnake()
{
	int i,j=10;
    gotoxy(37,21);
	color(14);
	printf("	张	洋	贪	吃	蛇\n						欢	迎	你!");
	gotoxy(19-1,9);
	color(12);
	printf("张洋");
	gotoxy(23-1,9);
	color(12);
	printf("张洋");	
	gotoxy(27-1,9);
	color(12);
	printf("张洋");	
	gotoxy(27-1,11);
	color(12);
	printf("张洋");
	gotoxy(19-1,13);
	color(12);
	printf("张洋");
	gotoxy(23-1,13);
	color(12);
	printf("张洋");	
	gotoxy(27-1,13);
	color(12);
	printf("张洋");	
	for(i=20;i<28;i++)
	{
	gotoxy(i+10,j);
	color(j-10);
	printf("张洋");
    j++;	
	}
	for(i=30;i<38;i++)
	{
	gotoxy(i+10,j);
	color(j-10);
	printf("张洋");
    j--;
	}
	for(i=40;i<48;i++)
	{
	gotoxy(i+10,j);
	color(j-10);
	printf("张洋");
    j++;	
	}
	for(i=50;i<58;i++)
	{
	gotoxy(i+10,j);
	color(j-10);
	printf("张洋");
    j--;
	}
	for(i=60;i<68;i++)
	{
	gotoxy(i+10,j);
	color(j-10);
	printf("张洋");
    j++;	
	}
	for(i=70;i<77;i++)
	{
	gotoxy(i+10,j);
	color(j-10);
	printf("张洋");
    j--;
	}
	gotoxy(87,11);
	color(11);
	printf("张洋");
    gotoxy(91,11);
	color(11);
	printf("张洋");
	gotoxy(95,11);
	color(11);
	printf("张洋");
	gotoxy(99,11);
	color(11);
	printf("张洋");
   	
}
    /*************************主函数******************************************/
    int main()
{
	system("mode con cols=140 lines=40");//设置控制台的宽高
	printsnake();//绘制字符蛇
	return 0;
}

欢迎界面

/************************* 每个人可根据自己的创意,设计不同的欢迎界面。 **********************/

/************************************************ 开始界面 ********************************************/

void welcome()
{
	int n;
	int i,j=1;
	color(14);
	for (i=24;i<=30;i++)
	{
		for (j=35;j<=82;j++)
		{
			gotoxy(j,i);
			if(i==24||i==30)
			{
				printf("-");
			}
			else if(j==35||j==82)
			{
				printf("|");
			}
		}
	}
	color(12);
	gotoxy(45,26);
	printf("1.开始游戏");
	gotoxy(65,26);
	printf("2.游戏说明");
	gotoxy(45,28);
	printf("3.退出游戏");
	gotoxy(48,32);
	color(3);
	printf("请选择[1 2 3]:[ ]\b\b");
	color(14);
	scanf("%d",&n);
	switch(n)
	{
	case 1 :
		system("cls");//清屏 
		break;
	case 2:

		break;
	case 3:
		exit(0);
		break;
	default:
		color(12);
		gotoxy(40,38);
		printf("请输入1-3之间的数!");
		getch();  //输入任意键
		system("cls");  //清屏
		printsnake();
		welcome();
	}
}
int main()
{
	system("mode con cols=140 lines=40");//设置控制台的宽高
	printsnake();//绘制字符蛇
	welcome();
	return 0;
}


两个结合在一起,就构成了开始的主界面

六:游戏主窗体设计

/****************************游戏主窗体设计*********************************/
void createMap()           //创建地图
{
	int i,j;
	for (i=0;i<58;i+=2)
	{
		gotoxy(i,0);
		color(5);
		printf("□");
		gotoxy(i,26);
		printf("□");
	}
	for (i=1;i<26;i++)
	{
		gotoxy(0,i);
		printf("□");
		gotoxy(56,i);
		printf("□");
	}
	for (i=2;i<56;i+=2)
	{
		for (j=1;j<26;j++)
		{
			gotoxy(i,j);
			color(3);
			printf("■\n\n");
		}
	}
}
/*********************游戏右侧的得分和小提示******************/
void scoreandtips()
{
	int i;
	File_out();							 //调用File_out(),读取文件中的内容
	gotoxy(74,4);
	color(11);
	printf("▂▄▅最高纪录▄▃▂:%d",HighScore);//打印游戏最高分
	gotoxy(74,8);
	color(14);
	printf("得分: %d  ",score);
	color(13);
	gotoxy(83,11);
	printf("小 提 示");
	gotoxy(70,13);
	color(6);
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓");
	for (i=15;i<25;i=i+2)
	{
		gotoxy(70,i);
		printf("┃");
	}
	for (i=15;i<25;i=i+2)
	{
		gotoxy(103,i);
		printf("┃");
	}
	gotoxy(70,25);
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
	color(3);
	gotoxy(74,14);
	printf("每个事物得分:%d 分",add);
	gotoxy(74,16);
	printf("不能穿墙,不能咬到自己");
	gotoxy(74,18);
	printf("用↑↓←→分别控制蛇的移动");
	gotoxy(74,20);
	printf("F1加速,F2减速");
	gotoxy(74,22);
	printf("space:暂停游戏");
	gotoxy(74,24);
	printf("ESC:退出游戏");
}
/***************在文件中读取最高分*******************/
void File_out()
{
	FALSE *fp;
	fp=fopen("save.txt","a+");		//打开文件save.txt
	fscanf(fp,"%d",&HighScore);
	fclose(fp);
}
/*****************主函数****************************/
int main()
{
	system("mode con cols=120 lines=40");//设置控制台的宽高
	printsnake();//绘制字符蛇
	welcome();//欢迎界面
	File_out();
	return 0;
}


在C语言中的文件调用,保存一定要学好,才能在这里灵活运用。

绘制蛇身和蛇食物

/******************* 绘制蛇身************************/
    void initsnake()
    {
    	snake *tail;
    	int i;
    	tail=(snake*)malloc(sizeof(snake));  //从蛇尾开始,头插法,以X,Y设定开始的位置
    	tail->x=24;                          //蛇的初始位置(24,5)
    	tail->y=5;
    	tail->next=NULL;
    	for (i=1;i<=4;i++)                     //初始长度为5
    	{
    		head=(snake*)malloc(sizeof(snake));//初始化蛇头
    		head->next=tail;                   //蛇头的下一位为蛇尾
    		head->x=24+2*i;                    //设置蛇头位置
    		head->y=5;
    		tail=head;                         //蛇头变成蛇尾,然后重复循环
    	}
    	while (tail!=NULL)                     //从头到尾,输出蛇身
    	{
    		gotoxy(tail->x,tail->y);
    		color(14);
    		printf("⊕");               //输出蛇身
    		tail=tail->next;           //蛇头输出完毕,输出蛇头的下一位,一直输出到蛇尾
    	}
    }
 
/*************绘制食物******************************/
void createfood()
{
	snake *food_1;
	srand((unsigned)time(NULL));				//初始化随机数
	food_1=(snake*)malloc(sizeof(snake));       //初始化food_1
	//保证其为偶数,使得食物能与蛇头对齐,然后食物会出现在网格线上
	while ((food_1->x%2)!=0)
	{
		food_1->x=rand()%52+2;           //设置食物的X坐标随机出现,食物的x坐标在2-53
	}
	food_1->y=rand()%24+1;             //食物的Y坐标在1-24
	q=head;
	while (q->next==NULL)
	{
		if (q->x==food_1->x&&q->y==food_1->y)  //判断蛇身是否与食物重合
		{
			free(food_1);           //如果食物与蛇身重合,那么释放食物指针
			createfood ();          //重新创建食物
		}
		q=q->next;
	}
	gotoxy(food_1->x,food_1->y);    //设置食物位置
	food=food_1;
	color(12);
	printf("▼");             //输出食物

} 


此时贪吃蛇的游戏界面就已经大致做好,剩下的是进行游戏需要的逻辑等;

七:游戏逻辑

 /**********************************游戏逻辑**********************************/
    
    /*********************判断是否咬到自己*****************/
    int biteself()
    {
    	snake *self;								//定义self为蛇身上的一个节点
    	self=head->next;							//self是蛇头之外的蛇身上的节点
    	while(self!=NULL)
    	{
    		if (self->x==head->x&&self->y==head->y)   //如果self和蛇头上的节点重合
    		{
    			return 1;    						  //返回1
    		}
    		self=self->next;    					 //循环蛇上的每一个节点
    	}
    	return 0;
    }
    /************判断蛇是否撞到墙******************/
    void cantcrosswall()
    {
    	if (head->x==0||head->x==56||head->y==0||head->y==26)//如果蛇头碰到了墙壁
    	{
    		endgamestatus=1;    					  //返回第一种情况
    	}
    }
    /*******************设置蛇加速前进**********/
    void speedup()
    {
    	if (sleeptime>=50)  						 //如果时间间隔大于等于50
    	{
    		sleeptime=sleeptime-10;  				 //时间间隔减10
		     add=add+2;                               //每吃一次食物的得分加2
    		if(sleeptime==320)
    		{
    			add=2;                                //防止减到1之后再加回来有错
    		}
    	}
    }
    /*******************设置蛇减速前进************/
    void speeddown()
    {
    	if (sleeptime<350)              		 	//如果时间间隔小于350
    	{
    		sleeptime=sleeptime+30;     		 	 //时间间隔加上30
    		add=add-2;                				 //没吃一次食物的得分减2
    		if (sleeptime==350)
    		{
    			add=1;               				  //保证最低分为1
    		}
    	}
    }
    /******************控制方向*************************/
void  snakemove()
{
	snake *nexthead;
	cantcrosswall();
	nexthead=(snake*)malloc(sizeof(snake));  //为下一步开辟空间
	if (status==W)
	{
		nexthead->x=head->x;    //向上前进时,x坐标不变,y坐标-1
		nexthead->y=head->y-1;
		nexthead->next=head;
		q=head;                //指针q指向蛇头
		//如果下一个有食物,下一个位置的坐标和食物的坐标相同
		if (nexthead->x==food->x&&nexthead->y==food->y)
		{
			while (q!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //原来食物的位置,从▼变成⊕
				q=q->next;       //指针q指向的蛇身的下一位也执行循环里的操作
			}
			score=score+add;      //吃了一个食物,在总分上加上食物的分
			speedup();
			createfood();         //创建食物
		}
		else
		{
			while (q->next->next!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //蛇正常往前走,输出当前位置的蛇身
				q=q->next;       //继续输出整个蛇身
				
			}
			//经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
			gotoxy(q->next->x,q->next->y);
			color(3);
			printf("■");
			free(q->next);     //进行输出▼之后,释放指向下一位的指针
			q->next=NULL;     //指针下一位指向空
		}
	}
	///
	if (status==S)                 
	{
		nexthead->x=head->x;    //向上前进时,x坐标不变,y坐标+1
		nexthead->y=head->y+1;
		nexthead->next=head;
		q=head;                //指针q指向蛇头
		//如果下一个有食物,下一个位置的坐标和食物的坐标相同
		if (nexthead->x==food->x&&nexthead->y==food->y)
		{
			while (q!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //原来食物的位置,从▼变成⊕
				q=q->next;       //指针q指向的蛇身的下一位也执行循环里的操作
			}
			score=score+add;      //吃了一个食物,在总分上加上食物的分
			speedup();
			createfood();         //创建食物
		}
		else
		{
			while (q->next->next!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //蛇正常往前走,输出当前位置的蛇身
				q=q->next;       //继续输出整个蛇身
				
			}
			//经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
			gotoxy(q->next->x,q->next->y);
			color(3);
			printf("■");
			free(q->next);     //进行输出▼之后,释放指向下一位的指针
			q->next=NULL;     //指针下一位指向空
		}
	}
	/
	if (status==A)
	{
		nexthead->x=head->x-2;    //向左前进时,x坐标向左移动-2,y坐标不变
		nexthead->y=head->y;
		nexthead->next=head;
		q=head;                //指针q指向蛇头
		//如果下一个有食物,下一个位置的坐标和食物的坐标相同
		if (nexthead->x==food->x&&nexthead->y==food->y)
		{
			while (q!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //原来食物的位置,从▼变成⊕
				q=q->next;       //指针q指向的蛇身的下一位也执行循环里的操作
			}
			score=score+add;      //吃了一个食物,在总分上加上食物的分
			speedup();
			createfood();         //创建食物
		}
		else
		{
			while (q->next->next!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //蛇正常往前走,输出当前位置的蛇身
				q=q->next;       //继续输出整个蛇身
				
			}
			//经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
			gotoxy(q->next->x,q->next->y);
			color(3);
			printf("■");
			free(q->next);     //进行输出▼之后,释放指向下一位的指针
			q->next=NULL;     //指针下一位指向空
		}
	}
	/
	if (status==D)
	{
		nexthead->x=head->x+2;    //向右前进时,x坐标向左移动+2,y坐标不变
		nexthead->y=head->y;
		nexthead->next=head;
		q=head;                //指针q指向蛇头
		//如果下一个有食物,下一个位置的坐标和食物的坐标相同
		if (nexthead->x==food->x&&nexthead->y==food->y)
		{
			while (q!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //原来食物的位置,从▼变成⊕
				q=q->next;       //指针q指向的蛇身的下一位也执行循环里的操作
			}
			score=score+add;      //吃了一个食物,在总分上加上食物的分
			speedup();
			createfood();         //创建食物
		}
		else
		{
			while (q->next->next!=NULL)
			{
				gotoxy(q->x,q->y);
				color(14);
				printf("⊕");    //蛇正常往前走,输出当前位置的蛇身
				q=q->next;       //继续输出整个蛇身
				
			}
			//经过上面的循环,q指向蛇尾,蛇尾的下一位,就是蛇走过去的位置
			gotoxy(q->next->x,q->next->y);
			color(3);
			printf("■");
			free(q->next);     //进行输出▼之后,释放指向下一位的指针
			q->next=NULL;     //指针下一位指向空
		}
	}
	if (biteself()==1)			//判断是否会咬到自己
	{
		endgamestatus=2;
	}
}
/******************************* 键盘 ************************************/
void key()
{
	status=R;					//初始蛇向右移动 
	while (1)
	{
		scoreandtips();           //游戏界面右侧的得分和小提醒
//GetAsyncKeyState函数 用来判断函数调用时指定虚拟键的状态
		if (GetAsyncKeyState(VK_UP)&&status!=S)
		{
			status=W;      //如果蛇不是向下前进的时候,按向上键,执行向上前进操作
		}
		else if (GetAsyncKeyState(VK_DOWN)&&status!=W)
		{
			status=S;      //如果蛇不是向上前进的时候,按向下键,执行向下前进操作
		}
		else if (GetAsyncKeyState(VK_LEFT)&&status!=D)
		{
			status=A;      //如果蛇不是向右前进的时候,按向左键,执行向左前进操作
		}
		else if (GetAsyncKeyState(VK_RIGHT)&&status!=A)
		{
			status=D;      //如果蛇不是向左前进的时候,按向右键,执行向右前进操作
		}
		if (GetAsyncKeyState(VK_SPACE))     //按下暂停键,执行pause暂停函数
		{
			while (1)
			{
	//Sleep()函数,头文件#include <unistd.h>另进程暂停,直到达到里面设定参数的时间
				Sleep(300);
				if (GetAsyncKeyState(VK_SPACE))  //按下空格键暂停
				{
					break;
				}
			}
		}
		else if (GetAsyncKeyState(VK_ESCAPE))
		{
			endgamestatus=3;   //按ESC,直接到结束界面
			break;
		}
		else if (GetAsyncKeyState(VK_F1))   //按F1,加速
		{
			speedup();
		}
		else if (GetAsyncKeyState(VK_F2))   //按F2,减速
		{
			if (sleeptime<350)            //如果时间间隔小于350
			{
				sleeptime=sleeptime+30;  //时间间隔加上30
				add=add-2;                //没吃一次食物的得分减2
				if (sleeptime==350)
				{
					add=1;                //保证最低分为1
				}
			}
		}
		Sleep(sleeptime);                 //不按键时,蛇保持前行
		snakemove();
	}
}
/*****************主函数****************************/
int main()
{
	system("mode con cols=120 lines=40");	//设置控制台的宽高
	printsnake();							//绘制字符蛇
	welcome();								//欢迎界面
	File_out();
	key();
	return 0;
}

八:游戏失败界面

/************************失败界面*********************/
void Lostdraw()
{   
	int k;
	system("cls");
	gotoxy(50,2);
	printf("∑游戏结果");
	gotoxy(17,5);
	color(11);
	printf("┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
	printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓");
	for (k=7;k<=18;k++)  //竖边框
	{
		gotoxy(17,k);
		printf("┃");
		gotoxy(82,k);
		printf("┃");
	}
	gotoxy(17,20);
	printf("┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
	printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛");
}
/****************************结束游戏*****************/
void endgame()
{
	system("cls");
	if (endgamestatus==1)   //如果蛇撞到了墙
	{
		Lostdraw();
		gotoxy(35,9);
		color(12);
		printf("对不起,你头铁也撞不烂墙。游戏结束");
	}
	else if (endgamestatus==2)  //如果蛇咬到了自己
	{
		Lostdraw();
		gotoxy(35,9);
		color(12);
		printf("对不起,你咬到了自己,游戏结束!");
	}
	else if (endgamestatus==3)  //如果按ESC键退出
	{
		Lostdraw();
		gotoxy(40,9);
		color(12);
		printf("你已经结束了游戏!");
	}
	gotoxy(43,12);
	color(13);
	printf("你的得分是 %d",score);
	if (score>=HighScore)
	{
		color(10);
		gotoxy(40,16);
		printf("牛逼,创纪录了!!");
		File_in();     //把最高分写进文件
	}
	else                  //如果低于最高分
	{
		color(10);
		gotoxy(35,16);
		printf("继续努力啊,你离最高分还差:%d",HighScore-score);
	}
	choose();    //边框下面的分支选项
}
/********************边框下面的分支选项************/
void choose()
{
	int m;
	gotoxy(25,23);
	color(12);
	printf("我要重新玩一把-------- 1");
	gotoxy(52,23);
	printf("不玩了,退出-------- 2");
	gotoxy(46,25);
	color(11);
	printf("选择: ");
	scanf("%d",&m);
	switch(m)
	{
	case 1:
		system("cls");   //清屏
		score=0;        //分数归零
		sleeptime=200;   //设定初始速度
		add=10;         //使add设为初值,吃一个食物得十分,然后累加
		printsnake();   //返回欢迎界面
		welcome();
		break;
	case 2:
		exit(0);             //退出游戏
		break;
	default:           //输入1或2以外的数字
		gotoxy(35,27);
		color(12);
		printf("不要瞎输入,请重新输入");
		system("pause>nul");     //按任意键
		endgame();
		choose();  //边框下面的分支语句
		break;
	}
}

/*****************主函数****************************/
int main()
{
	system("mode con cols=120 lines=40");	//设置控制台的宽高
	printsnake();							//绘制字符蛇
	welcome();								//欢迎界面
	File_out();                             //读取文件信息
	keyjianpan();                           //控制键盘按键
	endgame();                              //游戏结束
	return 0;	
}

注:此时还要记住在前面蛇不同的失败函数里加上endgame();

九:游戏说明

/*********************游戏说明************************/
void explation()
{
	int i,j=1;
	system("cls");
	color(13);
	gotoxy(52,3);
	printf("游戏说明");
	color(2);
	for (i=6;i<=22;i++)     //输出上下边框
	{
		for (j=20;j<=75;j++)
		{
			gotoxy(j+10,i);
			if (i==6||i==22)
			{
				printf("||");
			}
		}
	}
	color(3);
	gotoxy(40,8);
	printf("一:不能穿墙,不能咬到自己");
	color(10);
	gotoxy(40,11);
	printf("二:用↑↓←→分别控制蛇的移动");
	color(14);
	gotoxy(40,14);
	printf("三:F1加速,F2减速");
	color(11);
	gotoxy(40,17);
	printf("四:安空格键暂停,再按空格键继续");
	color(4);
	gotoxy(40,20);
	printf("五:ESC:退出游戏,space:暂停游戏");
	getch();//按任意键返回主界面
	system("cls");
	printsnake();
	welcome();
}

此时一个好玩的贪吃蛇游戏就做好了,大家可以自己试一试,有利于理解C语言的相关运用

可以关注一下再走。。。。。。

不想要自己费时学习的可以直接找我要完整代码

    原文作者:跋扈洋
    原文地址: https://blog.csdn.net/qq_44629109/article/details/98512639
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。