C语言小游戏——贪吃蛇

#温馨提示:以下设计在VS2019下完美运行,完整代码附在末尾,供大家学习参考
(1)游戏进入界面(动态读取以及温馨提示)

void loading()//动态加载图
{
	int j;
	gotoxy(43, 11);
	printf("Loading...");
	gotoxy(39, 13);
	printf("□□□□□□□□");
	gotoxy(39, 13);
	for (j = 8; j >= 0; j--)
	{
		HideCursor();
		Sleep(200);
		printf("\033[40;35m■\033[0m");
	}
	gotoxy(43, 11);
	printf("          ");
	gotoxy(39, 13);
	printf("                          ");
	gotoxy(39, 9);
	printf("欢迎来到贪吃蛇世界!");
	gotoxy(22, 14);
	printf("抵制不良游戏  拒绝盗版游戏  注意自我保护  谨防受骗上当");
	gotoxy(22, 16);
	printf("适度游戏益脑  沉迷游戏伤身  合理安排时间  享受健康生活");
	Sleep(1500);
}

动态读取
(2)菜单界面

void menu(int a)
{
	HideCursor();
	gotoxy(11, 3);
	printf("\033[40;37m                         _________________________  ||                                   \033[0m");
	gotoxy(11, 4);
	printf("\033[40;33m                       //=====================      ||   //                              \033[0m");
	gotoxy(11, 5);
	printf("\033[40;37m                      //                            ||  //                               \033[0m");
	gotoxy(11, 6);
	printf("\033[40;37m                      \\\\                  __        || //                              \033[0m");
	gotoxy(11, 7);
	printf("\033[40;33m                       \\\\                //\\\\       ||//                             \033[0m");
	gotoxy(11, 8);
	printf("\033[40;33m                       //               //  \\\\      ||\\\\        =====                \033[0m");
	gotoxy(11, 9);
	printf("\033[40;37m                      //    ==         //    \\\\     || \\\\     //      \\\\           \033[0m");
	gotoxy(11, 10);
	printf("\033[40;37m _ _ _ ____          //   //  \\\\      //======\\\\    ||  \\\\   ||=========           \033[0m");
	gotoxy(11, 11);
	printf("\033[40;33m- - - -----\\\\_______//   //    \\\\    //        \\\\   ||   \\\\  ||                  \033[0m");
	gotoxy(11, 12);
	printf("\033[40;35m            \\-------/   //      \\\\  //          \\\\  ||    \\\\  \\\\________________\033[0m");
	gotoxy(39, 6);
	printf("\033[40;36m②○②○\033[0m");
	gotoxy(2, 15);
	printf("\033[40;33m—————————————————————————————————————————————————\033[1m");

	gotoxy(2, 18);
	printf("                      1.开始游戏                              2.游戏设置");
	gotoxy(2, 20);
	printf("                      3.游戏说明                              4.退出游戏");

	switch (a) {
	case 1: gotoxy(22, 18); break;
	case 2: gotoxy(62, 18); break;
	case 3:	gotoxy(22, 20); break;
	case 4: gotoxy(62, 20); break;
	}
	printf("\033[40;36m◇\033[0m");
	return;
}

在这里插入图片描述
(3)菜单选择

void chose()//菜单选择
{
	ii = 1;
	fflush(stdin);
	frame(2);
	menu(ii);
	while (ii != 5)
	{
		(void)_getch();
		if (GetAsyncKeyState(VK_DOWN) & 0x8000)//下
		{
			if (ii == 1)
				ii = 3;
			else if (ii == 2)
				ii = 4;
		}
		if (GetAsyncKeyState(VK_UP) & 0x8000)//上
		{
			if (ii == 3)
				ii = 1;
			else if (ii == 4)
				ii = 2;
		}
		if (GetAsyncKeyState(VK_LEFT) & 0x8000)//左
		{
			if (ii == 2)
				ii = 1;
			else if (ii == 4)
				ii = 3;
		}
		if (GetAsyncKeyState(VK_RIGHT) & 0x8000)//右
		{
			if (ii == 1)
				ii = 2;
			else if (ii == 3)
				ii = 4;
		}
		menu(ii);
		Sleep(150);//缓冲
		if (GetAsyncKeyState(VK_RETURN) & 0x0D)//确认
		{
			fflush(stdin);
			return;
		}
	}
}

(4)障碍物与地图

void obstacle() //障碍物
{   //IOT地图
	int sup_mapx1[68] = { 16,18,20,22,24,20,20,20,20,20,20,16,18,20,22,24,36,38,40,42,44,36,44,36,44,36,44,36,44,36,44,36,44,36,38,40,42,44,56,58,60,62,64,60,60,60,60,60,60,60 };
	int sup_mapy1[68] = {  8, 8, 8, 8, 8, 9,10,11,12,13,14,15,15,15,15,15, 8, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,15,15,15, 8, 8, 8, 8, 8, 9,10,11,12,13,14,15 };
     //ZHKU地图
	int sup_mapx2[77] = { 10,12,14,16,18,20,20,18,16,14,12,10,10,12,14,16,18,20,28,28,28,28,28,28,28,28,30,32,34,36,36,36,36,36,36,36,36,44,44,44,44,44,44,44,44,46,48,48,50,52,50,52,60,60,60,60,60,60,60,60,62,64,66,68,70,70,70,70,70,70,70,70,18,12,46,46,48 };
    int sup_mapy2[77] = {  9, 9, 9, 9, 9, 9,10,11,12,13,14,15,16,16,16,16,16,16, 9,10,11,12,13,14,15,16,12,12,12, 9,10,11,12,13,14,15,16, 9,10,11,12,13,14,15,16,12,11,13,10, 9,14,15, 9,10,11,12,13,14,15,16,16,16,16,16, 9,10,11,12,13,14,15,16,10,15,11,13,12 };
	if (map == 2)//困难
		j = 5;
	if (map == 3)//地狱
		j = 15;
	if (map == 4)//传说
		j = 30;
	if(map>1)
	for (i = 0; i < j; i++)//生成障碍物
	{
		obs.x[i] = rand() % 70 + 6;
		obs.y[i] = rand() % 20 + 3;
		if (obs.x[i] % 2 != 0)//优化出现的位置
			obs.x[i]--;
		if (obs.x[i] == food.x && obs.y[i] == food.y)//障碍物不能出现在初始食物上
		continue;
		if (obs.y[i] == 20)//初始方向上不出现障碍物
			i--;
	}
	else if (map == 0)
	{                 
		j = 68;
		for (i = 0; i < j; i++)//特别版地图1绘制
		{
			obs.x[i] = sup_mapx1[i];
			obs.y[i] = sup_mapy1[i];
		}
	}
	else if (map == -1)
	{
		j = 77;
		for (i = 0; i < j; i++)//特别版地图2绘制
		{
			obs.x[i] = sup_mapx2[i];
			obs.y[i] = sup_mapy2[i];
		}
	}
	if (map >1)
		for (i = 0; i < j; i++)//打印障碍物
		{
			gotoxy(obs.x[i], obs.y[i]);
			printf("\033[40;31m▲\033[0m");
		}
	else if(map==0)
		for (i = 0; i < 50; i++)//打印特别地图1
		{
			gotoxy(obs.x[i], obs.y[i]);
			if(i<16)
			printf("\033[40;31m■\033[0m");
			else if(i>37)
			    	printf("\033[40;34m■\033[0m");
		       	else printf("\033[40;32m■\033[0m");
		}
	else if(map==-1)
		for (i = 0; i < 72; i++)//打印特别地图2
		{
			gotoxy(obs.x[i], obs.y[i]);
			if(i<18)printf("\033[40;32m■\033[0m");
			if (i < 37 && i >= 18) printf("\033[40;33m■\033[0m");
			if(i>=37&&i<52)	printf("\033[40;36m■\033[0m");
			if (i >=52)printf("\033[40;35m■\033[0m");
		}
}

在这里插入图片描述

(5)蛇的控制

void control()
{
	fflush(stdin);
	if (foodFlag == 0)//在蛇尾处输出空格即擦去蛇尾
	{
		gotoxy(snake.x[snake.length - 1], snake.y[snake.length - 1]);
		switch (tail) //尾巴痕迹选择功能
		{
		case 1:printf("  "); break;
		case 2:printf("~ "); break;
		case 3:printf("·"); break;
		}
	}
	for (i = snake.length - 1; i > 0; i--)//将蛇的每一节依次向前移动一节(蛇头除外)
	{
		snake.x[i] = snake.x[i - 1];
		snake.y[i] = snake.y[i - 1];
	}
	while (1)
	{
		if ((GetAsyncKeyState(VK_DOWN)) && vkflag != 2)//下
		{
			vkflag = 4;	break;
		}
		if ((GetAsyncKeyState(VK_UP)) && vkflag != 4)//上
		{
			vkflag = 2;	break;
		}
		if ((GetAsyncKeyState(VK_LEFT)) && vkflag != 3)//左
		{
			vkflag = 1;	break;
		}
		if ((GetAsyncKeyState(VK_RIGHT)) && vkflag != 1)//右
		{
			vkflag = 3;	break;
		}
		if (GetAsyncKeyState(VK_SPACE) && 0x20)//暂停功能
			while (1)
			{
				gotoxy(84, 16);
				printf("\033[40;36m游戏已经暂停\033[0m");
				Sleep(200);
				gotoxy(84, 16);
				printf("            "); //闪烁
				Sleep(150);
				if (GetAsyncKeyState(VK_SPACE) && 0x20)
					break;
			}
		break;
	}
	switch (vkflag)//方向
	{
	case 1:	snake.x[0] -= 2; break;//左
	case 2: snake.y[0]--; break;//上
	case 3: snake.x[0] += 2; break;//右
	case 4: snake.y[0]++; break;//下
	}
	gotoxy(snake.x[0], snake.y[0]);//蛇头移动
	printf("◆");
	gotoxy(snake.x[1], snake.y[1]);//蛇身移动
	printf("■");
	foodFlag = 0;
	fflush(stdin);
	return;
}

(6)食物生成

void foodcreate()
{
	n++;//加速标记
	flag = 1;
    sorce += 10;//每个食物得10分
	if (sorce>=his_max )//最高分
	{
		his_max = sorce;
		gotoxy(82, 2);
		printf("                 ");
		gotoxy(82, 2);
		printf("★历史最高:%d", his_max);
	}
	gotoxy(82, 3);//本局得分
	printf("                 ");
	gotoxy(82, 3);
	printf("☆当前得分:%d", sorce);

	while (flag==1)//生成食物
	{		
	  food.x = rand() % 74 + 4;//随机选取食物的范围
	  food.y = rand() % 24 + 1;
	  if (food.x % 2 != 0 && flag == 1)//优化出现位置
	  {
		  food.x = food.x - 1;
		  flag = 0;
	  }
	  if(map!=1)//非普通地图项
	  for (i = 0; i < snake.length; i++)
	  {
		  for(m=0;m<j;m++)
			  if (obs.x[m] == food.x && obs.y[m] == food.y)
			  {
				  flag = 1;
				  break;
			  }
	  }
	  for (i = 0; i < snake.length; i++)//不能在蛇的身体上生成食物
	  {
		  if (snake.x[i] == food.x && snake.y[i] == food.y)
		  {
			  flag = 1;
			  break;
		  }
	  }
	}
    gotoxy(food.x, food.y);	//生成食物
	printf("●");
	snake.length++;//吃到食物长度加1
	foodFlag = 1;//吃到食物尾部不清除
	return;
}

(7)死亡判断

int  dead()
{
	if (snake.y[0] == 0 || snake.y[0] == map_y-1)//上下边界死亡
		return 0;
	if (snake.x[0] == 0 || snake.x[0] == map_x-2)//左右边界死亡
		return 0;
	if(map!=1)//撞到障碍物死亡
	for (m = 0; m < j; m++)
		if (obs.x[m] == snake.x[0] && obs.y[m] == snake.y[0])
		{
			return 0;
		}
	for (i = 1; i < snake.length; i++)//咬到自身死亡
	{
	if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
		return 0;
	}
	if (GetAsyncKeyState(VK_ESCAPE)&0x1B)//ESC健返回死亡
	{
		ii = 5;
		return 0;
	}
	return 1;
}

在这里插入图片描述

(8)初始化游戏

void game()//初始化游戏
{
	int i ;
	n = 0;//重置状态
	vkflag = 1;
	sorce = 0;
	foodFlag = 0;
	system("cls");//初始清屏
	frame(1);//打印游戏框架(动态)
	gotoxy(82, 2);
	printf("★历史最高:%d", his_max);
	gotoxy(82, 3);
	printf("☆当前得分:%d", sorce);
	gotoxy(84, 8);
	printf("通过下面按键");
	gotoxy(85, 9);
	printf("\033[40;33m    ↑      \033[0m");
	gotoxy(85, 10);
	printf("\033[40;33m  ←  →    \033[0m");
	gotoxy(85, 11);
	printf("\033[40;33m    ↓      \033[0m");
	gotoxy(83, 12);
	printf("来控制蛇的方向");
	gotoxy(82, 18);
	printf("按空格键暂停/继续");
	gotoxy(83, 20);
	printf("按Shift键 加速");	
	gotoxy(82, 22);
	printf("按ESC键返回菜单");

	snake.length = org_len;//初始化蛇(固定位置)
	snake.x[0] = 50 ;
	snake.y[0] = 20;
	gotoxy(snake.x[0], snake.y[0]);
	printf("◆");
	for (i = 1; i < snake.length; i++)//打印蛇
	{
		Sleep(25);
		snake.x[i] = snake.x[i - 1] + 2;
		snake.y[i] = snake.y[0];
		gotoxy(snake.x[i], snake.y[i]);
		printf("■");
	}
	if (map >=1)
	{
		food.x = rand() % 44 + 4;//初始化食物(左方出现)
		food.y = rand() % 24 + 1;
		if (food.x % 2 != 0)
			food.x = food.x - 1;
	}
	else {
		food.x = 14;//初始化食物(左方出现)
		food.y = 3;
	}
	gotoxy(food.x, food.y);//初始的食物闪烁
	printf("\033[40;37m●\033[0m");
	Sleep(250);
	gotoxy(food.x, food.y);
	printf("  ");
	Sleep(250);
	gotoxy(food.x, food.y);
	printf("\033[40;37m●\033[0m");
	Sleep(250);
	obstacle();
	while(ii==1) //运行
	{
		if (GetAsyncKeyState(VK_SHIFT))//加速功能
		{
			gotoxy(93, 20);
			printf("\033[40;31m加速\033[0m");//特效
		}
		else { Sleep(100);
		gotoxy(93, 20);
		printf("加速");
		}
		Sleep(speed - (changespeed * n));//变速模式
		control();//控制
		if (snake.x[0] == food.x && snake.y[0] == food.y)//吃掉食物
		foodcreate();
		if (dead() != 1) //判断是否结束游戏
		{
			gotoxy(36,12);
			printf("Game over");//结束显示
			gotoxy(36, 14);
			printf("  T _ T  ");
			Sleep(500);
			while (1)
			{
				gotoxy(32, 16);
				printf("请按Enter键返回主菜单");
				Sleep(150);

				if (GetAsyncKeyState(VK_RETURN) & 0x0D)//确认返回
				{
					fflush(stdin);
					ii = 5;
					return;
				}
				
			}
		}	
	}
}

(9)游戏设置

void setup2()//设置显示(分析各种情况)
{
	gotoxy(34, 8);
	switch (org_len)//初始长度
	{
	case 2: printf("初始长度           ◆■           >"); break;
	case 3: printf("初始长度       <   ◆■■         >"); break;
	case 4: printf("初始长度       <   ◆■■■       >"); break;
	case 5: printf("初始长度       <   ◆■■■■     >"); break;
	case 6: printf("初始长度       <   ◆■■■■■   >"); break;
	case 7: printf("初始长度       <   ◆■■■■■■  "); break;
	}
	gotoxy(34, 10);
	switch (speed)//初始速度
	{
	case  50:printf("游戏初速度     <   较快    "); break;
	case 100:printf("游戏初速度     <   中等   >"); break;
	case 150:printf("游戏初速度         较慢   >"); break;
	}
	gotoxy(34, 12);
	switch (changespeed)//是否变速
	{
	case 0:printf("吃到食物加速        否    >"); break;
	case 5:printf("吃到食物加速   <    是     "); break;
	}
	gotoxy(34, 14);
	switch (tail)//尾巴选择
	{
	case 1:printf("当前尾巴痕迹        无    >"); break;
	case 2:printf("当前尾巴痕迹   <    ~     >"); break;
	case 3:printf("当前尾巴痕迹   <   ·      "); break;
	}
	gotoxy(34, 16);
	switch (map)//地图选择
	{
	case -1:printf("当前地图难度      特别版2 >"); break;
	case 0:printf("当前地图难度   <  特别版1 >"); break;
	case 1:printf("当前地图难度   <   普通   >"); break;
	case 2:printf("当前地图难度   <   困难   >"); break;
	case 3:printf("当前地图难度   <   地狱   >"); break;
	case 4:printf("当前地图难度   <   传说    "); break;
	}
    gotoxy(70, 22);
    printf("确定并返回菜单"); 

	for (i = 0; i < 7; i++)
	{
		gotoxy(31, 8 + 2 * i);
		printf("  ");
	}
	gotoxy(67, 22);
	printf("  ");
	switch (set_flag)
	{
	case 1:gotoxy(31,  8); break;
	case 2:gotoxy(31, 10); break;
	case 3:gotoxy(31, 12); break;
	case 4:gotoxy(31, 14); break;
	case 5:gotoxy(31, 16); break;
	case 6:gotoxy(67, 22); break;
	}
	printf("★");
	return;
}
void setup()//设置操作(改变全局变量)
{
	frame(2);
	set_flag=1;
	gotoxy(30, 3);
	printf("      ■■◆    游戏设置    ◆■■");
	gotoxy(26, 4);
	printf("■■■■■■                        ■■■■■■");
	setup2();
	fflush(stdin);
	while (1)
	{
		if (GetAsyncKeyState(VK_DOWN))//下
		{
			if (set_flag == 6)
				set_flag = 1;
			else set_flag++;
		}
		if (GetAsyncKeyState(VK_UP))//上
		{
			if (set_flag == 1)
				set_flag = 6;
			else set_flag--;
		}
		if (GetAsyncKeyState(VK_LEFT))//左
		{
			switch (set_flag)
			{
			case 1: if (org_len > 2)
				org_len--; break;
			case 2: if (speed < 150)
				speed += 50; break;
			case 3: if (changespeed == 5)
				changespeed = 0;break;
			case 4: if (tail > 1)
				tail--;break;
			case 5: if (map > -1)
				map--;break;
			case 6: break;
			}
		}
		if (GetAsyncKeyState(VK_RIGHT))//右
		{
			switch (set_flag)
			{
			case 1: if (org_len < 7)
				org_len++;break;
			case 2: if (speed > 50)
				speed -= 50;break;
			case 3: if (changespeed == 0)
				changespeed = 5;break;
			case 4: if (tail < 3)
				tail++;break;
			case 5: if (map < 4)
				map++;break;
			case 6:break;
			}
		}
		setup2();
		if ((GetAsyncKeyState(VK_RETURN)&0x0D)&&set_flag==6)
		{
			ii = 5;
			return;
		}
		Sleep(175);
	}
	return;
}

在这里插入图片描述

(10)游戏说明

void instructions()//游戏说明
{
	system("cls");
	frame(2);
	gotoxy(10, 3);
	printf("游戏说明:");
	gotoxy(18, 5);
	printf("一条蛇在封闭空间里,空间内随机出现一个食物,通过按键盘四个光标");
	gotoxy(18, 7);
	printf("键↑←↓→控制蛇向上下左右四个方向移动来获取食物食物,当食物被");
	gotoxy(18, 9);
	printf("吃掉,蛇身体长一节,同时记10分,接着又出现新的食物,如果蛇撞到");
	gotoxy(18, 11);
	printf("墙或蛇头撞到自己身体或撞到障碍物,游戏结束。");
	gotoxy(18, 15);
	printf("温馨提示:游戏过程中,可按Shift键加速,但不能同时按方向键,也");
	gotoxy(18, 17);
	printf("          可以按空格键来暂停游戏。                          ");
	gotoxy(60, 20);
	printf("按确认键返回主菜单");
	gotoxy(3, 23);
	printf("当前游戏版本 V1.0");
	while (1)//按确认键返回主菜单
	{
		Sleep(100);
		(void)_getch();
		if (GetAsyncKeyState(VK_RETURN))//确认
		{
			ii = 5;
			break;
		}
	}
}
void end()//游戏退出
{
	frame(2);
	gotoxy(44, 12);
	printf("游戏已退出");
	gotoxy(0, 26);
}

在这里插入图片描述
(11)直接贴完整代码

#include<stdio.h>
#include <stdlib.h>
#include<Windows.h>
#include <time.h>
#include<conio.h>

#define   SNAKE 300//蛇的最大节数
#define   KEYDOWN(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?1:0)//vk键会返回两次值,在这里筛选按下操作
#define   KEYUP(vk_code)((GetAsyncKeyState(vk_code)&0x8000)?0:1)

int ii = 1, i, m, flag = 1, n = 0, set_flag = 1;//其他的全局变量(ii为菜单,n变速,set_flag设置,flag是否产生新食物标记)
int speed = 100, changespeed = 5, tail = 1, org_len = 5, map = 1;//速度、速度变化、尾巴痕迹、初始长度、地图难度
int vkflag = 1;//记录键盘
int sorce = 0, his_max = 0;//记录分数和历史最高分
int map_x = 80, map_y = 26;//边界
int foodFlag = 0;//吃到食物标记
int j;//障碍物数量

struct//定义蛇
{
	int length;//蛇的长度
	int x[SNAKE];//组成蛇身的每一个小方块中x的坐标
	int y[SNAKE];//组成蛇身的每一个小方块中y的坐标
}snake;
struct //定义食物节点
{
	int x, y;
} food;
struct //定义障碍物
{
	int x[77];
	int y[77];
}obs;

void gotoxy();//移动光标位置
void HideCurson();//隐藏光标
void frame(int a);//框架1/2
void loading();//(假)读取
void menu(int a);//菜单
void chose();//菜单选择
void obstacle();//障碍物
void control();//控制方向
void foodcreate();//创建食物
int  dead();//判断死亡
void game();//开始游戏
void setup2();//设置的更新
void setup();//设置参数的改变
void instructions();//游戏说明
void end();//游戏结束

void gotoxy(int x, int y) //调整光标
{
	COORD pos = { x,y };
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);// 获取标准输出设备句柄
	SetConsoleCursorPosition(hOut, pos);//两个参数分别是指定哪个窗体,具体位置
}
void HideCursor()//隐藏光标
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void frame(int a)//初始化框
{
	int i, k;
	system("cls");
	gotoxy(78, 0);//横1
	for (k = 0; k <= 11; k++)
	{
		if (a == 1)
			Sleep(4);
		printf("\033[40;37m■\033[0m");
	}

	for (i = 0; i <= 25; i++)//右竖
	{
		if (a == 1)
			Sleep(4);
		gotoxy(100, i);
		printf("\033[40;37m■\033[0m");
	}

	for (k = 0; k <= 50; k++)//下横往左
	{
		if (a == 1)
			Sleep(4);
		gotoxy(100 - 2 * k, 25);
		printf("\033[40;37m■\033[0m");
	}
	for (i = 25; i >= 0; i--)//左竖向上
	{
		if (a == 1)
			Sleep(4);
		gotoxy(0, i);
		printf("\033[40;37m■\033[0m");
	}
	gotoxy(0, 0);
	for (k = 0; k <= 38; k++)//横2
	{
		if (a == 1)
			Sleep(4);
		printf("\033[40;37m■\033[0m");
	}
	if (a == 1)
		for (i = 0; i <= 25; i++)//分割竖
		{
			Sleep(6);
			gotoxy(78, i);
			printf("\033[40;37m■\033[0m");
		}
}
void loading()//动态加载图
{
	int j;
	gotoxy(43, 11);
	printf("Loading...");
	gotoxy(39, 13);
	printf("□□□□□□□□");
	gotoxy(39, 13);
	for (j = 8; j >= 0; j--)
	{
		HideCursor();
		Sleep(200);
		printf("\033[40;35m■\033[0m");
	}
	gotoxy(43, 11);
	printf("          ");
	gotoxy(39, 13);
	printf("                          ");
	gotoxy(39, 9);
	printf("欢迎来到贪吃蛇世界!");
	gotoxy(22, 14);
	printf("抵制不良游戏  拒绝盗版游戏  注意自我保护  谨防受骗上当");
	gotoxy(22, 16);
	printf("适度游戏益脑  沉迷游戏伤身  合理安排时间  享受健康生活");
	Sleep(1500);
}
void menu(int a)
{
	HideCursor();
	gotoxy(11, 3);
	printf("\033[40;37m                         _________________________  ||                                   \033[0m");
	gotoxy(11, 4);
	printf("\033[40;33m                       //=====================      ||   //                              \033[0m");
	gotoxy(11, 5);
	printf("\033[40;37m                      //                            ||  //                               \033[0m");
	gotoxy(11, 6);
	printf("\033[40;37m                      \\\\                  __        || //                              \033[0m");
	gotoxy(11, 7);
	printf("\033[40;33m                       \\\\                //\\\\       ||//                             \033[0m");
	gotoxy(11, 8);
	printf("\033[40;33m                       //               //  \\\\      ||\\\\        =====                \033[0m");
	gotoxy(11, 9);
	printf("\033[40;37m                      //    ==         //    \\\\     || \\\\     //      \\\\           \033[0m");
	gotoxy(11, 10);
	printf("\033[40;37m _ _ _ ____          //   //  \\\\      //======\\\\    ||  \\\\   ||=========           \033[0m");
	gotoxy(11, 11);
	printf("\033[40;33m- - - -----\\\\_______//   //    \\\\    //        \\\\   ||   \\\\  ||                  \033[0m");
	gotoxy(11, 12);
	printf("\033[40;35m            \\-------/   //      \\\\  //          \\\\  ||    \\\\  \\\\________________\033[0m");
	gotoxy(39, 6);
	printf("\033[40;36m②○②○\033[0m");
	gotoxy(2, 15);
	printf("\033[40;33m—————————————————————————————————————————————————\033[1m");

	gotoxy(2, 18);
	printf("                      1.开始游戏                              2.游戏设置");
	gotoxy(2, 20);
	printf("                      3.游戏说明                              4.退出游戏");

	switch (a) {
	case 1: gotoxy(22, 18); break;
	case 2: gotoxy(62, 18); break;
	case 3:	gotoxy(22, 20); break;
	case 4: gotoxy(62, 20); break;
	}
	printf("\033[40;36m◇\033[0m");
	return;
}
void chose()//菜单选择
{
	ii = 1;
	fflush(stdin);
	frame(2);
	menu(ii);
	while (ii != 5)
	{
		(void)_getch();
		if (GetAsyncKeyState(VK_DOWN) & 0x8000)//下
		{
			if (ii == 1)
				ii = 3;
			else if (ii == 2)
				ii = 4;
		}
		if (GetAsyncKeyState(VK_UP) & 0x8000)//上
		{
			if (ii == 3)
				ii = 1;
			else if (ii == 4)
				ii = 2;
		}
		if (GetAsyncKeyState(VK_LEFT) & 0x8000)//左
		{
			if (ii == 2)
				ii = 1;
			else if (ii == 4)
				ii = 3;
		}
		if (GetAsyncKeyState(VK_RIGHT) & 0x8000)//右
		{
			if (ii == 1)
				ii = 2;
			else if (ii == 3)
				ii = 4;
		}
		menu(ii);
		Sleep(150);//缓冲
		if (GetAsyncKeyState(VK_RETURN) & 0x0D)//确认
		{
			fflush(stdin);
			return;
		}
	}
}
void obstacle() //障碍物
{   //IOT地图
	int sup_mapx1[68] = { 16,18,20,22,24,20,20,20,20,20,20,16,18,20,22,24,36,38,40,42,44,36,44,36,44,36,44,36,44,36,44,36,44,36,38,40,42,44,56,58,60,62,64,60,60,60,60,60,60,60 };
	int sup_mapy1[68] = {  8, 8, 8, 8, 8, 9,10,11,12,13,14,15,15,15,15,15, 8, 8, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,15,15,15, 8, 8, 8, 8, 8, 9,10,11,12,13,14,15 };
     //ZHKU地图
	int sup_mapx2[77] = { 10,12,14,16,18,20,20,18,16,14,12,10,10,12,14,16,18,20,28,28,28,28,28,28,28,28,30,32,34,36,36,36,36,36,36,36,36,44,44,44,44,44,44,44,44,46,48,48,50,52,50,52,60,60,60,60,60,60,60,60,62,64,66,68,70,70,70,70,70,70,70,70,18,12,46,46,48 };
    int sup_mapy2[77] = {  9, 9, 9, 9, 9, 9,10,11,12,13,14,15,16,16,16,16,16,16, 9,10,11,12,13,14,15,16,12,12,12, 9,10,11,12,13,14,15,16, 9,10,11,12,13,14,15,16,12,11,13,10, 9,14,15, 9,10,11,12,13,14,15,16,16,16,16,16, 9,10,11,12,13,14,15,16,10,15,11,13,12 };
	if (map == 2)//困难
		j = 5;
	if (map == 3)//地狱
		j = 15;
	if (map == 4)//传说
		j = 30;
	if(map>1)
	for (i = 0; i < j; i++)//生成障碍物
	{
		obs.x[i] = rand() % 70 + 6;
		obs.y[i] = rand() % 20 + 3;
		if (obs.x[i] % 2 != 0)//优化出现的位置
			obs.x[i]--;
		if (obs.x[i] == food.x && obs.y[i] == food.y)//障碍物不能出现在初始食物上
		continue;
		if (obs.y[i] == 20)//初始方向上不出现障碍物
			i--;
	}
	else if (map == 0)
	{                 
		j = 68;
		for (i = 0; i < j; i++)//特别版地图1绘制
		{
			obs.x[i] = sup_mapx1[i];
			obs.y[i] = sup_mapy1[i];
		}
	}
	else if (map == -1)
	{
		j = 77;
		for (i = 0; i < j; i++)//特别版地图2绘制
		{
			obs.x[i] = sup_mapx2[i];
			obs.y[i] = sup_mapy2[i];
		}
	}
	if (map >1)
		for (i = 0; i < j; i++)//打印障碍物
		{
			gotoxy(obs.x[i], obs.y[i]);
			printf("\033[40;31m▲\033[0m");
		}
	else if(map==0)
		for (i = 0; i < 50; i++)//打印特别地图1
		{
			gotoxy(obs.x[i], obs.y[i]);
			if(i<16)
			printf("\033[40;31m■\033[0m");
			else if(i>37)
			    	printf("\033[40;34m■\033[0m");
		       	else printf("\033[40;32m■\033[0m");
		}
	else if(map==-1)
		for (i = 0; i < 72; i++)//打印特别地图2
		{
			gotoxy(obs.x[i], obs.y[i]);
			if(i<18)printf("\033[40;32m■\033[0m");
			if (i < 37 && i >= 18) printf("\033[40;33m■\033[0m");
			if(i>=37&&i<52)	printf("\033[40;36m■\033[0m");
			if (i >=52)printf("\033[40;35m■\033[0m");
		}
}
void control()
{
	fflush(stdin);
	if (foodFlag == 0)//在蛇尾处输出空格即擦去蛇尾
	{
		gotoxy(snake.x[snake.length - 1], snake.y[snake.length - 1]);
		switch (tail) //尾巴痕迹选择功能
		{
		case 1:printf("  "); break;
		case 2:printf("~ "); break;
		case 3:printf("·"); break;
		}
	}
	for (i = snake.length - 1; i > 0; i--)//将蛇的每一节依次向前移动一节(蛇头除外)
	{
		snake.x[i] = snake.x[i - 1];
		snake.y[i] = snake.y[i - 1];
	}
	while (1)
	{
		if ((GetAsyncKeyState(VK_DOWN)) && vkflag != 2)//下
		{
			vkflag = 4;	break;
		}
		if ((GetAsyncKeyState(VK_UP)) && vkflag != 4)//上
		{
			vkflag = 2;	break;
		}
		if ((GetAsyncKeyState(VK_LEFT)) && vkflag != 3)//左
		{
			vkflag = 1;	break;
		}
		if ((GetAsyncKeyState(VK_RIGHT)) && vkflag != 1)//右
		{
			vkflag = 3;	break;
		}
		if (GetAsyncKeyState(VK_SPACE) && 0x20)//暂停功能
			while (1)
			{
				gotoxy(84, 16);
				printf("\033[40;36m游戏已经暂停\033[0m");
				Sleep(200);
				gotoxy(84, 16);
				printf("            "); //闪烁
				Sleep(150);
				if (GetAsyncKeyState(VK_SPACE) && 0x20)
					break;
			}
		break;
	}
	switch (vkflag)//方向
	{
	case 1:	snake.x[0] -= 2; break;//左
	case 2: snake.y[0]--; break;//上
	case 3: snake.x[0] += 2; break;//右
	case 4: snake.y[0]++; break;//下
	}
	gotoxy(snake.x[0], snake.y[0]);//蛇头移动
	printf("◆");
	gotoxy(snake.x[1], snake.y[1]);//蛇身移动
	printf("■");
	foodFlag = 0;
	fflush(stdin);
	return;
}
void foodcreate()
{
	n++;//加速标记
	flag = 1;
    sorce += 10;//每个食物得10分
	if (sorce>=his_max )//最高分
	{
		his_max = sorce;
		gotoxy(82, 2);
		printf("                 ");
		gotoxy(82, 2);
		printf("★历史最高:%d", his_max);
	}
	gotoxy(82, 3);//本局得分
	printf("                 ");
	gotoxy(82, 3);
	printf("☆当前得分:%d", sorce);

	while (flag==1)//生成食物
	{		
	  food.x = rand() % 74 + 4;//随机选取食物的范围
	  food.y = rand() % 24 + 1;
	  if (food.x % 2 != 0 && flag == 1)//优化出现位置
	  {
		  food.x = food.x - 1;
		  flag = 0;
	  }
	  if(map!=1)//非普通地图项
	  for (i = 0; i < snake.length; i++)
	  {
		  for(m=0;m<j;m++)
			  if (obs.x[m] == food.x && obs.y[m] == food.y)
			  {
				  flag = 1;
				  break;
			  }
	  }
	  for (i = 0; i < snake.length; i++)//不能在蛇的身体上生成食物
	  {
		  if (snake.x[i] == food.x && snake.y[i] == food.y)
		  {
			  flag = 1;
			  break;
		  }
	  }
	}
    gotoxy(food.x, food.y);	//生成食物
	printf("●");
	snake.length++;//吃到食物长度加1
	foodFlag = 1;//吃到食物尾部不清除
	return;
}
int  dead()
{
	if (snake.y[0] == 0 || snake.y[0] == map_y-1)//上下边界死亡
		return 0;
	if (snake.x[0] == 0 || snake.x[0] == map_x-2)//左右边界死亡
		return 0;
	if(map!=1)//撞到障碍物死亡
	for (m = 0; m < j; m++)
		if (obs.x[m] == snake.x[0] && obs.y[m] == snake.y[0])
		{
			return 0;
		}
	for (i = 1; i < snake.length; i++)//咬到自身死亡
	{
	if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
		return 0;
	}
	if (GetAsyncKeyState(VK_ESCAPE)&0x1B)//ESC健返回死亡
	{
		ii = 5;
		return 0;
	}
	return 1;
}
void game()//初始化游戏
{
	int i ;
	n = 0;//重置状态
	vkflag = 1;
	sorce = 0;
	foodFlag = 0;
	system("cls");//初始清屏
	frame(1);//打印游戏框架(动态)
	gotoxy(82, 2);
	printf("★历史最高:%d", his_max);
	gotoxy(82, 3);
	printf("☆当前得分:%d", sorce);
	gotoxy(84, 8);
	printf("通过下面按键");
	gotoxy(85, 9);
	printf("\033[40;33m    ↑      \033[0m");
	gotoxy(85, 10);
	printf("\033[40;33m  ←  →    \033[0m");
	gotoxy(85, 11);
	printf("\033[40;33m    ↓      \033[0m");
	gotoxy(83, 12);
	printf("来控制蛇的方向");
	gotoxy(82, 18);
	printf("按空格键暂停/继续");
	gotoxy(83, 20);
	printf("按Shift键 加速");	
	gotoxy(82, 22);
	printf("按ESC键返回菜单");

	snake.length = org_len;//初始化蛇(固定位置)
	snake.x[0] = 50 ;
	snake.y[0] = 20;
	gotoxy(snake.x[0], snake.y[0]);
	printf("◆");
	for (i = 1; i < snake.length; i++)//打印蛇
	{
		Sleep(25);
		snake.x[i] = snake.x[i - 1] + 2;
		snake.y[i] = snake.y[0];
		gotoxy(snake.x[i], snake.y[i]);
		printf("■");
	}
	if (map >=1)
	{
		food.x = rand() % 44 + 4;//初始化食物(左方出现)
		food.y = rand() % 24 + 1;
		if (food.x % 2 != 0)
			food.x = food.x - 1;
	}
	else {
		food.x = 14;//初始化食物(左方出现)
		food.y = 3;
	}
	gotoxy(food.x, food.y);//初始的食物闪烁
	printf("\033[40;37m●\033[0m");
	Sleep(250);
	gotoxy(food.x, food.y);
	printf("  ");
	Sleep(250);
	gotoxy(food.x, food.y);
	printf("\033[40;37m●\033[0m");
	Sleep(250);
	obstacle();
	while(ii==1) //运行
	{
		if (GetAsyncKeyState(VK_SHIFT))//加速功能
		{
			gotoxy(93, 20);
			printf("\033[40;31m加速\033[0m");//特效
		}
		else { Sleep(100);
		gotoxy(93, 20);
		printf("加速");
		}
		Sleep(speed - (changespeed * n));//变速模式
		control();//控制
		if (snake.x[0] == food.x && snake.y[0] == food.y)//吃掉食物
		foodcreate();
		if (dead() != 1) //判断是否结束游戏
		{
			gotoxy(36,12);
			printf("Game over");//结束显示
			gotoxy(36, 14);
			printf("  T _ T  ");
			Sleep(500);
			while (1)
			{
				gotoxy(32, 16);
				printf("请按Enter键返回主菜单");
				Sleep(150);

				if (GetAsyncKeyState(VK_RETURN) & 0x0D)//确认返回
				{
					fflush(stdin);
					ii = 5;
					return;
				}
				
			}
		}	
	}
}
void setup2()//设置显示(分析各种情况)
{
	gotoxy(34, 8);
	switch (org_len)//初始长度
	{
	case 2: printf("初始长度           ◆■           >"); break;
	case 3: printf("初始长度       <   ◆■■         >"); break;
	case 4: printf("初始长度       <   ◆■■■       >"); break;
	case 5: printf("初始长度       <   ◆■■■■     >"); break;
	case 6: printf("初始长度       <   ◆■■■■■   >"); break;
	case 7: printf("初始长度       <   ◆■■■■■■  "); break;
	}
	gotoxy(34, 10);
	switch (speed)//初始速度
	{
	case  50:printf("游戏初速度     <   较快    "); break;
	case 100:printf("游戏初速度     <   中等   >"); break;
	case 150:printf("游戏初速度         较慢   >"); break;
	}
	gotoxy(34, 12);
	switch (changespeed)//是否变速
	{
	case 0:printf("吃到食物加速        否    >"); break;
	case 5:printf("吃到食物加速   <    是     "); break;
	}
	gotoxy(34, 14);
	switch (tail)//尾巴选择
	{
	case 1:printf("当前尾巴痕迹        无    >"); break;
	case 2:printf("当前尾巴痕迹   <    ~     >"); break;
	case 3:printf("当前尾巴痕迹   <   ·      "); break;
	}
	gotoxy(34, 16);
	switch (map)//地图选择
	{
	case -1:printf("当前地图难度      特别版2 >"); break;
	case 0:printf("当前地图难度   <  特别版1 >"); break;
	case 1:printf("当前地图难度   <   普通   >"); break;
	case 2:printf("当前地图难度   <   困难   >"); break;
	case 3:printf("当前地图难度   <   地狱   >"); break;
	case 4:printf("当前地图难度   <   传说    "); break;
	}
    gotoxy(70, 22);
    printf("确定并返回菜单"); 

	for (i = 0; i < 7; i++)
	{
		gotoxy(31, 8 + 2 * i);
		printf("  ");
	}
	gotoxy(67, 22);
	printf("  ");
	switch (set_flag)
	{
	case 1:gotoxy(31,  8); break;
	case 2:gotoxy(31, 10); break;
	case 3:gotoxy(31, 12); break;
	case 4:gotoxy(31, 14); break;
	case 5:gotoxy(31, 16); break;
	case 6:gotoxy(67, 22); break;
	}
	printf("★");
	return;
}
void setup()//设置操作(改变全局变量)
{
	frame(2);
	set_flag=1;
	gotoxy(30, 3);
	printf("      ■■◆    游戏设置    ◆■■");
	gotoxy(26, 4);
	printf("■■■■■■                        ■■■■■■");
	setup2();
	fflush(stdin);
	while (1)
	{
		if (GetAsyncKeyState(VK_DOWN))//下
		{
			if (set_flag == 6)
				set_flag = 1;
			else set_flag++;
		}
		if (GetAsyncKeyState(VK_UP))//上
		{
			if (set_flag == 1)
				set_flag = 6;
			else set_flag--;
		}
		if (GetAsyncKeyState(VK_LEFT))//左
		{
			switch (set_flag)
			{
			case 1: if (org_len > 2)
				org_len--; break;
			case 2: if (speed < 150)
				speed += 50; break;
			case 3: if (changespeed == 5)
				changespeed = 0;break;
			case 4: if (tail > 1)
				tail--;break;
			case 5: if (map > -1)
				map--;break;
			case 6: break;
			}
		}
		if (GetAsyncKeyState(VK_RIGHT))//右
		{
			switch (set_flag)
			{
			case 1: if (org_len < 7)
				org_len++;break;
			case 2: if (speed > 50)
				speed -= 50;break;
			case 3: if (changespeed == 0)
				changespeed = 5;break;
			case 4: if (tail < 3)
				tail++;break;
			case 5: if (map < 4)
				map++;break;
			case 6:break;
			}
		}
		setup2();
		if ((GetAsyncKeyState(VK_RETURN)&0x0D)&&set_flag==6)
		{
			ii = 5;
			return;
		}
		Sleep(175);
	}
	return;
}
void instructions()//游戏说明
{
	system("cls");
	frame(2);
	gotoxy(10, 3);
	printf("游戏说明:");
	gotoxy(18, 5);
	printf("一条蛇在封闭空间里,空间内随机出现一个食物,通过按键盘四个光标");
	gotoxy(18, 7);
	printf("键↑←↓→控制蛇向上下左右四个方向移动来获取食物食物,当食物被");
	gotoxy(18, 9);
	printf("吃掉,蛇身体长一节,同时记10分,接着又出现新的食物,如果蛇撞到");
	gotoxy(18, 11);
	printf("墙或蛇头撞到自己身体或撞到障碍物,游戏结束。");
	gotoxy(18, 15);
	printf("温馨提示:游戏过程中,可按Shift键加速,但不能同时按方向键,也");
	gotoxy(18, 17);
	printf("          可以按空格键来暂停游戏。                          ");
	gotoxy(60, 20);
	printf("按确认键返回主菜单");
	gotoxy(3, 23);
	printf("当前游戏版本 V1.0");
	while (1)//按确认键返回主菜单
	{
		Sleep(100);
		(void)_getch();
		if (GetAsyncKeyState(VK_RETURN))//确认
		{
			ii = 5;
			break;
		}
	}
}
void end()//游戏退出
{
	frame(2);
	gotoxy(44, 12);
	printf("游戏已退出");
	gotoxy(0, 26);
}
main()//游戏框架
{
	frame(2);
	loading();
	while (ii == 1 || ii == 2 || ii == 3||ii==5)
	{
		system("cls");
		Sleep(200);	
		menu(ii);
		chose();
		switch (ii)
		{
		case 1:game(); break;
		case 2:setup(); break;
		case 3:instructions(); break;
		case 4:break;
		case 5:ii = 1; continue;
		}
	}
	end();
}

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

第四维度4

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值