用C语言写一个简单的贪吃蛇游戏(用到easyx图形库)

2023-10-26

学习内容:1.游戏的存储与读写

                  2.制作游戏菜单

                  3.制作定时器

目录

一、需要用到的头文件、全局变量和一些函数

二、定时器

三、数据的初始化和绘制

四、蛇的运行和吃食物

五、游戏菜单界面

六、游戏存储与读写

七、其他函数

八、主函数入口


主菜单

 游戏内容

一、需要用到的头文件、全局变量和一些函数

#include<stdio.h>
#include<easyx.h>
#include<time.h>
#include<conio.h>
#pragma comment (lib,"winmm.lib")

#define WIDTH 600//屏幕宽度与高度
#define HEIGHT 500
#define MAX_SNAKE 30//最大蛇长度

//全局变量
int game_state = 1;//游戏状态:1.游戏菜单选项 2.运行游戏 3.退出游戏  
int option;//菜单栏状态

bool game_pause;
bool snake_die;
MOUSEMSG m1;
MOUSEMSG m2;

//定一个方向枚举
enum DIR
{
	up,
	down,
	left,
	right
};

//蛇结构体
struct Snake
{
	POINT coord[MAX_SNAKE];
	int num;
	int len;
	int exis;
	int score;
	int dir;
}snake;

//食物结构体
struct Food
{
	POINT fd;
	int exis;
}food;

//需要用到的函数
void InitData();//初始化数据
void DrawImag();//绘制图画
void ReadGame();//读取要保存的数据
void SaveGame();//保存数据
void EatFood();//吃食物
void GameOver();//游戏结束
void GameMenu();//游戏菜单
void UpdataWithInput();//有数据输入
void UpdataWithoutInput();//无数据输入
void SnakeMove();//蛇的移动
void KeyControl();//键盘输入

二、定时器

用static 定义 start避免循环时被覆盖

开始start与end处以同一时间,start保存的时间不变,end时间一直在变化,直至end和start时间差大于等于ms,当相等时,再将start与end时间同步,重复以上操作,用时间差来控制程序运行快慢。

作用:满足时间要求时可进行某个操作,也不影响其他操作的进行。(可用于蛇的运动快慢)

bool timer(int ms, int id)
{
	static int start[6] = { clock() };
	int end = clock();
	if (end - start[id] >= ms)
	{
		start[id] = end;
		return true;
	}
	return false;
}

三、数据的初始化和绘制

void InitData()
{

	initgraph(WIDTH, HEIGHT, 1);//1表示显示控制台
	
	//播放背景音乐
	mciSendString("open .\\resource\\bk1.mp3 alias bgm1", NULL, 0, NULL);
	mciSendString("play bgm1 repeat", NULL, 0, NULL);

	//初始化蛇
	snake.len = 10;
	snake.num = 3;
	snake.dir = right;
	snake.score = 0;
	snake.coord[2].x = 0;
	snake.coord[2].y = 0;
	snake.coord[1].x = snake.len;
	snake.coord[1].y = 0;
	snake.coord[0].x = 2 * snake.len;//作为蛇头
	snake.coord[0].y = 0;

	// 画食物
	food.fd.x = rand() % (WIDTH / 10) * 10;
	food.fd.y = rand() % (HEIGHT / 10) * 10;
	food.exis = 1;

	//按键选项初始化0
	option = 0;
	//蛇是否死亡
	snake_die = false;
	//游戏是否暂停初始化为否
	game_pause = false;
}

//绘制图形画面
void DrawImag()
{
	setbkcolor(GREEN);
	cleardevice();
	BeginBatchDraw();
	while (game_state == 1)
	{
		GameMenu();
	}
	//画蛇
	for (int i = snake.num - 1; i >= 0; i--)
	{
		setfillcolor(YELLOW);
		setlinecolor(BLACK);
		fillrectangle(snake.coord[i].x, snake.coord[i].y, snake.coord[i].x + snake.len, snake.coord[i].y + snake.len);
		//printf("%d,%d\n", snake.coord[i].x, snake.coord[i].y);
	}

	//画食物
	setfillcolor(RED);
	solidellipse(food.fd.x, food.fd.y, food.fd.x + snake.len, food.fd.y + snake.len);

	settextstyle(25, 0, "黑体");
	outtextxy(20, 20,"得分:");
	TCHAR c[3];
	sprintf(c, "%02d", snake.score);
	outtextxy(90, 20, c);
	setbkmode(TRANSPARENT);

	//画出暂停与返回菜单界面按键
	char button_name1[10] = { "暂停游戏" };
	char button_name2[10] = { "继续游戏" };
	char button_name3[10] = { "返回菜单" };
	//按键框(仅供参考,可以自己在做一个小按键隐藏按钮,避免遮挡视线)
	setfillcolor(WHITE);
	fillrectangle(10, 400, 130, 440);
	fillrectangle(10, 450, 130, 490);
	setlinecolor(WHITE);//当鼠标不再范围内边框变白
	rectangle(10, 400, 130, 440);
	rectangle(10, 450, 130, 490);

	setbkmode(TRANSPARENT);
	settextcolor(BLACK);
	outtextxy(10 + 60 - textwidth(button_name3) / 2, 450 + 20 - textheight(button_name3) / 2, button_name3);
	if (game_pause)
	{
		outtextxy(10 + 60 - textwidth(button_name1) / 2, 400 + 20 - textheight(button_name1) / 2, button_name2);
	}
	else
	{
		outtextxy(10 + 60 - textwidth(button_name2) / 2, 400 + 20 - textheight(button_name2) / 2, button_name1);
	}
	if (m2.x >= 10 && m2.x <= 130 && m2.y >= 400 && m2.y <= 440)
	{
		setlinecolor(RED);//鼠标在方形区域时边框变红
		rectangle(10, 400, 130, 440);
		option = 1;
	}
	if (m2.x >= 10 && m2.x <= 130 && m2.y >= 450 && m2.y <= 490)
	{
		setlinecolor(RED);
		rectangle(10, 450, 130, 490);
		option = 2;
	}
    //当游戏结束时
	if (snake_die)
	{
		setbkmode(TRANSPARENT);
		settextcolor(RED);
		settextstyle(40, 20, "黑体");
		outtextxy(100, 200, "吃到自己了,游戏结束!!");
		outtextxy(100, 240, "是否继续游戏!!");
		outtextxy(100, 280, "继续请按Y   否请按N");
	}

	FlushBatchDraw();
}

四、蛇的运行和吃食物

//蛇的移动
void SnakeMove()
{
	
	for (int i = snake.num - 1; i > 0; i--)
	{
		snake.coord[i].x = snake.coord[i - 1].x;
		snake.coord[i].y = snake.coord[i - 1].y;
	}
	//snake.coord[0].x += 10;
	switch (snake.dir)
	{
	case up:
		snake.coord[0].y -= 10;
		if (snake.coord[0].y +10 == 0)
		{
			snake.coord[0].y = HEIGHT;
		}
		break;
	case down:
		snake.coord[0].y += 10;
		if (snake.coord[0].y - 10 == HEIGHT)
		{
			snake.coord[0].y = 0 ;
		}
		break;
	case right:
		snake.coord[0].x += 10;
		if (snake.coord[0].x -10 == WIDTH)
		{
			snake.coord[0].x = 0;
		}
		break;
	case left:
		snake.coord[0].x -= 10;
		if (snake.coord[0].x +10 == 0)
		{
			snake.coord[0].x = WIDTH;
		}
		break;
	default:
		break;
	}
	//判断蛇是不是吃到自己了
	for (int i = 3; i < snake.num; i++)//当蛇身只有三个时吃不到自己
	{
		if (snake.coord[0].x == snake.coord[i].x&&snake.coord[0].y == snake.coord[i].y)
		{
			snake_die = true;
		}
	}
}

//用键盘控制
void KeyControl()
{
	if (GetAsyncKeyState(VK_UP) && snake.dir != down)
	{
		snake.dir = up;
	}
	if (GetAsyncKeyState(VK_DOWN) && snake.dir != up)
	{
		snake.dir = down;
	}
	if (GetAsyncKeyState(VK_RIGHT) && snake.dir != left)
	{
		snake.dir = right;
	}
	if (GetAsyncKeyState(VK_LEFT) && snake.dir != right)
	{
		snake.dir = left;
	}
}

//吃食物
void EatFood()
{
	srand((unsigned int)time(NULL));
	if (snake.coord[0].x == food.fd.x&&snake.coord[0].y == food.fd.y)
	{
		food.fd.x = rand() % (WIDTH / 10)  * 10;
		food.fd.y = rand() % (HEIGHT / 10)  * 10;
		snake.num++;
		snake.score++;
	}
}

五、游戏菜单界面

//游戏 界面菜单
void GameMenu()
{
	
	cleardevice();

	BeginBatchDraw();
	//游戏名字
	char game_name[20] = { "贪吃蛇" };
	setbkcolor(TRANSPARENT);
	settextcolor(GREEN);
	settextstyle(40, 20, "华文琥珀");
	outtextxy(WIDTH / 2 - textwidth(game_name) / 2, 40, game_name);
	
	if (MouseHit())
	{
		m1 = GetMouseMsg();
		if (m1.uMsg == WM_LBUTTONDOWN)
		{
			//开始新游戏
			if (option == 1) 
			{
				game_state = 2;
				mciSendString("close bgm1", NULL, 0, NULL);
				Sleep(400);
				mciSendString("open .\\resource\\bk2.mp3 alias bgm2", NULL, 0, NULL);
				mciSendString("play bgm2 repeat", NULL, 0, NULL);
			}
			else if (option == 2) 
			{ 
				ReadGame(); game_state = 2; mciSendString("close bgm1", NULL, 0, NULL);
				Sleep(400);
				mciSendString("open .\\resource\\bk2.mp3 alias bgm2", NULL, 0, NULL);
				mciSendString("play bgm2 repeat", NULL, 0, NULL);
			}//读取进度开始游戏
			else if (option == 3) { SaveGame(); closegraph(); _exit(0); }//保存并退出游戏
		}
	}

	option = 0;
	char select1[9] = { "游戏开始" };
	char select2[9] = { "继续游戏" };
	char select3[9] = { "保存退出" };

	int textw = 140;
	int texth = 40;

	
	settextcolor(WHITE);
	//开始游戏按钮
	if (m1.x >= WIDTH*0.39 &&m1.x <= WIDTH*0.39 + textw &&m1.y >= HEIGHT*0.3&&m1.y <= HEIGHT*0.3 + texth)
	{
		//settextcolor(RED);
		settextstyle(35, 0, "华文彩云");//悬浮在按钮上
		outtextxy(WIDTH*0.39, HEIGHT*0.3, select1);
		option = 1;
		//getchar();
	}
	else 
	{ 
		settextstyle(35, 0, "黑体"); //不在按钮上
		outtextxy(WIDTH*0.39, HEIGHT*0.3, select1);
	}

	//继续游戏
	if (m1.x >= WIDTH*0.39 &&m1.x <= WIDTH*0.39 + textw &&m1.y >= HEIGHT*0.5&&m1.y <= HEIGHT*0.5 + texth)
	{
		settextstyle(35, 0, "华文彩云");
		outtextxy(WIDTH*0.39, HEIGHT*0.5, select2);
		option = 2;
	}
	else
	{
		settextstyle(35, 0, "黑体");
		outtextxy(WIDTH*0.39, HEIGHT*0.5, select2);
	}

	//保存并退出游戏
	if (m1.x >= WIDTH*0.39 &&m1.x <= WIDTH*0.39 + textw &&m1.y >= HEIGHT*0.7&&m1.y <= HEIGHT*0.7 + texth)
	{
		settextstyle(35, 0, "华文彩云");
		outtextxy(WIDTH*0.39, HEIGHT*0.7, select3);
		option = 3;
	}
	else
	{
		settextstyle(35, 0, "黑体");
		outtextxy(WIDTH*0.39, HEIGHT*0.7, select3);
	}
	FlushBatchDraw();
	//clearrectangle(0, 0, WIDTH - 1, HEIGHT - 1);//用背景色清除当前区域
}

六、游戏存储与读写

文件打开失败没有连接其他功能,可自行添加

打开文件之后需要关闭文件

//存档
void SaveGame()
{
	char ch[20];
	sprintf(ch, "del storage.txt");
	system(ch);//删除已有存档

	FILE* stor;

	if ((stor = fopen("storage.txt", "w+")) == NULL)//打开失败
	{
		cleardevice();
		setbkmode(TRANSPARENT);
		settextcolor(RED);
		settextstyle(40, 20, "黑体");
		outtextxy(200, 300, "存档失败!!");
	}
	else
	{
		fwrite(&(snake.num), sizeof(snake.num), 1, stor);
		fwrite(&(snake.score), sizeof(snake.score), 1, stor);
		fwrite(&(snake.score), sizeof(snake.score), 1, stor);
		fwrite(&(snake.dir), sizeof(snake.dir), 1, stor);
		fwrite(&(snake.len), sizeof(snake.len), 1, stor);
		fwrite(&(food.fd), sizeof(food.fd), 1, stor);
		fwrite(&(food.exis), sizeof(food.exis), 1, stor);
		for (int i = 0; i <= snake.num; i++)
		{
			fwrite(&snake.coord[i], sizeof(snake.coord[i]), 1, stor);
		}
	}
	fclose(stor);
}

//读取游戏
void ReadGame()
{
	FILE* stor;
	if ((stor = fopen("storage.txt", "r")) == NULL)
	{
		cleardevice();
		setbkmode(TRANSPARENT);
		settextcolor(RED);
		settextstyle(40, 20, "黑体");
		outtextxy(200, 300, "读写失败,可能没有存档!!");
		getchar();
	}
	else
	{
		fread(&(snake.num), sizeof(snake.num), 1, stor);
		fread(&(snake.score), sizeof(snake.score), 1, stor);
		fread(&(snake.exis), sizeof(snake.exis), 1, stor);
		fread(&(snake.dir), sizeof(snake.dir), 1, stor);
		fread(&(snake.len), sizeof(snake.len), 1, stor);
		fread(&(food.fd), sizeof(food.fd), 1, stor);
		fread(&(food.exis), sizeof(food.exis), 1, stor);
		for (int i = 0; i <= snake.num ; i++)
		{
			fread(&snake.coord[i] , sizeof(snake.coord[i]) , 1, stor);
		}
	}
	fclose(stor);
}

七、其他函数

//当蛇吃到自己时游戏结束
void GameOver()
{
	if (snake_die)
	{
		char ch;
		ch = _getch();
		switch (ch)
		{
		case 'Y':
		case 'y':
			closegraph();
			InitData();
			mciSendString("close bgm1", NULL, 0, NULL);
			break;
		case'N':
		case'n':
			EndBatchDraw();
			closegraph();
			_exit(0);
			break;
		default:
			break;
		}
	}
}

//需输入更新
void UpdataWithInput()
{
	KeyControl();

	//判断是否有鼠标介入
	while (MouseHit())
	{
		m2 = GetMouseMsg();
		if (m2.uMsg == WM_LBUTTONDOWN)
		{
			if (option == 1)
			{
				game_pause = true;
			}
			else if (option == 2)
			{
				game_state = 1;
				mciSendString("close bgm2", NULL, 0, NULL);
				mciSendString("open .\\resource\\bk1.mp3 alias bgm1", NULL, 0, NULL);
				mciSendString("play bgm1 repeat", NULL, 0, NULL);
			}
		}

		//游戏暂停将会一直在此循环直到点击继续游戏或者返回主页菜单
		while (game_pause)
		{
			DrawImag();
			while (MouseHit())
			{
				m2 = GetMouseMsg();
				if (m2.uMsg == WM_LBUTTONDOWN)
				{
					if (option == 1)
					{
						game_pause = false;
					}
					else if (option == 2)
					{
						game_state = 1;
						mciSendString("close bgm2", NULL, 0, NULL);
						mciSendString("open .\\resource\\bk1.mp3 alias bgm1", NULL, 0, NULL);
						mciSendString("play bgm1 repeat", NULL, 0, NULL);
					}
				}
			}
		}

	}
}

//无需输入更新
void UpdataWithoutInput()
{
	if (timer(100, 0))
	{
		SnakeMove();
	}
	GameOver();
	EatFood();
	
}

八、主函数入口

//主入口
int main()
{
	InitData();
	
	while (true)
	{
		DrawImag();
		UpdataWithInput();
		UpdataWithoutInput();
	}
	closegraph();
	getchar();
	return 0;
}

总结:难点在于设计菜单需要用到多重循环,以及按键效果,数据存储时避免遗漏。

此游戏功能简单,仅供学习参考。(有不足的地方欢迎大家指出,希望能和大家一起学习进步)

有兴趣可以尝试完成其他功能,比如封装、添加ai蛇,速度随着长度增加,障碍物或用链表写一个贪吃蛇等。

easyx图形库资源,音乐资源网上可下载。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用C语言写一个简单的贪吃蛇游戏(用到easyx图形库) 的相关文章

  • 从0开始学PyTorch(一):线性回归、Softmax与分类模型、多层感知机

    文章目录 线性回归 模型 数据集 损失函数 优化函数 随机梯度下降 Softmax与分类感知机 softmax的基本概念 多层感知机 多层感知机的基本知识 隐藏层 表达公式 激活函数 线性回归 线性回归的基本要素 模型 为了简单起见 这里我
  • java文件下载接口,含泪整理面经

    Java如何入门 1 建立好开发环境 首先建立好开发环境非常重要 工欲善其事 必先利其器 做任何开发 首先就是要把这个环境准备好 之后就可以去做各种尝试 尝试过程中就能逐渐建立信心 初学者往往在环境配置中被各种预想不到的问题弄得很沮丧 这里
  • Python工业项目实战 04:数仓维度层DWS层构建

    知识点01 课程回顾 ODS层与DWD层的功能与区别是什么 ODS 原始数据层 存储格式 AVRO 数据内容 基本与原始数据是一致的 DWD 明细数据层 存储格式 Orc 数据内容 基于与ODS层是一致的 ODS层的需求是什么 自动化建库建
  • php怎么判断密码是否达标,php中简单的密码强中弱判断,php密码验证规则

    密码种类 1 小写字母 2 大写字母 3 数字 4 特殊符号 弱 1 中 2 强 3 或 4 长度 6 16个字符 区分大小写 1 长度判断 pwd len strlen password if pwd len gt 16 pwd len
  • 【华为OD机试】仿 LISP 运算【2023 B卷

    华为OD机试 真题 点这里 华为OD机试 真题考点分类 点这里 题目描述 LISP 语言唯一的语法就是括号要配对 形如 OP P1 P2 括号内元素由单个空格分割 其中第一个元素 OP 为操作符 后续元素均为其参数 参数个数取决于操作符类型

随机推荐

  • 百度语音合成精简版

    我参照文档合成的源码下载 https download csdn net download qq 31939617 10388588 下载 文档 Android TTS SDK 集成进入helloworld 项目 一 简介 本文针对遇见集成
  • io流读写文件(文件内容修改)

    package cn sos psasps import java io BufferedReader import java io BufferedWriter import java io FileReader import java
  • Git第十三讲 Git重置和回滚更改

    在使用Git时 我们有时可能会犯错或者需要撤销之前的提交或更改 Git提供了一些强大的命令来重置和回滚更改 帮助我们管理项目的版本控制 本文将介绍如何使用Git进行重置和回滚操作 重置到指定提交 重置 Reset 命令允许我们将分支的指针移
  • tar 打包压缩命令

    tar 命令用于文件的打包或压缩 是最为常用的打包压缩命令 其语法格式如下 tar 选项 文件名 tar gz 源文件 tar czvf xxx tar gz source file tar czvf 包名 tar gz 源文件 以tar
  • 【以太坊系列-005】使用solc编译solidity智能合约,并生产web3deploy格式的代码

    说明 本文主要介绍 只通过solc来进行智能合约的部署 更简单的方式是通过remix直接生成 该场景是用于用户自己修改了solc编译器 remix无法使用的情况 1 代码结构 cat counter sol pragma solidity
  • SPP连接流程

    1 SDP服务注册 Server Channel即RFCOMM Server Channel 表示上层profile的rfcomm channel Central设备会使用SDP查询SPP的Server Channel 在后面使用RFCOM
  • C++ — 类型萃取

    类型萃取 在编程中我们可能时常会听到类型萃取这个高大上的 学术名词 我们今天来探究一下这个高大上的学术名词 到底是何方神圣 先看看官方的解释类型萃取使用模板技术来萃取类型 包含自定义类型和内置类型 的某些特 性 用以判断该类型是否含有某些特
  • Coinbase 研究:Web3 开发者堆栈指南

    原文标题 A simple guide to the web3 developer stack 撰文 Jonathan King Connor Dempsey Hoolie Tejwani 编译 胡韬 链捕手 尽管比特币和以太坊的兴起 以及
  • 电力识读图解(电力系统、电力网、电力系统电路图)

    一 电力系统和电力网 世界上大部分国家的动力资源和电力负荷中心分布是不一致的 如水力资源都是集中在江河流域水位落差较大的地方 燃料资源集中在煤 石油 天燃气的矿区 大电力负荷中心则多集中在工业区和大城市 因而发电厂和负荷中心往往相隔很远的距
  • 岁月划过生命线(2016 年终总结 -季度之星)

    岁月划过生命线 2016 年终总结 季度之星 标签 coder 年假结束 明天就要回到杭州 回到我fighting的战场 回首过去的2016 放纵了许多 但也收获了很多 n个项目 n个框架 第一个季度之星 头像第一次登上CSDN以及第一个年
  • 【C++笔记】OpenCV图像Mat格式转换为QT中QImage并显示zai Qlabel上

    Mat rgb QImage imgGray img if imgGray channels 1 imgGray img QImage const unsigned char imgGray data imgGray cols imgGra
  • 蓝桥杯官网练习题(兰顿蚂蚁)

    题目描述 兰顿蚂蚁 是于 1986 年 由克里斯 兰顿提出来的 属于细胞自动机的一种 平面上的正方形格子被填上黑色或白色 在其中一格正方形内有一只 蚂蚁 蚂蚁的头部朝向为 上下左右其中一方 蚂蚁的移动规则十分简单 若蚂蚁在黑格 右转 90
  • 标准时间格式转unix时间戳格式,误差8小时问题常见原因剖析

    标准时间格式即人一眼就能看懂的时间格式 比如 2017 11 28 15 00 00 unix时间戳格式 就是从1970年1月1日0点0分0秒 UTC GMT的午夜 开始计时 所经过的秒数 前端工作中有一次遇到需要从数据库中取出标准格式时间
  • 51单片机的智能温室大棚控制系统【proteus仿真+程序+报告+原理图】

    1 主要功能 该系统由AT89C51单片机 LCD1602模块 DS18B20温度传感器模块 DS1302时间模块 继电器驱动模块 电位器模块构成 本方案适用于智能温室大棚 蔬菜大棚等各类设计中 版本一 1 DS18B20温度传感器检测大棚
  • linux服务器结合宝塔搭建Gitlab服务器完整过程

    不想被束缚 公司总是不给我gitlab管理员账号 我自己搭建一个去 又不是没有服务器的人 哼 1 宝塔安装GitLab服务器 根据自己的内存选择不用的版本安装 2 宝塔开发端口如 8099 这个是我的Gitlab服务器的端口 如果有防火墙那
  • 虚拟化技术原理(CPU、内存、IO)

    本文来自 http www ywnds com p 5856 虚拟化 云计算现在已经非常成熟了 而虚拟化是构建云计算基础架构不可或缺的关键技术之一 云计算的云端系统 其实质上就是一个大型的分布式系统 虚拟化通过在一个物理平台上虚拟出更多的虚
  • 简单明了实现Java地图小程序项目

    简单明了实现Java地图小程序项目 博主介绍 前言 地图概述 地图技术 地图应用场景 网约车服务 智能穿戴 智能物流 智能景区 车联网 国内常见地图 地图API与搜索 JS API GL 演示百度地图 创建浏览器端应用 创建地图 添加控件
  • NGUI的一个bug解决:Thetype or namespace name `UnityEditor‘ could not be found.

    BUG Thetype or namespace name UnityEditor could not be found Are you missing ausing directive or an assembly reference 解
  • 计算机网络必会:TCP和UDP,面向连接,无连接,可靠与不可靠

    文章目录 导论 面向连接可靠的服务 TCP 无连接 不可靠的服务 UDP 导论 我在学习计算机网络的过程中 遇到了TCP和UDP解释 其中 无连接 面向连接 对我有很多新启发 下面就简单来聊聊 有兴趣多点个赞收藏一下 有错误可以私信反馈 欢
  • 用C语言写一个简单的贪吃蛇游戏(用到easyx图形库)

    学习内容 1 游戏的存储与读写 2 制作游戏菜单 3 制作定时器 目录 一 需要用到的头文件 全局变量和一些函数 二 定时器 三 数据的初始化和绘制 四 蛇的运行和吃食物 五 游戏菜单界面 六 游戏存储与读写 七 其他函数 八 主函数入口