精华内容
下载资源
问答
  • c 贪吃蛇
    2021-05-19 05:55:14

    c语言贪吃蛇[编辑]

    概述

    c语言贪吃蛇是用c语言编写的贪吃蛇。贪吃蛇游戏是经典手机游戏,既简单又耐玩。通过控制蛇头方向吃蛋,使得蛇变长,从而获得积分。

    一、简介

    c语言贪吃蛇是用c语言编写的贪吃蛇。

    C语言是一门通用计算机编程语言,应用广泛。

    C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、产生少量的机器码以及不需要任何运行环境支

    持便能运行的编程语言。

    尽管C语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的C语言程序可在许多

    电脑平台上进行编译,甚至包含一些嵌入式处理器(单片机或称MCU)以及超级电脑等作业平台。

    二十世纪八十年代,为了避免各开发厂商用的C语言语法产生差异,由美国国家标准局为C语言订定了一套完整的国际

    标准语法,称为ANSI C,作为C语言最初的标准。

    贪吃蛇 游戏是经典手机游戏,既简单又耐玩。

    通过控制蛇头方向吃蛋,使得蛇变长,从而获得积分。

    贪吃蛇钻井测井技术是一种运用旋转导向系统、随钻测井系统等的油气田定向钻井、随钻测井技术,可完成海上“丛式

    井”和复杂油气层的开采需求,大幅降低油气田开发综合成本。

    二、实现要求

    产生一个固定大小没有边界的游戏区域,蛇从区域的中心开始,由玩家通过键盘控制蛇的运动方向,用蛇头去吃随机

    分布在游戏区域内的食物; 蛇的运动限制在游戏区域内,游戏区域没有边界,所以蛇在区域内作循环运动; 蛇的运

    动方向为直线运动,只走横和竖的方向,不走斜线; 蛇的运动速度由游戏的难度来控制,难度越高,速度越快,游戏

    难度分为9个等级; 蛇身体的长度从1开始每吃掉一份食物就增加一个长度; 食物的出现安照随机分布的原则,蛇吃

    掉一份后随即在游戏区域内放一份新的食物; 每吃掉一份食物得分为10*游戏的难度,游戏结束后统计全部的得分;

    游戏结束的条件为:在控制蛇的过程中蛇头碰到蛇的身体的任何部位。

    三、游戏玩法

    一条蛇在密闭的围墙内,在围墙内随机出现一个食物,通过按键盘上的四个光标键控制蛇向上下左右四个方向移动,

    舌头撞到食物,则表示食物被蛇吃掉,这时蛇的身体长一节,同时计10分,接着又出现食物,等待被蛇吃掉,每吃

    10个食物,则升一级,蛇移动的速度也会随着加快,如果蛇在移动过程中,撞到墙壁或身体则游戏结束。

    参考资料: 百度百科

    搜狗百科

    扩展阅读:

    相关词条:

    合作编辑:

    分享到:

    更多

    网络营销词典内容均由网友提供,仅供参考。如发现词条内容有问题,请发邮件至info # wm23.com。

    更多相关内容
  • C语言贪吃蛇实验报告
  • 实用文案 C 语言程序设计报告 标准文档 实用文案 题目贪吃蛇游戏的程序设计 院系西语学院 英语教育 6 班 姓名 学号 标准文档 实用文案 1.1 题目 设计贪吃蛇小游戏 1.2 题目的要求 玩家通过键盘控制蛇在地图上寻找...
  • C语言贪吃蛇

    2018-10-31 19:47:10
    C语言制作的基本的贪吃蛇游戏,带有背景音乐和源代码。
  • C语言贪吃蛇,贪吃蛇C语言代码实现大全

    千次阅读 多人点赞 2022-03-02 09:52:29
    一、C语言贪吃蛇代码实现前言 设计贪吃蛇游戏的主要目的是让大家夯实C语言基础,训练编程思维,培养解决问题的思路,领略多姿多彩的C语言。 贪吃蛇是非常经典的一款游戏,本次我们模拟在控制台实现贪吃蛇游戏,也...

    一、C语言贪吃蛇代码实现前言

    设计贪吃蛇游戏的主要目的是让大家夯实C语言基础,训练编程思维,培养解决问题的思路,领略多姿多彩的C语言。

    贪吃蛇是非常经典的一款游戏,本次我们模拟在控制台实现贪吃蛇游戏,也就是实现贪吃蛇的基本功能,比如在地图中,用“↑↓←→”控制移动蛇的方向,吃掉食物之后,蛇身体会变长等等。。。。

    首先我们得分析,游戏中我们会碰见的一些情况。

    ①蛇的部分,蛇的身子是一节一节的,此时最容易联想到的数据结构就是顺序表,链表,如果把蛇比做顺序表或者链表,在之后吃到食物的时候,身子肯定会变长,这就涉及到插入的操作,所以为了更高的效率,我们用链表实现我们的蛇的部分,最初我们把蛇身子按照四个结点打印在屏幕。

    ②蛇的移动,在屏幕上面蛇的移动看起来是整个身子向前方平移一个单位,但是其原理是我们在屏幕的另一个地方把蛇从新打印一遍,又把之前的蛇身子去除掉。

    ③食物的产生,随机的在地图中产生一个节点,在蛇的头坐标和食物的坐标重复的时候,食物消失,蛇的身子加长,也就是蛇的节点数增加一个。

    ④蛇在其中的几种状态,正常状态:蛇头节点的坐标没有和墙的坐标以及自己身子的坐标重合,

    被自己杀死:蛇头的坐标和蛇身子的坐标重合,撞墙:蛇头的坐标和墙的坐标重合。穿墙:蛇不会撞墙而死。

    二、C语言贪吃蛇代码实现游戏说明

    1、大 量 C语言项目游戏 源 代 码  获 取 可 以 关 注 微 信 公 众 号:“ C和C加加 ” 回复:“TC”即可

    2、C语言贪吃蛇游戏界面当中没有打印相关的按键说明,这里先逐一列出C语言贪吃蛇游戏按键说明

    • 按方向键上下左右,可以实现蛇移动方向的改变。

    • 短时间长按方向键上下左右其中之一,可实现蛇向该方向的短时间加速移动。

    • 按空格键可实现暂停,暂停后按任意键继续游戏。

    • 按Esc键可直接退出游戏。

    • 按R键可重新开始游戏。

    除此之外,本游戏还拥有计分系统,可保存玩家的历史最高记录。

    三、C语言贪吃蛇代码游戏效果展示

    贪吃蛇游戏当中蛇的移动速度可以进行调整,动图当中把速度调得较慢(速度太快导致动图上蛇身显示不全),下面给出的代码当中将蛇的速度调整到了合适的位置,大家可以试试

    四、C语言贪吃蛇游戏代码大全如下

    大家可以将以下代码复制到自己的编译器当中运行:

    #include <stdio.h>
    #include <Windows.h>
    #include <stdlib.h>
    #include <time.h>
    #include <conio.h>
    
    #define ROW 22 //游戏区行数
    #define COL 42 //游戏区列数
    
    #define KONG 0 //标记空(什么也没有)
    #define WALL 1 //标记墙
    #define FOOD 2 //标记食物
    #define HEAD 3 //标记蛇头
    #define BODY 4 //标记蛇身
    
    #define UP 72 //方向键:上
    #define DOWN 80 //方向键:下
    #define LEFT 75 //方向键:左
    #define RIGHT 77 //方向键:右
    #define SPACE 32 //暂停
    #define ESC 27 //退出
    
    //蛇头
    struct Snake
    {
    	int len; //记录蛇身长度
    	int x; //蛇头横坐标
    	int y; //蛇头纵坐标
    }snake;
    
    //蛇身
    struct Body
    {
    	int x; //蛇身横坐标
    	int y; //蛇身纵坐标
    }body[ROW*COL]; //开辟足以存储蛇身的结构体数组
    
    int face[ROW][COL]; //标记游戏区各个位置的状态
    
    //隐藏光标
    void HideCursor();
    //光标跳转
    void CursorJump(int x, int y);
    //初始化界面
    void InitInterface();
    //颜色设置
    void color(int c);
    //从文件读取最高分
    void ReadGrade();
    //更新最高分到文件
    void WriteGrade();
    //初始化蛇
    void InitSnake();
    //随机生成食物
    void RandFood();
    //判断得分与结束
    void JudgeFunc(int x, int y);
    //打印蛇与覆盖蛇
    void DrawSnake(int flag);
    //移动蛇
    void MoveSnake(int x, int y);
    //执行按键
    void run(int x, int y);
    //游戏主体逻辑函数
    void Game();
    
    int max, grade; //全局变量
    int main()
    {
    #pragma warning (disable:4996) //消除警告
    	max = 0, grade = 0; //初始化变量
    	system("title 贪吃蛇"); //设置cmd窗口的名字
    	system("mode con cols=84 lines=23"); //设置cmd窗口的大小
    	HideCursor(); //隐藏光标
    	ReadGrade(); //从文件读取最高分到max变量
    	InitInterface(); //初始化界面
    	InitSnake(); //初始化蛇
    	srand((unsigned int)time(NULL)); //设置随机数生成起点
    	RandFood(); //随机生成食物
    	DrawSnake(1); //打印蛇
    	Game(); //开始游戏
    	return 0;
    }
    
    //隐藏光标
    void HideCursor()
    {
    	CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
    	curInfo.dwSize = 1; //如果没赋值的话,光标隐藏无效
    	curInfo.bVisible = FALSE; //将光标设置为不可见
    	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    	SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
    }
    //光标跳转
    void CursorJump(int x, int y)
    {
    	COORD pos; //定义光标位置的结构体变量
    	pos.X = x; //横坐标
    	pos.Y = y; //纵坐标
    	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    	SetConsoleCursorPosition(handle, pos); //设置光标位置
    }
    //初始化界面
    void InitInterface()
    {
    	color(6); //颜色设置为土黄色
    	for (int i = 0; i < ROW; i++)
    	{
    		for (int j = 0; j < COL; j++)
    		{
    			if (j == 0 || j == COL - 1)
    			{
    				face[i][j] = WALL; //标记该位置为墙
    				CursorJump(2 * j, i);
    				printf("■");
    			}
    			else if (i == 0 || i == ROW - 1)
    			{
    				face[i][j] = WALL; //标记该位置为墙
    				printf("■");
    			}
    			else
    			{
    				face[i][j] = KONG; //标记该位置为空
    			}
    		}
    	}
    	color(7); //颜色设置为白色
    	CursorJump(0, ROW);
    	printf("当前得分:%d", grade);
    	CursorJump(COL, ROW);
    	printf("历史最高得分:%d", max);
    }
    //颜色设置
    void color(int c)
    {
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //颜色设置
    	//注:SetConsoleTextAttribute是一个API(应用程序编程接口)
    }
    //从文件读取最高分
    void ReadGrade()
    {
    	FILE* pf = fopen("贪吃蛇最高得分记录.txt", "r"); //以只读的方式打开文件
    	if (pf == NULL) //打开文件失败
    	{
    		pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
    		fwrite(&max, sizeof(int), 1, pf); //将max写入文件(此时max为0),即将最高得分初始化为0
    	}
    	fseek(pf, 0, SEEK_SET); //使文件指针pf指向文件开头
    	fread(&max, sizeof(int), 1, pf); //读取文件当中的最高得分到max当中
    	fclose(pf); //关闭文件
    	pf = NULL; //文件指针及时置空
    }
    //更新最高分到文件
    void WriteGrade()
    {
    	FILE* pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
    	if (pf == NULL) //打开文件失败
    	{
    		printf("保存最高得分记录失败\n");
    		exit(0);
    	}
    	fwrite(&grade, sizeof(int), 1, pf); //将本局游戏得分写入文件当中
    	fclose(pf); //关闭文件
    	pf = NULL; //文件指针及时置空
    }
    //初始化蛇
    void InitSnake()
    {
    	snake.len = 2; //蛇的身体长度初始化为2
    	snake.x = COL / 2; //蛇头位置的横坐标
    	snake.y = ROW / 2; //蛇头位置的纵坐标
    	//蛇身坐标的初始化
    	body[0].x = COL / 2 - 1;
    	body[0].y = ROW / 2;
    	body[1].x = COL / 2 - 2;
    	body[1].y = ROW / 2;
    	//将蛇头和蛇身位置进行标记
    	face[snake.y][snake.x] = HEAD;
    	face[body[0].y][body[0].x] = BODY;
    	face[body[1].y][body[1].x] = BODY;
    }
    //随机生成食物
    void RandFood()
    {
    	int i, j;
    	do
    	{
    		//随机生成食物的横纵坐标
    		i = rand() % ROW;
    		j = rand() % COL;
    	} while (face[i][j] != KONG); //确保生成食物的位置为空,若不为空则重新生成
    	face[i][j] = FOOD; //将食物位置进行标记
    	color(12); //颜色设置为红色
    	CursorJump(2 * j, i); //光标跳转到生成的随机位置处
    	printf("●"); //打印食物
    }
    //判断得分与结束
    void JudgeFunc(int x, int y)
    {
    	//若蛇头即将到达的位置是食物,则得分
    	if (face[snake.y + y][snake.x + x] == FOOD)
    	{
    		snake.len++; //蛇身加长
    		grade += 10; //更新当前得分
    		color(7); //颜色设置为白色
    		CursorJump(0, ROW);
    		printf("当前得分:%d", grade); //重新打印当前得分
    		RandFood(); //重新随机生成食物
    	}
    	//若蛇头即将到达的位置是墙或者蛇身,则游戏结束
    	else if (face[snake.y + y][snake.x + x] == WALL || face[snake.y + y][snake.x + x] == BODY)
    	{
    		Sleep(1000); //留给玩家反应时间
    		system("cls"); //清空屏幕
    		color(7); //颜色设置为白色
    		CursorJump(2 * (COL / 3), ROW / 2 - 3);
    		if (grade > max)
    		{
    			printf("恭喜你打破最高记录,最高记录更新为%d", grade);
    			WriteGrade();
    		}
    		else if (grade == max)
    		{
    			printf("与最高记录持平,加油再创佳绩", grade);
    		}
    		else
    		{
    			printf("请继续加油,当前与最高记录相差%d", max - grade);
    		}
    		CursorJump(2 * (COL / 3), ROW / 2);
    		printf("GAME OVER");
    		while (1) //询问玩家是否再来一局
    		{
    			char ch;
    			CursorJump(2 * (COL / 3), ROW / 2 + 3);
    			printf("再来一局?(y/n):");
    			scanf("%c", &ch);
    			if (ch == 'y' || ch == 'Y')
    			{
    				system("cls");
    				main();
    			}
    			else if (ch == 'n' || ch == 'N')
    			{
    				CursorJump(2 * (COL / 3), ROW / 2 + 5);
    				exit(0);
    			}
    			else
    			{
    				CursorJump(2 * (COL / 3), ROW / 2 + 5);
    				printf("选择错误,请再次选择");
    			}
    		}
    	}
    }
    //打印蛇与覆盖蛇
    void DrawSnake(int flag)
    {
    	if (flag == 1) //打印蛇
    	{
    		color(10); //颜色设置为绿色
    		CursorJump(2 * snake.x, snake.y);
    		printf("■"); //打印蛇头
    		for (int i = 0; i < snake.len; i++)
    		{
    			CursorJump(2 * body[i].x, body[i].y);
    			printf("□"); //打印蛇身
    		}
    	}
    	else //覆盖蛇
    	{
    		if (body[snake.len - 1].x != 0) //防止len++后将(0, 0)位置的墙覆盖
    		{
    			//将蛇尾覆盖为空格即可
    			CursorJump(2 * body[snake.len - 1].x, body[snake.len - 1].y);
    			printf("  ");
    		}
    	}
    }
    //移动蛇
    void MoveSnake(int x, int y)
    {
    	DrawSnake(0); //先覆盖当前所显示的蛇
    	face[body[snake.len - 1].y][body[snake.len - 1].x] = KONG; //蛇移动后蛇尾重新标记为空
    	face[snake.y][snake.x] = BODY; //蛇移动后蛇头的位置变为蛇身
    	//蛇移动后各个蛇身位置坐标需要更新
    	for (int i = snake.len - 1; i > 0; i--)
    	{
    		body[i].x = body[i - 1].x;
    		body[i].y = body[i - 1].y;
    	}
    	//蛇移动后蛇头位置信息变为第0个蛇身的位置信息
    	body[0].x = snake.x;
    	body[0].y = snake.y;
    	//蛇头的位置更改
    	snake.x = snake.x + x;
    	snake.y = snake.y + y;
    	DrawSnake(1); //打印移动后的蛇
    }
    //执行按键
    void run(int x, int y)
    {
    	int t = 0;
    	while (1)
    	{
    		if (t == 0)
    			t = 3000; //这里t越小,蛇移动速度越快(可以根据次设置游戏难度)
    		while (--t)
    		{
    			if (kbhit() != 0) //若键盘被敲击,则退出循环
    				break;
    		}
    		if (t == 0) //键盘未被敲击
    		{
    			JudgeFunc(x, y); //判断到达该位置后,是否得分与游戏结束
    			MoveSnake(x, y); //移动蛇
    		}
    		else //键盘被敲击
    		{
    			break; //返回Game函数读取键值
    		}
    	}
    }
    //游戏主体逻辑函数
    void Game()
    {
    	int n = RIGHT; //开始游戏时,默认向后移动
    	int tmp = 0; //记录蛇的移动方向
    	goto first; //第一次进入循环先向默认方向前进
    	while (1)
    	{
    		n = getch(); //读取键值
    		//在执行前,需要对所读取的按键进行调整
    		switch (n)
    		{
    		case UP:
    		case DOWN: //如果敲击的是“上”或“下”
    			if (tmp != LEFT&&tmp != RIGHT) //并且上一次蛇的移动方向不是“左”或“右”
    			{
    				n = tmp; //那么下一次蛇的移动方向设置为上一次蛇的移动方向
    			}
    			break;
    		case LEFT:
    		case RIGHT: //如果敲击的是“左”或“右”
    			if (tmp != UP&&tmp != DOWN) //并且上一次蛇的移动方向不是“上”或“下”
    			{
    				n = tmp; //那么下一次蛇的移动方向设置为上一次蛇的移动方向
    			}
    		case SPACE:
    		case ESC:
    		case 'r':
    		case 'R':
    			break; //这四个无需调整
    		default:
    			n = tmp; //其他键无效,默认为上一次蛇移动的方向
    			break;
    		}
    	first: //第一次进入循环先向默认方向前进
    		switch (n)
    		{
    		case UP: //方向键:上
    			run(0, -1); //向上移动(横坐标偏移为0,纵坐标偏移为-1)
    			tmp = UP; //记录当前蛇的移动方向
    			break;
    		case DOWN: //方向键:下
    			run(0, 1); //向下移动(横坐标偏移为0,纵坐标偏移为1)
    			tmp = DOWN; //记录当前蛇的移动方向
    			break;
    		case LEFT: //方向键:左
    			run(-1, 0); //向左移动(横坐标偏移为-1,纵坐标偏移为0)
    			tmp = LEFT; //记录当前蛇的移动方向
    			break;
    		case RIGHT: //方向键:右
    			run(1, 0); //向右移动(横坐标偏移为1,纵坐标偏移为0)
    			tmp = RIGHT; //记录当前蛇的移动方向
    			break;
    		case SPACE: //暂停
    			system("pause>nul"); //暂停后按任意键继续
    			break;
    		case ESC: //退出
    			system("cls"); //清空屏幕
    			color(7); //颜色设置为白色
    			CursorJump(COL - 8, ROW / 2);
    			printf("  游戏结束  ");
    			CursorJump(COL - 8, ROW / 2 + 2);
    			exit(0);
    		case 'r':
    		case 'R': //重新开始
    			system("cls"); //清空屏幕
    			main(); //重新执行主函数
    		}
    	}
    }
    

    五、C语言贪吃蛇游戏代码详解

    1、贪吃蛇C语言实现游戏框架构建

    首先定义游戏界面的大小,定义游戏区行数和列数。

     

    这里将蛇活动的区域称为游戏区,将分数提示的区域称为提示区(提示区占一行)。

     

    此外,我们还需要两个结构体用于表示蛇头和蛇身。蛇头结构体当中存储着当前蛇身的长度以及蛇头的位置坐标。

     

    蛇身结构体当中存储着该段蛇身的位置坐标。

     

    同时我们需要一个二维数组来标记游戏区各个位置的状态(空、墙、食物、蛇头以及蛇身)。

     

    为了增加代码的可读性,最好运用宏来定义各个位置的状态,而不是在代码中用干巴巴的数字对各个位置的状态进行切换。

     

    当然,为了代码的可读性,我们最好也将需要用到的按键的键值用宏进行定义。

    2、隐藏光标

    隐藏光标比较简单,定义一个光标信息的结构体变量,然后对光标信息进行赋值,最后用这个光标信息的结构体变量进行光标信息设置即可。

    3、光标跳转

    光标跳转,也就是让光标跳转到指定位置进行输出。与隐藏光标的操作步骤类似,先定义一个光标位置的结构体变量,然后设置光标的横纵坐标,最后用这个光标位置的结构体变量进行光标位置设置即可。

    4、初始化界面

    初始化界面完成游戏区“墙”的打印,和提示区的打印即可。

    在打印过程中需要注意两点:

    在cmd窗口中一个小方块占两个单位的横坐标,一个单位的纵坐标。

    光标跳转函数CursorJump接收的是光标将要跳至位置的横纵坐标。

    例如,要用CursorJump函数跳转至 i 行 j 列(以一个小方块为一个单位),就等价于让光标跳转至坐标(2*j,i)处。

    //初始化界面
    void InitInterface()
    {
    	color(6); //颜色设置为土黄色
    	for (int i = 0; i < ROW; i++)
    	{
    		for (int j = 0; j < COL; j++)
    		{
    			if (j == 0 || j == COL - 1)
    			{
    				face[i][j] = WALL; //标记该位置为墙
    				CursorJump(2 * j, i);
    				printf("■");
    			}
    			else if (i == 0 || i == ROW - 1)
    			{
    				face[i][j] = WALL; //标记该位置为墙
    				printf("■");
    			}
    			else
    			{
    				face[i][j] = KONG; //标记该位置为空
    			}
    		}
    	}
    	color(7); //颜色设置为白色
    	CursorJump(0, ROW);
    	printf("当前得分:%d", grade);
    	CursorJump(COL, ROW);
    	printf("历史最高得分:%d", max);
    }
    

    注意: 在初始化界面的同时,记得对游戏区相应位置的状态进行标记。

    5、C语言贪吃蛇游戏颜色设置

    颜色设置函数的作用是,将此后输出的内容颜色都更为所指定的颜色,接收的参数c是颜色代码,十进制颜色代码表如下:

     

    设置颜色函数在其头文件当中的声明如下:

     

    6、初始化蛇

    初始化蛇时将蛇身的长度初始化为2,蛇头的起始位置在游戏区的中央,蛇头向右依次是第0个蛇身、第1个蛇身。

     在初始化蛇的信息后,记得对游戏区该位置的状态进行标记。

    7、随机生成食物

    随机在游戏区生成食物,需要对生成后的坐标进行判断,只有该位置为空才能在此生成食物,否则需要重新生成坐标。食物坐标确定后,需要对游戏区该位置的状态进行标记。

    8、打印蛇与覆盖蛇

    打印蛇和覆盖蛇这里直接使用一个函数来实现,若传入参数flag为1,则打印蛇;若传入参数为0,则用空格覆盖蛇。

    打印蛇:

    先根据结构体变量snake获取蛇头的坐标,到相应位置打印蛇头。

    然后根据结构体数组body依次获取蛇身的坐标,到相应位置进行打印即可。

    覆盖蛇:

    用空格覆盖最后一段蛇身即可。

    但需要注意在覆盖前判断覆盖的位置是否为(0,0)位置,因为当得分后蛇身长度增加,需要覆盖当前的蛇(进而打印长度增加后的蛇),而此时新加蛇身还未进行赋值(编译器一般默认初始化为0),我们根据最后一段蛇身获取到的坐标便是(0,0),则会用空格对(0,0)位置的墙进行覆盖,需要看完后面的移动蛇函数的实现后再进行理解。(也可以先将该判断去掉,观察蛇吃到食物后(0,0)位置墙的变化再进行分析)

    //打印蛇与覆盖蛇
    void DrawSnake(int flag)
    {
    	if (flag == 1) //打印蛇
    	{
    		color(10); //颜色设置为绿色
    		CursorJump(2 * snake.x, snake.y);
    		printf("■"); //打印蛇头
    		for (int i = 0; i < snake.len; i++)
    		{
    			CursorJump(2 * body[i].x, body[i].y);
    			printf("□"); //打印蛇身
    		}
    	}
    	else //覆盖蛇
    	{
    		if (body[snake.len - 1].x != 0) //防止len++后将(0, 0)位置的墙覆盖
    		{
    			//将蛇尾覆盖为空格即可
    			CursorJump(2 * body[snake.len - 1].x, body[snake.len - 1].y);
    			printf("  ");
    		}
    	}
    }
    

    9、移动蛇

    移动蛇函数的作用就是先覆盖当前所显示的蛇,然后再打印移动后的蛇。

    参数说明:

    x:蛇移动后的横坐标相对于当前蛇的横坐标的变化。

    y:蛇移动后的纵坐标相对于当前蛇的纵坐标的变化。

    蛇移动后,各种信息需要变化:

    最后一段蛇身在游戏区当中需要被重新标记为空。

    蛇头位置在游戏区当中需要被重新标记为蛇身。

    存储蛇身坐标信息的结构体数组body当中,需要将第i段蛇身的坐标信息更新为第i-1段蛇身的坐标信息,而第0段,即第一段蛇身的坐标信息需要更新为当前蛇头的坐标信息。

    蛇头的坐标信息需要根据传入的参数x和y,进行重新计算。

    10、游戏主体逻辑函数

    主体逻辑:

    首先第一次进入该函数,默认蛇向右移动,进而执行run函数。

    直到键盘被敲击,再从run函数返回到Game函数进行按键读取。

    读取到键值后需要对读取到的按键进行调整(这是必要的)。

    调整后再进行按键执行,然后再进行按键读取,如此循环进行。

    按键调整机制:

    如果敲击的是“上”或“下”键,并且上一次蛇的移动方向不是“左”或“右”,那么将下一次蛇的移动方向设置为上一次蛇的移动方向,即移动方向不变。

    如果敲击的是“左”或“右”键,并且上一次蛇的移动方向不是“上”或“下”,那么将下一次蛇的移动方向设置为上一次蛇的移动方向,即移动方向不变。

    如果敲击的按键是空格、Esc、r或是R,则不作调整。

    其余按键无效,下一次蛇的移动方向设置为上一次蛇的移动方向,即移动方向不变。

    //游戏主体逻辑函数
    void Game()
    {
    	int n = RIGHT; //开始游戏时,默认向后移动
    	int tmp = 0; //记录蛇的移动方向
    	goto first; //第一次进入循环先向默认方向前进
    	while (1)
    	{
    		n = getch(); //读取键值
    		//在执行前,需要对所读取的按键进行调整
    		switch (n)
    		{
    		case UP:
    		case DOWN: //如果敲击的是“上”或“下”
    			if (tmp != LEFT&&tmp != RIGHT) //并且上一次蛇的移动方向不是“左”或“右”
    			{
    				n = tmp; //那么下一次蛇的移动方向设置为上一次蛇的移动方向
    			}
    			break;
    		case LEFT:
    		case RIGHT: //如果敲击的是“左”或“右”
    			if (tmp != UP&&tmp != DOWN) //并且上一次蛇的移动方向不是“上”或“下”
    			{
    				n = tmp; //那么下一次蛇的移动方向设置为上一次蛇的移动方向
    			}
    		case SPACE:
    		case ESC:
    		case 'r':
    		case 'R':
    			break; //这四个无需调整
    		default:
    			n = tmp; //其他键无效,默认为上一次蛇移动的方向
    			break;
    		}
    	first: //第一次进入循环先向默认方向前进
    		switch (n)
    		{
    		case UP: //方向键:上
    			run(0, -1); //向上移动(横坐标偏移为0,纵坐标偏移为-1)
    			tmp = UP; //记录当前蛇的移动方向
    			break;
    		case DOWN: //方向键:下
    			run(0, 1); //向下移动(横坐标偏移为0,纵坐标偏移为1)
    			tmp = DOWN; //记录当前蛇的移动方向
    			break;
    		case LEFT: //方向键:左
    			run(-1, 0); //向左移动(横坐标偏移为-1,纵坐标偏移为0)
    			tmp = LEFT; //记录当前蛇的移动方向
    			break;
    		case RIGHT: //方向键:右
    			run(1, 0); //向右移动(横坐标偏移为1,纵坐标偏移为0)
    			tmp = RIGHT; //记录当前蛇的移动方向
    			break;
    		case SPACE: //暂停
    			system("pause>nul"); //暂停后按任意键继续
    			break;
    		case ESC: //退出
    			system("cls"); //清空屏幕
    			color(7); //颜色设置为白色
    			CursorJump(COL - 8, ROW / 2);
    			printf("  游戏结束  ");
    			CursorJump(COL - 8, ROW / 2 + 2);
    			exit(0);
    		case 'r':
    		case 'R': //重新开始
    			system("cls"); //清空屏幕
    			main(); //重新执行主函数
    		}
    	}
    }
    

    11、执行按键

    参数说明:

    x:蛇移动后的横坐标相对于当前蛇的横坐标的变化。

    y:蛇移动后的纵坐标相对于当前蛇的纵坐标的变化。

    给定一定的时间间隔,若在该时间间隔内键盘被敲击,则退出run函数,返回Game函数进行按键读取。若未被敲击,则先判断蛇到达移动后的位置后是否得分或是游戏结束,然后再移动蛇的位置。

    若键盘一直未被敲击,则就会一直执行run函数当中的while函数,蛇就会一直朝一个方向移动,直到游戏结束。

    //执行按键
    void run(int x, int y)
    {
    	int t = 0;
    	while (1)
    	{
    		if (t == 0)
    			t = 3000; //这里t越小,蛇移动速度越快(可以根据次设置游戏难度)
    		while (--t)
    		{
    			if (kbhit() != 0) //若键盘被敲击,则退出循环
    				break;
    		}
    		if (t == 0) //键盘未被敲击
    		{
    			JudgeFunc(x, y); //判断到达该位置后,是否得分与游戏结束
    			MoveSnake(x, y); //移动蛇
    		}
    		else //键盘被敲击
    		{
    			break; //返回Game函数读取键值
    		}
    	}
    }
    

    12、判断得分与结束

    判断得分:

    若蛇头即将到达的位置是食物,则得分。得分后需要将蛇身加长,并且更新当前得分,除此之外,还需要重新生成食物。

    判断结束:

    若蛇头即将到达的位置是墙或者蛇身,则游戏结束。游戏结束后比较本局得分和历史最高得分,给出相应的提示语句,并且询问玩家是否再来一局,可自由发挥。

    //判断得分与结束
    void JudgeFunc(int x, int y)
    {
    	//若蛇头即将到达的位置是食物,则得分
    	if (face[snake.y + y][snake.x + x] == FOOD)
    	{
    		snake.len++; //蛇身加长
    		grade += 10; //更新当前得分
    		color(7); //颜色设置为白色
    		CursorJump(0, ROW);
    		printf("当前得分:%d", grade); //重新打印当前得分
    		RandFood(); //重新随机生成食物
    	}
    	//若蛇头即将到达的位置是墙或者蛇身,则游戏结束
    	else if (face[snake.y + y][snake.x + x] == WALL || face[snake.y + y][snake.x + x] == BODY)
    	{
    		Sleep(1000); //留给玩家反应时间
    		system("cls"); //清空屏幕
    		color(7); //颜色设置为白色
    		CursorJump(2 * (COL / 3), ROW / 2 - 3);
    		if (grade > max)
    		{
    			printf("恭喜你打破最高记录,最高记录更新为%d", grade);
    			WriteGrade();
    		}
    		else if (grade == max)
    		{
    			printf("与最高记录持平,加油再创佳绩", grade);
    		}
    		else
    		{
    			printf("请继续加油,当前与最高记录相差%d", max - grade);
    		}
    		CursorJump(2 * (COL / 3), ROW / 2);
    		printf("GAME OVER");
    		while (1) //询问玩家是否再来一局
    		{
    			char ch;
    			CursorJump(2 * (COL / 3), ROW / 2 + 3);
    			printf("再来一局?(y/n):");
    			scanf("%c", &ch);
    			if (ch == 'y' || ch == 'Y')
    			{
    				system("cls");
    				main();
    			}
    			else if (ch == 'n' || ch == 'N')
    			{
    				CursorJump(2 * (COL / 3), ROW / 2 + 5);
    				exit(0);
    			}
    			else
    			{
    				CursorJump(2 * (COL / 3), ROW / 2 + 5);
    				printf("选择错误,请再次选择");
    			}
    		}
    	}
    }
    

    注意: 若本局得分大于历史最高得分,需要更新最高分到文件。

    13、从文件读取最高分

    首先需要使用fopen函数打开“贪吃蛇最高得分记录.txt”文件,若是第一次运行该代码,则会自动创建该文件,并将历史最高记录设置为0,之后再读取文件当中的历史最高记录存储在max变量当中,并关闭文件即可。

     

    14、更新最高分到文件

    首先使用fopen函数打开“贪吃蛇最高得分记录.txt”,然后将本局游戏的分数grade写入文件当中即可(覆盖式)。

    15、主函数

    有了以上函数的支撑,写出主函数是相当简单的,但需要注意以下三点:

    全局变量grade需要在主函数内初始化为0,不能在全局范围初始化为0,因为当玩家按下R键进行重玩时我们需要将当前分数grade重新设置为0。

    随机数的生成起点建议设置在主函数当中。

    主函数当中的#pragma语句是用于消除类似以下警告的:

     

    六、穿墙版贪吃蛇C语言代码

    1、游戏效果展示

    个人认为穿墙版的贪吃蛇比普通版贪吃蛇更好玩,你觉得呢?

    2、贪吃蛇C语言游戏代码

    以下代码可以直接运行,欢迎试玩:

    #include <stdio.h>
    #include <Windows.h>
    #include <stdlib.h>
    #include <time.h>
    #include <conio.h>
    
    #define ROW 23 //界面行数
    #define COL 42 //界面列数
    
    #define KONG 0 //标记空(什么也没有)
    #define FOOD 1 //标记食物
    #define HEAD 2 //标记蛇头
    #define BODY 3 //标记蛇身
    
    #define UP 72 //方向键:上
    #define DOWN 80 //方向键:下
    #define LEFT 75 //方向键:左
    #define RIGHT 77 //方向键:右
    #define SPACE 32 //暂停
    #define ESC 27 //退出
    
    //蛇头
    struct Snake
    {
    	int len; //记录蛇身长度
    	int x; //蛇头横坐标
    	int y; //蛇头纵坐标
    }snake;
    
    //蛇身
    struct Body
    {
    	int x; //蛇身横坐标
    	int y; //蛇身纵坐标
    }body[ROW*COL]; //开辟足以存储蛇身的结构体数组
    
    int face[ROW][COL]; //标记界面当中各个位置的信息
    
    //隐藏光标
    void HideCursor();
    //光标跳转
    void CursorJump(int x, int y);
    //初始化界面
    void InitInterface();
    //颜色设置
    void color(int c);
    //从文件读取最高分
    void ReadGrade();
    //更新最高分到文件
    void WriteGrade();
    //初始化蛇
    void InitSnake();
    //随机生成食物
    void RandFood();
    //判断得分与结束
    void JudgeFunc(int x, int y);
    //打印蛇/覆盖蛇
    void DrawSnake(int flag);
    //移动蛇
    void MoveSnake(int x, int y);
    //执行按键
    void run(int x, int y);
    //游戏主体逻辑函数
    void Game();
    
    int max, grade; //全局变量
    int main()
    {
    #pragma warning (disable:4996) //消除警告
    	max = 0, grade = 0; //初始化变量
    	system("title 贪吃蛇"); //设置cmd窗口名称
    	system("mode con cols=84 lines=23"); //设置cmd窗口大小
    	HideCursor(); //隐藏光标
    	ReadGrade(); //从文件读取最高分
    	InitInterface(); //初始化界面
    	InitSnake(); //初始化蛇
    	srand((unsigned int)time(NULL)); //设置随机数生成起点
    	RandFood(); //随机生成食物
    	DrawSnake(1); //打印蛇
    	Game(); //开始游戏
    	return 0;
    }
    
    //隐藏光标
    void HideCursor()
    {
    	CONSOLE_CURSOR_INFO curInfo; //定义光标信息的结构体变量
    	curInfo.dwSize = 1; //如果没赋值的话,光标隐藏无效
    	curInfo.bVisible = FALSE; //将光标设置为不可见
    	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    	SetConsoleCursorInfo(handle, &curInfo); //设置光标信息
    }
    //光标跳转
    void CursorJump(int x, int y)
    {
    	COORD pos; //定义光标位置的结构体变量
    	pos.X = x; //横坐标
    	pos.Y = y; //纵坐标
    	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //获取控制台句柄
    	SetConsoleCursorPosition(handle, pos); //设置光标位置
    }
    //初始化界面
    void InitInterface()
    {
    	color(7); //颜色设置为白色
    	CursorJump(0, 0);
    	printf("当前得分:%d", grade);
    	CursorJump(COL, 0);
    	printf("历史最高得分:%d", max);
    	color(11); //颜色设置为浅蓝色
    	for (int i = 1; i < ROW; i++)
    	{
    		for (int j = 0; j < COL; j++)
    		{
    			if (i == 1 && j != 0 && j != COL - 1) //打印游戏区的上界
    			{
    				CursorJump(2 * j, i);
    				printf("__");
    			}
    			else if (i == ROW - 1 && j != 0 && j != COL - 1) //打印游戏区的下界
    			{
    				CursorJump(2 * j, i);
    				printf("▔▔");
    			}
    			else if (j == 0 && i != 1 && i != 0 && i != ROW - 1) //打印游戏区的左界
    			{
    				CursorJump(2 * j, i);
    				printf(" >");
    			}
    			else if (j == COL - 1 && i != 1 && i != 0 && i != ROW - 1) //打印游戏区的右界
    			{
    				CursorJump(2 * j, i);
    				printf("< ");
    			}
    			else
    			{
    				face[i][j] = KONG; //其余位置标记为空(非常必要)
    			}
    		}
    	}
    }
    //颜色设置
    void color(int c)
    {
    	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //颜色设置
    }
    //从文件读取最高分
    void ReadGrade()
    {
    	FILE* pf = fopen("贪吃蛇最高得分记录.txt", "r"); //以只读的方式打开文件
    	if (pf == NULL) //打开文件失败
    	{
    		pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
    		fwrite(&max, sizeof(int), 1, pf); //将max写入文件(此时max为0),即将最高得分初始化为0
    	}
    	fseek(pf, 0, SEEK_SET); //使文件指针pf指向文件开头
    	fread(&max, sizeof(int), 1, pf); //读取文件当中的最高得分到max当中
    	fclose(pf); //关闭文件
    	pf = NULL; //文件指针及时置空
    }
    //更新最高分到文件
    void WriteGrade()
    {
    	FILE* pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件
    	if (pf == NULL) //打开文件失败
    	{
    		printf("保存最高得分记录失败\n");
    		exit(0);
    	}
    	fwrite(&grade, sizeof(int), 1, pf); //将本局游戏得分写入文件当中
    	fclose(pf); //关闭文件
    	pf = NULL; //文件指针及时置空
    }
    //初始化蛇
    void InitSnake()
    {
    	snake.len = 2; //蛇身长度初始化为2
    	snake.x = COL / 2; //蛇头位置的横坐标
    	snake.y = ROW / 2; //蛇头位置的纵坐标
    	//蛇身坐标的初始化
    	body[0].x = COL / 2 - 1;
    	body[0].y = ROW / 2;
    	body[1].x = COL / 2 - 2;
    	body[1].y = ROW / 2;
    	//将蛇头和蛇身位置进行标记
    	face[snake.y][snake.x] = HEAD;
    	face[body[0].y][body[0].x] = BODY;
    	face[body[1].y][body[1].x] = BODY;
    }
    //随机生成食物
    void RandFood()
    {
    	int i, j;
    	do
    	{
    		//随机生成食物的横纵坐标
    		i = rand() % ROW;
    		j = rand() % COL;
    		//若食物生成位置不在游戏区,或者生成食物的位置不为空,则重新生成
    	} while (i <= 1 || i == ROW - 1 || j == 0 || j == COL - 1 || face[i][j] != KONG); 
    	face[i][j] = FOOD; //将食物位置进行标记
    	color(9); //颜色设置为深蓝色
    	CursorJump(2 * j, i);
    	printf("●");
    }
    //判断得分与结束
    void JudgeFunc(int x, int y)
    {
    	int nextX = snake.x + x;
    	int nextY = snake.y + y;
    
    	if (nextX == COL - 1)
    		nextX = 1;
    	if (nextX == 0)
    		nextX = COL - 2;
    
    	if (nextY == ROW - 1)
    		nextY = 2;
    	if (nextY == 1)
    		nextY = ROW - 2;
    	//若即将到达的位置是食物,则得分
    	if (face[nextY][nextX] == FOOD)
    	{
    		snake.len++; //蛇身加长
    		grade += 10; //更新当前得分
    		color(7); //颜色设置为白色
    		CursorJump(0, 0);
    		printf("当前得分:%d", grade); //重新打印当前得分
    		RandFood(); //重新随机生成食物
    	}
    	//若即将到达的位置是蛇身,则游戏结束
    	else if (face[nextY][nextX] == BODY)
    	{
    		Sleep(1000); //留给玩家反应时间
    		system("cls"); //清空屏幕
    		color(7); //颜色设置为白色
    		CursorJump(2 * (COL / 3), ROW / 2 - 3);
    		if (grade > max)
    		{
    			printf("恭喜你打破最高记录,最高记录更新为%d", grade);
    			WriteGrade();
    		}
    		else if (grade == max)
    		{
    			printf("与最高记录持平,加油再创佳绩", grade);
    		}
    		else
    		{
    			printf("请继续加油,当前与最高记录相差%d", max - grade);
    		}
    		CursorJump(2 * (COL / 3), ROW / 2);
    		printf("GAME OVER");
    		while (1) //询问玩家是否再来一局
    		{
    			char ch;
    			CursorJump(2 * (COL / 3), ROW / 2 + 3);
    			printf("再来一局?(y/n):");
    			scanf("%c", &ch);
    			if (ch == 'y' || ch == 'Y')
    			{
    				system("cls");
    				main();
    			}
    			else if (ch == 'n' || ch == 'N')
    			{
    				CursorJump(2 * (COL / 3), ROW / 2 + 5);
    				exit(0);
    			}
    			else
    			{
    				CursorJump(2 * (COL / 3), ROW / 2 + 4);
    				printf("选择错误,请再次选择");
    			}
    		}
    	}
    }
    //打印蛇与覆盖蛇
    void DrawSnake(int flag)
    {
    	if (flag == 1) //打印蛇
    	{
    		color(10); //颜色设置为绿色
    		CursorJump(2 * snake.x, snake.y);
    		printf("■"); //打印蛇头
    		//打印蛇身
    		for (int i = 0; i < snake.len; i++)
    		{
    			CursorJump(2 * body[i].x, body[i].y);
    			printf("■");
    		}
    	}
    	else //覆盖蛇
    	{
    		if (body[snake.len - 1].x != 0) //防止len++后(0, 0)位置所显示的信息被覆盖
    		{
    			//将蛇尾覆盖为空格即可
    			CursorJump(2 * body[snake.len - 1].x, body[snake.len - 1].y);
    			printf("  ");
    		}
    	}
    }
    //移动蛇
    void MoveSnake(int x, int y)
    {
    	DrawSnake(0); //先覆盖当前所显示的蛇
    	face[body[snake.len - 1].y][body[snake.len - 1].x] = KONG; //蛇移动后蛇尾重新标记为空
    	face[snake.y][snake.x] = BODY; //蛇移动后蛇头的位置变为蛇身
    	//蛇移动后各个蛇身位置坐标需要更新
    	for (int i = snake.len - 1; i > 0; i--)
    	{
    		body[i].x = body[i - 1].x;
    		body[i].y = body[i - 1].y;
    	}
    	//蛇移动后蛇头位置信息变为第0个蛇身的位置信息
    	body[0].x = snake.x;
    	body[0].y = snake.y;
    	//蛇头的位置更改
    	snake.x = snake.x + x;
    	if (snake.x == COL - 1) //越过右界
    		snake.x = 1;
    	else if (snake.x == 0) //越过左界
    		snake.x = COL - 2;
    	snake.y = snake.y + y;
    	if (snake.y == ROW - 1) //越过下界
    		snake.y = 2;
    	else if (snake.y == 1) //越过上界
    		snake.y = ROW - 2;
    	face[snake.y][snake.x] = HEAD; //对蛇头位置进行标记
    	DrawSnake(1); //打印移动后的蛇
    }
    //执行按键
    void run(int x, int y)
    {
    	int t = 0;
    	while (1)
    	{
    		if (t == 0)
    			t = 3000; //这里t越小,蛇移动速度越快(可以根据次设置游戏难度)
    		while (--t)
    		{
    			if (kbhit() != 0) //若键盘被敲击,则退出循环
    				break;
    		}
    		if (t == 0) //键盘未被敲击
    		{
    			JudgeFunc(x, y); //判断到达该位置后,是否得分与游戏结束
    			MoveSnake(x, y); //移动蛇
    		}
    		else //键盘被敲击
    		{
    			break; //返回Game函数读取键值
    		}
    	}
    }
    //游戏主体逻辑函数
    void Game()
    {
    	int n = RIGHT; //开始游戏时,默认向后移动
    	int tmp = 0; //记录蛇的移动方向
    	goto first; //第一次进入循环先向默认方向前进
    	while (1)
    	{
    		n = getch(); //读取键值
    		//在执行前,需要对所读取的按键进行调整
    		switch (n)
    		{
    		case UP:
    		case DOWN: //如果敲击的是“上”或“下”
    			if (tmp != LEFT&&tmp != RIGHT) //并且上一次蛇的移动方向不是“左”或“右”
    			{
    				n = tmp; //那么下一次蛇的移动方向设置为上一次蛇的移动方向
    			}
    			break;
    		case LEFT:
    		case RIGHT: //如果敲击的是“左”或“右”
    			if (tmp != UP&&tmp != DOWN) //并且上一次蛇的移动方向不是“上”或“下”
    			{
    				n = tmp; //那么下一次蛇的移动方向设置为上一次蛇的移动方向
    			}
    		case SPACE:
    		case ESC:
    		case 'r':
    		case 'R':
    			break; //这四个无需调整
    		default:
    			n = tmp; //其他键无效,默认为上一次蛇移动的方向
    			break;
    		}
    	first: //第一次进入循环先向默认方向前进
    		switch (n)
    		{
    		case UP: //方向键:上
    			if (snake.y - 1 != body[0].y) //改变的方向不能是第0个蛇身的方向
    			{
    				run(0, -1); //向上移动(横坐标偏移为0,纵坐标偏移为-1)
    				tmp = UP; //记录当前蛇的移动方向
    			}
    			break;
    		case DOWN: //方向键:下
    			if (snake.y + 1 != body[0].y) //改变的方向不能是第0个蛇身的方向
    			{
    				run(0, 1); //向下移动(横坐标偏移为0,纵坐标偏移为1)
    				tmp = DOWN; //记录当前蛇的移动方向
    			}
    			break;
    		case LEFT: //方向键:左
    			if (snake.x - 1 != body[0].x) //改变的方向不能是第0个蛇身的方向
    			{
    				run(-1, 0); //向左移动(横坐标偏移为-1,纵坐标偏移为0)
    				tmp = LEFT; //记录当前蛇的移动方向
    			}
    			break;
    		case RIGHT: //方向键:右
    			if (snake.x + 1 != body[0].x) //改变的方向不能是第0个蛇身的方向
    			{
    				run(1, 0); //向右移动(横坐标偏移为1,纵坐标偏移为0)
    				tmp = RIGHT; //记录当前蛇的移动方向
    			}
    			break;
    		case SPACE: //暂停
    			system("pause>nul"); //暂停后按任意键继续
    			break;
    		case ESC: //退出
    			system("cls"); //清空屏幕
    			color(7); //颜色设置为白色
    			CursorJump(COL - 8, ROW / 2);
    			printf("  游戏结束  ");
    			CursorJump(COL - 8, ROW / 2 + 2);
    			exit(0);
    		case 'r':
    		case 'R': //重新开始
    			system("cls"); //清空屏幕
    			main(); //重新执行主函数
    		}
    	}
    }
    

    3、游戏代码详解

    跟前面的大同小异这里就不细说了,感兴趣的对照看一下就明白了。

    七、大量C语言项目游戏源代码获 取

    可 以 关 注 微 信 公 众 号:“ C和C加加 ” 回复:“TC”即可

    展开全文
  • C语言贪吃蛇,简单版本。
  • C语言贪吃蛇实验报告
  • C语言贪吃蛇.pdf

    2020-08-21 02:01:39
    想学习如何用c语言实现贪吃蛇 需要一点c语言基础和vs的基本操作 内容为从创建文件到贪吃蛇实现的全过程及截图 其中用到了windows下的函数 需要调用windows.h 建议细看之前现浏览一下全文的的内容
  • C语言贪吃蛇.zip

    2020-02-24 10:14:39
    大一期末工程实践作品,实现了基础的游戏玩法,用户注册,分数排行等功能,界面简单,附上答辩ppt。供大家参考学习改进
  • C语言编写贪吃蛇源代码,简单易懂,文件为VC源代码
  • C贪吃蛇

    2021-03-15 15:59:06
    摘要:VC/C++源码,游戏编程,贪吃蛇 C贪吃蛇源码,部分代码及注释如下:  int i,key;  int score=0;/*得分*/  int gamespeed=50000;/*游戏速度自己调整*/  struct Food  {  int x;/*食物的横坐标*/  ...
  • C语言--贪吃蛇相关PPT
  • C语言贪吃蛇C语言贪吃蛇
  • C语言 贪吃蛇

    万次阅读 多人点赞 2018-09-16 14:55:01
    C语言 贪吃蛇 一、简述 记--用C语言简单实现贪吃蛇小游戏。 二、效果 使用上下左右方向键控制方向,按ESC退出游戏。 三、代码结构 四、源代码 #include <stdio.h> //标准输入输出函数库 #...

    C语言 贪吃蛇

    一、简述

           记--用C语言简单实现贪吃蛇小游戏。

    二、效果

          使用上下左右方向键控制方向, 按ESC退出游戏。

           

           

    三、代码结构

           

    四、源代码

    #include <stdio.h>  //标准输入输出函数库 
    #include <stdlib.h> //包含system函数 
    #include <windows.h>//包含Sleep函数,来控制速度
    #include <time.h>   //设置食物时随机生成坐标用到time做种子
     
    #define DOWN_WALL 20	 //下边框  (下面的墙)   //使用宏定义 ,是方便以后调整边框大小 
    #define RIGHT_WALL 58 //右边框 (右面的墙)
     
    //加上typedef 以后声明此类型的结构体不需要struct关键字,可以用这样声明 Snake s1;(原来:struct s_snake s1)
    typedef struct s_snake //用来存储每一段蛇身的坐标位置 
    {
    	int x; //x坐标 
    	int y; //y坐标 
    	struct s_snake *next; //下一段蛇身 
    }Snake;
     
    /*函数声明*/
    void SetPos(int x,int y);//移动光标函数
    int IsHitWall();//判断撞墙函数
    int IsBiteYouself();//判断咬到自己的函数
    void DrawFrame();//画边框函数
    void InitSnake();//初始化蛇函数
    void CreateFood();//创建食物函数
    void PlayGame();//游戏移动循环函数
    int Move();//移动函数,方向控制 
    void Welcome();//欢迎界面
    void free_snake(Snake *head);//释放资源 
     
    Snake *head,*end;//蛇头、蛇尾
    Snake *p;//辅助指针
    int speed=310;//休眠时间,用来控制移动速度 
    int level = 0,score = 0;//分数
    int foodx,foody;//食物的(x,y)坐标
    char key;//方向,暂停/继续 控制状态 
     
    int main()
    {
        Welcome(); //欢迎界面 
    	DrawFrame();//画边框 
    	InitSnake();//初始化蛇身 
    	CreateFood();//创建食物 
    	
    	//右侧提示信息 
    	SetPos(60,7);
    	printf("得分:%d",score);
    	SetPos(60,8);
    	printf("当前速度:%d毫秒",speed);
    	SetPos(60,9);
    	printf("每+30分速度变快");
    	SetPos(60,10);
    	printf("不能撞墙/咬到自己");
    	SetPos(60,11);
    	printf("按空格暂停/继续");
    	
    	PlayGame();//按方向键控制蛇身进行游戏 
    	
    	free_snake(head);
        return 0;
    }
     
    void SetPos(int x,int y)//设置光标位置(就是输出显示的开始位置)
    {
    	/*  COORD是Windows API中定义的一种结构体 
    	 *	typedef struct _COORD 
    	 *	{
    	 *		SHORT X; 
    	 *		SHORT Y;
    	 *	} COORD; 
    	 *
    	 */
    	COORD pos = {x,y};
    	HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);//获得 标准输出的句柄
        SetConsoleCursorPosition(output,pos); //设置控制台光标位置 
    }
     
    int IsHitWall()//判断是否撞墙 
    {
    	if (head->x==0||head->x==RIGHT_WALL||head->y==0||head->y==DOWN_WALL)
    	{  //因为蛇头最先动,并且蛇身后一段下一步会在前一段,所以只要蛇头不撞墙,那么整个蛇身就不会 撞墙 
    		SetPos(DOWN_WALL,14);
    		printf("游戏结束!撞到墙了\n");
    		SetPos(DOWN_WALL,15);//令 ‘按任意键继续...’居中显示 
    		//system("pause");//暂停
    		return 1;
    	}
    	return 0;
    }
     
    int IsBiteYouself()//判断是否咬到自己 
    {
    	while(p->next!=NULL)
    	{
    		p=p->next;
    		if (head->x==p->x&&head->y==p->y)//判断蛇头是否与其他蛇身重合 
    		{
    			SetPos(DOWN_WALL,14);
    		    printf("游戏结束!你咬到自己了\n");
    		    SetPos(DOWN_WALL,15);//令 “请按任意键继续”居中显示 
    			//system("pause");//暂停 
    		    return 1;
    		}
    	}
    	return 0;
    }
     
    void DrawFrame()//画边框 
    {
    	int i = 0;
    	for(i=0;i<60;i+=2)//打印上下边框 注意i 一段蛇身占用 x 2个单位, y 1个单位 
        {
            SetPos(i,0);   //上边框 
            printf("■");
            SetPos(i,DOWN_WALL);//下边框 
            printf("■");
        }
        for(i=1;i<DOWN_WALL;i++)//打印左右边框
        {
            SetPos(0,i); //左边框 
            printf("■"); 
            SetPos(RIGHT_WALL,i); //右边框 
            printf("■"); 
        }
    }
     
    void InitSnake()//初始化蛇身  头插法	初始化从(20,15)开始的四段蛇身 (横向排列) 
    {
    	int i = 0;
    	
    	//创建一个蛇身位置 蛇尾 
    	end=(Snake*)malloc(sizeof(Snake));
    	end->x=20;
    	end->y=15;
    	end->next=NULL;
    	
    	//创建三个蛇身位置 
    	for (i=1;i<=3;i++)
    	{
    		head = (Snake*)malloc(sizeof(Snake));
    		head->x = 20+2*i; //每个蛇身 x相差 2个单位 
    		head->y = 15;
    		
    		head->next=end;  //头插法 
    		end = head;
    	}
    	
    	//从蛇头开始画贪吃蛇 
    	while (end->next!=NULL)
    	{
    		SetPos(end->x,end->y);
    		printf("■");
    		end = end->next;
    	}    
    }
     
    void CreateFood()//设置食物 
    {
    	srand(time(0));//设置随机数种子 
    	flag:
    	while(1)//由于food的x坐标必须为偶数,所以设置循环判断是否为偶数
    	{
    		//rand()%num产生 0~num-1
    		//rand产生范围数公式rand()%(m+1-n)+n;有效范围在 [n,m]
    		foody=rand()%(DOWN_WALL-1+1-1)+1;//foody的有效范围在 [1,DOWN_WALL-1 ]
    		foodx=rand()%(RIGHT_WALL-2+1-3)+3;//foodx的有效范围在    [3,RIGHT_WALL-2] 注意x是以2为单位的 
    		if (foodx%2==0)
    	    {
    		    break;
    	    }
    	}
    	p=head;
    	while(1) 
    	{
    		if(p->x==foodx&&p->y==foody)//若生成坐标和蛇重叠了,回到生成坐标循环
    		{
    			goto flag;
    		}
     
    		if(p->next==NULL) //与每一段蛇身比较完毕,跳出循环 
    		{
    			break;
    		}
    		p=p->next;
    	}
    	
    	SetPos(foodx,foody);
    	printf("■");  //显示食物 
    }
     
    void PlayGame()//贪吃蛇移动,暂停
    {
    	int mv_ret = 0;//移动后的返回值,如果撞墙、或就咬到自己设置为1 
    	key = 'd';//刚开始,贪吃蛇默认向右移动 
    	while (1)
    	{	
    		//GetAsyncKeyState(VK_UP) 判断VK_UP按键的状态,若是被按下,则位15设为1;如抬起,则为0 
    		//所以要 与上0x8000 取出第15位 进行判断  
    		if ((GetAsyncKeyState(VK_UP)&& 0x8000)&& key != 's')//与key!='s',因为不能后退 
    		{
    			key='w';//如果本来不是向下的,按下向上键,将key设置为w 
    		}
    		else if ((GetAsyncKeyState(VK_DOWN)&& 0x8000)&& key != 'w')
    		{
    			key='s';
    		}
    		else if ((GetAsyncKeyState(VK_RIGHT) && 0x8000)&& key != 'a')
    		{
    			key='d';
    		}
    		else if ((GetAsyncKeyState(VK_LEFT)&& 0x8000) && key != 'd')
    		{
    			key='a';
    		}
    		else if (GetAsyncKeyState(VK_SPACE)&& 0x8000) //暂停/继续函数 
    		{
    			//补上消隐的蛇尾(蛇尾还在)  原因未知   
    			while(p->next!=NULL) p=p->next;
    			SetPos(p->x,p->y);
    			printf("■");
    			
    			while(1)//暂停语句
    			{
    				Sleep(100); //必要延时(消抖) Sleep(毫秒)
    				if (GetAsyncKeyState(VK_SPACE)&& 0x8000)
    				{
    					break;
    				}
    			}
    			
    			//擦掉补上的 蛇尾 
    			SetPos(p->x,p->y);
    			printf(" ");
    		}
    		else if(GetAsyncKeyState(VK_ESCAPE)&& 0x8000)//按下ESC退出游戏,VK_ESCAPE == 27 
    		{
    			return ; 
    		}
    		 
    		
    		//实时刷新速度  得分每+30分 移动速度变快
    		if (score==level && speed > 10)//判断得分
    		{
    			speed -=10; //睡眠时间,改变移动速度,越少越快 
    			level +=30; //速度变快条件 变化 
    			
    			SetPos(60,8);
    			printf("当前速度:%d毫秒",speed);
    		}
    		mv_ret = Move();//移动蛇身 
    		if( mv_ret == 1)
    		{
    			break;
    		} 
    	}
    }
     
    int Move()//移动函数,w前 s后 a左 d右,实现移动:头部增加一个,尾部减掉一个 
    {
    	int ret;
    	
    	//不是按下控制方向的 a,s,d,w 就 
    	if( (key != 'a') && (key != 's') && (key != 'd') && (key != 'w') ) 
    	{
    		return 0;
    	}
    	
    	ret = IsHitWall(); //是否撞墙 
    	ret += IsBiteYouself(); //是否咬到自己 
    	if(ret == 1)
    	{
    		return 1;
    	}
    	
    	p = (Snake*)malloc(sizeof(Snake));//头部增加的那个 
    	p->next=head;//添加到头部 
    	
    	switch(key)
    	{
    		case 'd'://向右 
    		    p->x = head->x+2;//右边 
    		    p->y = head->y;
    	        break;
    	
    		case 'w'://向上 
    			p->x=head->x;
    			p->y=head->y-1;//向上 
    			break;
    			
    		case 's'://向下 
    			p->x=head->x;
    			p->y=head->y+1;//向下 
    			break;
    			
    		case 'a'://向左 
    			p->x=head->x-2;//向左 
    			p->y=head->y;
    			break; 
    			
    	}
    	
    	//画出新的头部 
    	SetPos(p->x,p->y);
        printf("■");
        
        head = p;//在贪吃蛇的头部添加一个称为新的头 ,相当于是贪吃蛇移动一格 
        		//如果 移动的一格刚好是食物的位置,新增的称为蛇头,不用去掉蛇尾
    			//如果 移动的一格不是食物的位置,新增的称为蛇头,去掉蛇尾,就是贪吃蛇移动一格的效果 
        
        Sleep(speed);//移动速度的控制 
    	if (p->x==foodx && p->y==foody)//移动的一格刚好是食物的位置 
    	{
    		CreateFood();
    		score +=10;
    		SetPos(60,7);
    		printf("得分:%d",score);
    		
    	}
    	else   //吃不到食物,头部添加一个,尾部去掉一个 
    	{
    		//移动的一格刚好是食物的位置,新增的称为蛇头,不用去掉蛇尾 
    		while (p->next->next != NULL) p = p->next;//指向蛇尾前一格,然后释放蛇尾,并将原来的尾二置空。
    
    		SetPos(p->x, p->y);//为什么不是setPos(p->next->x,p->next->y)? 
    		printf(" ");//擦掉蛇尾(蛇头加一,蛇尾减一,实现移动效果) 
    
    		free(p->next);//释放蛇尾
    		p->next = NULL;//必须置空,不然原来的尾二还是指向原来的尾巴(但是原来的为尾巴已经释放了)
    		p = head;//将p指向head 
    	}
    	
    	return 0;
    }
     
    void Welcome()//欢迎界面 
    {
    	SetPos(25,8);
    	printf("【贪吃蛇】   作者:Genven_Liang");
    	SetPos(25,11);
    	printf("【游戏规则】");
    	SetPos(25,12);
    	printf("1、不能撞墙、咬到自己");
    	SetPos(25,13);
    	printf("2、按空格暂停/继续游戏");
    	
    	printf("\n");
    	SetPos(30,15);
    	system("pause");//暂停 
    	system("cls");//清屏 
    }
     
    void free_snake(Snake *head)//释放资源,释放链表空间 
    {
    	if(head == NULL || head->next == NULL)
    	{
    		return ;
    	}
     
        //从头部开始逐个节点释放
    	while( (p=head) != NULL)
    	{
    		head = head->next;
    		free(p);						
    	}	
    }
     

    五、关于看不见“游戏结束”

               例子使用的是C-Free,这个IDE在程序结束后会暂停的;如果使用的是Visual Studio,程序结束后不会暂停;需要在IsHitWall()函数和IsBiteYouself()函数里面加上一句system(pause);暂停一下(或者是加上一句getchar()),这样就能看见"游戏结束"了。

    六、问题记录

       6.1 残留问题

             目前在Win10-64bit家庭中文版 发现残留问题,现象如下:       

             ps:在Win7-32bit 系统,Win7-64bit系统,Win10专业版未发现该问题。

             产生原因:空格的宽度与■的宽度不一致,导致用空格不能完全擦除一段完整的蛇身--■

             解决办法:使用两个空格来擦除一段蛇身         

     

    ===========================以下回复 qq_45936030 这位老铁===================

    使用Dev-C++ IDE 

    使用VC6.0 IDE     (需要暂停一下才能看到最后的"游戏结束")

     

    ====================================以下回复  钢钢钢不爽 这位老铁 ======================

    在字符映射表charmap中可以搜索 实心 就可以找到实心方形--就是黑色的那个正方形

    可以使用快捷键Win键+R唤出运行窗口  (Win键就是这个按键

    ps:还可以使用系统自带的造字程序进行自定义,搜索:专用字符编辑程序 或在运行窗口直接输入 eudcedit.exe 然后回车。

     

    ======================以下回复  xmx666 这位老铁 ===============

    1 p->next->next是对的,p->next是不对的。以下是p->next->next和p->next的对比:

    原因:在没有吃到食物情况,我们需要在前面增加一个方块,并将最后的方块A去掉,以实现移动效果。

             去掉最后一个方块有2个操作:1)将最后的方块A释放内存,擦除方块A;2)断开联系,方块A的前面的方块B不要再指向方块A。

             (如果不断开的话,B还是指向A,但是A已经被释放了,程序已经没有合法权限去的操作A的内存空间了。)

             其中while (p->next->next != NULL) p = p->next;是找到倒数第二个方块,

             释放方块A的空间不管是找到A还是A的前一个都是可以的,但是单项链表不能操作A的前一个。

             将A的前面一个的next置空,如果是使用p->next找到A并释放A,那么是不能直接操作A的前面一个的(但是可以增加一个变量用来指向A的前面一个)

    展开全文
  • C语言贪吃蛇完整代码

    万次阅读 多人点赞 2019-09-07 16:47:21
    C语言贪吃蛇完整代码 #include #include #include //windows编程头文件 #include #include //控制台输入输出头文件 #ifndef __cplusplus typedef char bool; #define false 0 #define true 1 #endif //将光标移动到...

    C语言贪吃蛇完整代码

    #include <stdio.h>
    #include <stdlib.h>
    #include <Windows.h>//windows编程头文件
    #include <time.h>
    #include <conio.h>//控制台输入输出头文件
    
    #ifndef __cplusplus
     
    typedef char bool;
    #define false 0
    #define true  1
     
    #endif
    
    //将光标移动到控制台的(x,y)坐标点处
    void gotoxy(int x, int y)
    {
    	COORD coord;
    	coord.X = x;
    	coord.Y = y;
    	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
    }
     
    
    
    #define SNAKESIZE 100//蛇的身体最大节数
    #define MAPWIDTH 78//宽度
    #define MAPHEIGHT 24//高度
    
    //食物的坐标
    struct {
    	int x;
    	int y;
    }food;
     
    //蛇的相关属性
    struct {
    	int speed;//蛇移动的速度
    	int len;//蛇的长度
    	int x[SNAKESIZE];//组成蛇身的每一个小方块中x的坐标
    	int y[SNAKESIZE];//组成蛇身的每一个小方块中y的坐标
     
    }snake;
    
    //绘制游戏边框
    void drawMap();
    //随机生成食物
    void createFood();
    //按键操作
    void keyDown();
    //蛇的状态
    bool snakeStatus();
    //从控制台移动光标
    void gotoxy(int x, int y);
    
    int key = 72;//表示蛇移动的方向,72为按下“↑”所代表的数字
     
    //用来判断蛇是否吃掉了食物,这一步很重要,涉及到是否会有蛇身移动的效果以及蛇身增长的效果
    int changeFlag = 0;
     
    int sorce = 0;//记录玩家的得分
    
    int i;
    void drawMap()
    {
    	//打印上下边框
    	for (i = 0; i <= MAPWIDTH; i += 2)//i+=2是因为横向占用的是两个位置
    	{
    		//将光标移动依次到(i,0)处打印上边框
    		gotoxy(i, 0);
    		printf("■");
    		//将光标移动依次到(i,MAPHEIGHT)处打印下边框
    		gotoxy(i, MAPHEIGHT);
    		printf("■");
    	}
     
    	//打印左右边框
    	for (i = 1; i < MAPHEIGHT; i++)
    	{
    		//将光标移动依次到(0,i)处打印左边框
    		gotoxy(0, i);
    		printf("■");
    		//将光标移动依次到(MAPWIDTH, i)处打印左边框
    		gotoxy(MAPWIDTH, i);
    		printf("■");
    	}
     
    	//随机生成初试食物
    	while (1)
    	{
    		srand((unsigned int)time(NULL));
    		food.x = rand() % (MAPWIDTH - 4) + 2;
    		food.y = rand() % (MAPHEIGHT - 2) + 1;
    		//生成的食物横坐标的奇偶必须和初试时蛇头所在坐标的奇偶一致,因为一个字符占两个字节位置,若不一致
    		//会导致吃食物的时候只吃到一半
    		if (food.x % 2 == 0)
    			break;
    	}
    	//将光标移到食物的坐标处打印食物
    	gotoxy(food.x, food.y);
    	printf("*");
     
    	//初始化蛇的属性
    	snake.len = 3;
    	snake.speed = 200;
     
    	//在屏幕中间生成蛇头
    	snake.x[0] = MAPWIDTH / 2 + 1;//x坐标为偶数
    	snake.y[0] = MAPHEIGHT / 2;
    	//打印蛇头
    	gotoxy(snake.x[0], snake.y[0]);
    	printf("■");
     
    	//生成初试的蛇身
    	for (i = 1; i < snake.len; i++)
    	{
    		//蛇身的打印,纵坐标不变,横坐标为上一节蛇身的坐标值+2
    		snake.x[i] = snake.x[i - 1] + 2;
    		snake.y[i] = snake.y[i - 1];
    		gotoxy(snake.x[i], snake.y[i]);
    		printf("■");
    	}
    	//打印完蛇身后将光标移到屏幕最上方,避免光标在蛇身处一直闪烁
    	gotoxy(MAPWIDTH - 2, 0);
    	return;
    }
    
    void keyDown()
    {
    	int pre_key = key;//记录前一个按键的方向
    	if (_kbhit())//如果用户按下了键盘中的某个键
    	{
    		fflush(stdin);//清空缓冲区的字符
     
    		//getch()读取方向键的时候,会返回两次,第一次调用返回0或者224,第二次调用返回的才是实际值
    		key = _getch();//第一次调用返回的不是实际值
    		key = _getch();//第二次调用返回实际值
    	}
     
    	/*
    	*蛇移动时候先擦去蛇尾的一节
    	*changeFlag为0表明此时没有吃到食物,因此每走一步就要擦除掉蛇尾,以此营造一个移动的效果
    	*为1表明吃到了食物,就不需要擦除蛇尾,以此营造一个蛇身增长的效果
    	*/
    	if (changeFlag == 0)
    	{
    		gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
    		printf("  ");//在蛇尾处输出空格即擦去蛇尾
    	}
     
    	//将蛇的每一节依次向前移动一节(蛇头除外)
    	for (i = snake.len - 1; i > 0; i--)
    	{
    		snake.x[i] = snake.x[i - 1];
    		snake.y[i] = snake.y[i - 1];
    	}
     
    	//蛇当前移动的方向不能和前一次的方向相反,比如蛇往左走的时候不能直接按右键往右走
    	//如果当前移动方向和前一次方向相反的话,把当前移动的方向改为前一次的方向
    	if (pre_key == 72 && key == 80)
    		key = 72;
    	if (pre_key == 80 && key == 72)
    		key = 80;
    	if (pre_key == 75 && key == 77)
    		key = 75;
    	if (pre_key == 77 && key == 75)
    		key = 77;
     
    	/**
    	*控制台按键所代表的数字
    	*“↑”:72
    	*“↓”:80
    	*“←”:75
    	*“→”:77
    	*/
     
    	//判断蛇头应该往哪个方向移动
    	switch (key)
    	{
    	case 75:
    		snake.x[0] -= 2;//往左
    		break;
    	case 77:
    		snake.x[0] += 2;//往右
    		break;
    	case 72:
    		snake.y[0]--;//往上
    		break;
    	case 80:
    		snake.y[0]++;//往下
    		break;
    	}
    	//打印出蛇头
    	gotoxy(snake.x[0], snake.y[0]);
    	printf("■");
    	gotoxy(MAPWIDTH - 2, 0);
    	//由于目前没有吃到食物,changFlag值为0
    	changeFlag = 0;
    	return;
    }
    
    void createFood()
    { 
    	if (snake.x[0] == food.x && snake.y[0] == food.y)//蛇头碰到食物
    	{
    		//蛇头碰到食物即为要吃掉这个食物了,因此需要再次生成一个食物
    		while (1)
    		{
    			int flag = 1;
    			srand((unsigned int)time(NULL));
    			food.x = rand() % (MAPWIDTH - 4) + 2;
    			food.y = rand() % (MAPHEIGHT - 2) + 1;
     
    			//随机生成的食物不能在蛇的身体上
    			for (i = 0; i < snake.len; i++)
    			{
    				if (snake.x[i] == food.x && snake.y[i] == food.y)
    				{
    					flag = 0;
    					break;
    				}
    			}
    			//随机生成的食物不能横坐标为奇数,也不能在蛇身,否则重新生成
    			if (flag && food.x % 2 == 0)
    				break;
    		}
     
    		//绘制食物
    		gotoxy(food.x, food.y);
    		printf("*");
     
    		snake.len++;//吃到食物,蛇身长度加1
    		sorce += 10;//每个食物得10分
    		snake.speed -= 5;//随着吃的食物越来越多,速度会越来越快
    		changeFlag = 1;//很重要,因为吃到了食物,就不用再擦除蛇尾的那一节,以此来造成蛇身体增长的效果
    	}
    	return;
    }
    
    bool snakeStatus()
    {
    	//蛇头碰到上下边界,游戏结束
    	if (snake.y[0] == 0 || snake.y[0] == MAPHEIGHT)
    		return false;
    	//蛇头碰到左右边界,游戏结束
    	if (snake.x[0] == 0 || snake.x[0] == MAPWIDTH)
    		return false;
    	//蛇头碰到蛇身,游戏结束
    	for (i = 1; i < snake.len; i++)
    	{
    		if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
    			return false;
    	}
    	return true;
    }
    
    int main()
    {
        drawMap();
    	while (1)
    	{
    		keyDown();
    		if (!snakeStatus())
    			break;
    		createFood();
    		Sleep(snake.speed);
    	}
     
    	gotoxy(MAPWIDTH / 2, MAPHEIGHT / 2);
    	printf("Game Over!\n");
    	gotoxy(MAPWIDTH / 2, MAPHEIGHT / 2 + 1);
    	printf("本次游戏得分为:%d\n", sorce);
    	Sleep(5000);
    	return 0;
    }
    
    
    展开全文
  • 用windows api 做的贪吃蛇 #include #include"resource.h" #include"Node.h" #include #include TCHAR szAppname[] = TEXT("Snack_eat"); #define SIDE (x_Client/80) #define x_Client 800 #define y_Client 800 #...
  • c语言贪吃蛇课程设计报告.pdf
  • C语言贪吃蛇 新手入门(超详细)

    万次阅读 多人点赞 2021-02-08 11:06:54
    贪吃蛇小程序,主要采用C语言描述,采用数组进行数据存储的图形化操作界面,会涉及一点点C++ 知识(特别少的一点点),但是有C语言基础就够用了,编译器:VS2015,会涉及部分库函数的安装及使用,我会在文章中给出...
  • 实用标准文案精彩文档C语言程序设计实训报告姓 名专 业班 级指导教师二011 年 7 月 14 日精彩文档目录TOC \o "1-3" \h \z HYPERLINK \l "_Toc298334041" 1实训目的和要求 PAGEREF _Toc298334041 \h 1HYPERLINK \l "_...
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼#include#include#include#include#include#includeusing namespace std;#define HEAD 'H'#define BODY 'X'#define WALL '*'#define money 'S'#define N 50#define n 20...
  • C语言贪吃蛇游戏

    2018-02-25 22:30:22
    自己用C语言写的贪吃蛇游戏,感兴趣的可以参考一下,不喜勿喷
  • c语言贪吃蛇原代码.c

    2020-03-25 18:37:15
    c语言贪吃蛇原代码 游戏流畅 ,两种游戏模式,代码简单,全文771行,部分功能阉割后代码可以更简洁,使用链表制作, 暂时没发现bug,可以用作c语言课程设计, 转载请标明出处谢谢支持
  • C语言贪吃蛇源代码

    2018-03-23 09:46:14
    C语言写的贪吃蛇小游戏,含源代码参考,欢迎大家使用
  • c语言贪吃蛇(简易版本含完整代码)

    万次阅读 多人点赞 2020-11-29 08:50:00
    这个贪吃蛇是在我学完C语言的基本部分 在跟着哈工大的c语言程序设计Mooc课程完了之后做的 因为学完C语言很迷茫 不晓得应该学什么 学校里面的题库感觉刷起来又没有实际我能看到的东西 我认为在阶段性的学习过程中应该...
  • c语言入门,C语言语法学习,c语言项目 详细的项目学习教程,并附带完整的项目代码和注释 学习完此项目,c语言能力能上升一大截, 建议下载学习
  • C语言贪吃蛇实验报告

    2021-05-18 11:21:20
    C语言贪吃蛇实验报告 C 语言程序设计实训报告姓 名 专 业 班 级 指导教师 二 011 年 7 月 14 日I I目录1 实训目的和要求 11.1 实训目的和任务 11.2 实训要求 12 实训任务内容 12.1 游戏规则 12.2 流程设计 23 软件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,592
精华内容 7,036
关键字:

c 贪吃蛇

友情链接: ZHIBIAO.zip