贪吃蛇,有兴趣的可以自取,为了大家移植方便没有写头文件,直接复制就可以运行,编译环境是vs2022。
但是运行之前首先要进行两个配置,不然会报错
1>将字符集改为“使用多字节字符”
>因为我为游戏加入了背景音乐,所以要在贪吃蛇文件中新建一个sound文件,然后再加入四首音乐进去,记住重命名,名字和我的四首音乐一样(网易云的音乐格式不行,要用qq音乐的)
双人游戏我没有写,有兴趣的可以自己加进去。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
#include <mmsystem.h>
#include<easyx.h>
#pragma comment (lib,"winmm.lib")
#define frame_height 30//地图尺寸
#define frame_width 50
#define MAX 500
#define UP 'w'//移动
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'
int i, j, k, sp, score, s;
char x = '1';//判断是否继续游戏
char m = '1', a;
char ch = UP, state = UP, choo, str, n; //初始化方向
int grow = 0, c = 0;
typedef struct coor
{
int x;
int y;
}coor;
//蛇的基本属性
struct snake
{
int num;//蛇的总节数
coor xy[MAX];//存储蛇的坐标的结构体数组
char way;
}snake;
//食物的基本属性
struct food
{
coor fdxy;
int flag = 0;
int eatgrade = 0;
}food;
//方向枚举
enum way
{
right = 72,
left = 75,
down = 77,
up = 80
};
struct ranks //排行榜
{
int grade;
int rank1;
int rank2;
int rank3;
}rank[100];
void ranking();
void save();
void nice();
int color(int c);
void menu();
void mode();
void game();
void expain();
void gotoxy(int x, int y);//移动光标,进行游戏界面的打印
//初始化蛇
void insnake();
//绘制蛇
void inisnake();
//蛇的移动
void way();
//蛇的方向
void snakemove();
//蛇的食物
void foodxy();
//食物绘制
void inifood();
//判断蛇是否吃掉食物
void eatfood();
//判断蛇是否吃挂掉
void snakedie();
//游戏过程中,按 空格 可以对游戏进行暂停、开始
void again();
//存储蛇的坐标的结构体
int main()
{
FILE* fp;
fp = fopen("data.txt", "a+");
while (!feof(fp)) //得到有多少组数据
{
if (fscanf(fp, "%d %d %d %d", &rank[c].grade, &rank[c].rank1,
&rank[c].rank2, &rank[c].rank3) != 0)
c++;
}
while (m == '1')
{
n = '1';
score = 0;
system("cls");
nice();
menu();
switch (n)
{
case '1': //选择游戏难度
mciSendString("close song", NULL, 0, NULL);
mciSendString("open sound//anny3.mp3 alias song", NULL, 0, NULL);
mciSendString("play song repeat", NULL, 0, NULL);
game();
system("cls");
break;
case '2': //选择历史榜单
expain();
break;
case '3': //选择退出游戏
ranking();
break;
case '4': //选择退出游戏
gotoxy(30, 28);
exit(0);
break;
default: //输入非1~3之间的选项
color(12);
gotoxy(25, 45);
printf("输入错误!请输入1~3之间的数!");
a = _getch();
system("cls");
m = '1';
break;
}
}
fclose(fp);
gotoxy(30, 48);
}
//初始化蛇
void insnake() {
initgraph(650, 480);
setbkcolor(LIGHTGRAY);
snake.xy[2].x = 0;
snake.xy[2].y = 0;
snake.xy[1].x = 10;
snake.xy[1].y = 0;
snake.xy[0].x = 20;
snake.xy[0].y = 0;
snake.num = 3;
snake.way = right;
food.flag = 0;
}
//绘制蛇
void inisnake()
{
for (int i = 0; i < snake.num; i++)
{
setlinecolor(LIGHTGREEN);
if (i % 2 == 0)
{
setfillcolor(LIGHTGREEN);
}
else
{
setfillcolor(YELLOW);
}
fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10);
}
}
//蛇的移动
void way()
{
//除了第一节蛇,后面每节都是前面一节蛇的前一次坐标
for (int i = snake.num - 1; i > 0; i--)
{
snake.xy[i].x = snake.xy[i - 1].x;
snake.xy[i].y = snake.xy[i - 1].y;
}
switch (snake.way)
{
case right:
snake.xy[0].x += 10;
break;
case left:
snake.xy[0].x -= 10;
break;
case down:
snake.xy[0].y += 10;
break;
case up:
snake.xy[0].y -= 10;
break;
default:
break;
}
}
//蛇的方向控制
void snakemove()
{
char ch = 0;
ch = _getch();
switch (ch)
{
case 'w':
if (snake.way != down)
snake.way = up;
break;
case 'a':
if (snake.way != right)
snake.way = left;
break;
case 'd':
if (snake.way != left)
snake.way = right;
break;
case 's':
if (snake.way != up)
snake.way = down;
break;
default:
break;
}
}
//食物坐标获取
void foodxy()
{
//蛇坐标 0 10 20 30 n*10
//食物 如果 rand() % 650 那么坐标0 1 2 3 4 蛇将吃不到食物 坐标重合低
food.fdxy.x = rand() % 65 * 10;
food.fdxy.y = rand() % 48 * 10;
food.flag = 1;
for (int i = 0; i > snake.num; i++)
{
if (food.fdxy.x == snake.xy[i].x && food.fdxy.y == snake.xy[i].y)
{
food.fdxy.x = rand() % 65 * 10;
food.fdxy.y = rand() % 48 * 10;
}
}
}
//绘制食物
void inifood()
{
fillrectangle(food.fdxy.x, food.fdxy.y, food.fdxy.x + 10, food.fdxy.y + 10);
}
//吃食物的判断
void eatfood()
{
if (snake.xy[0].x == food.fdxy.x && snake.xy[0].y == food.fdxy.y)
{
snake.num++;
food.eatgrade += 10;
food.flag = 0;
}
}
//判断蛇是否死亡
void snakedie()
{
char grade[100] = { 0 };//分数
sprintf(grade, "%d", food.eatgrade);
setbkmode(0);//文字背景透明
outtextxy(570, 20, "分数:");
outtextxy(610, 20, grade);
if (snake.xy[0].x > 640 || snake.xy[0].x < 0 || snake.xy[0].y > 470 || snake.xy[0].y < 0)
{
save();
outtextxy(240, 320, "撞墙了,游戏结束!");
outtextxy(240, 350, "1.退出游戏");
outtextxy(240, 370, "2.重新开始");
Sleep(1000);
x = _getch();
if (x != '2')
{
gotoxy(30, 28);
exit(0);
}
}
for (int i = 1; i < snake.num; i++)
{
if (snake.xy[0].x == snake.xy[i].x && snake.xy[0].y == snake.xy[i].y)
{
save();
outtextxy(240, 320, "你咬死了自己,游戏结束!");
outtextxy(240, 350, "1.退出游戏");
outtextxy(240, 370, "2.重新开始");
Sleep(1000);
x = _getch();
if (x != '2')
{
gotoxy(30, 28);
exit(0);
}
}
}
}
void again()
{
if (_getch() == 32)
{
while (_getch() != 32);
}
}
void game()
{
int flag = 1;
while (1)
{
if(flag==1)
mode();
flag++;
x = '1';
switch (s)
{
case '1':
{
srand((unsigned int)time(NULL));//随机数种子,后面随机产生蛇的食物要用到
insnake();//初始化蛇
while (x=='1')
{
cleardevice();// 清屏
if (food.flag == 0)
{
foodxy();//获取食物坐标
}
inifood();
inisnake();
snakedie();
eatfood();//吃食物的判断
way();//蛇的移动
Sleep(100);
while (_kbhit())//这里是按上下左右键控制蛇的移动
{
//again();//暂停
snakemove();//蛇的方向控制
}
}
break;
}
case '2':
{
flag = 1;
break;
}
default:
{
flag = 1;
break;
}
}
}
}
/*移动光标*/
void nice()
{
system("cls");
printf(" \n");
Sleep(100); color(2);
printf(" __________ ___ \n");
Sleep(100); color(1);
printf(" / \\ / \\ \\ |____ __\\__ \n");
Sleep(100); color(2);
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
Sleep(100); color(3);
printf(" | | |__| _/_ |_| / [|] |/ \n");
Sleep(100); color(4);
printf(" | | | | | / _|_ \\__/ \n");
Sleep(100); color(5);
printf(" \\ \\_______ / \\ |___/ ____ \n");
Sleep(100); color(6);
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
Sleep(100); color(7);
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
Sleep(100); color(8);
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
Sleep(100); color(9);
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
Sleep(100); color(1);
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
Sleep(100); color(0);
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
Sleep(100); color(9);
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
mciSendString("close song", NULL, 0, NULL);
mciSendString("open sound//anny.mp3 alias song", NULL, 0, NULL);
mciSendString("play song repeat", NULL, 0, NULL);
}
int color(int c)
{
//SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色
/*SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
BACKGROUND_INTENSITY | BACKGROUND_RED | BACKGROUND_GREEN |
BACKGROUND_BLUE | c);*///设置三色相加
return 0;
}
void menu()
{
color(6);
for (i = 20; i <= 28; i++) //输出上下边框
{
for (j = 26; j <= 75; j++) //输出左右边框
{
gotoxy(i, j);
if (i == 20 || i == 28)
{
printf("═");
}
else if (j == 26 || j == 75)
{
printf("‖");
}
}
}
gotoxy(18, 43);
color(11);
printf("贪 吃 蛇 游 戏");
gotoxy(22, 28);
color(6);
printf("1.开始游戏");
gotoxy(24, 28);
color(2);
printf("2.游戏说明");
gotoxy(26, 28);
color(5);
printf("3.排行榜");
gotoxy(26, 45);
color(8);
printf("4.退出游戏");
gotoxy(23, 45);
color(3);
printf("请选择[1 2 3 4]:[ ]\b\b");
n = _getch();
}
void mode()
{
system("cls");
printf(" \n");
color(2);
printf(" __________ ___ \n");
color(1);
printf(" / \\ / \\ \\ |____ __\\__ \n");
color(2);
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
color(3);
printf(" | | |__| _/_ |_| / [|] |/ \n");
color(4);
printf(" | | | | | / _|_ \\__/ \n");
color(5);
printf(" \\ \\_______ / \\ |___/ ____ \n");
color(6);
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
color(7);
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
color(8);
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
color(9);
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
color(10);
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
color(11);
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
color(12);
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
color(6);
for (i = 20; i <= 28; i++) //输出上下边框
{
for (j = 26; j <= 75; j++) //输出左右边框
{
gotoxy(i, j);
if (i == 20 || i == 28)
{
printf("═");
}
else if (j == 26 || j == 75)
{
printf("‖");
}
}
}
gotoxy(18, 43);
color(11);
printf("请 选 择 难 度");
gotoxy(22, 28);
color(6);
printf("1.单人游戏");
gotoxy(24, 28);
color(2);
printf("2.双人游戏");
/*gotoxy(26, 28);
color(5);
printf("3.困 难");*/
gotoxy(23, 45);
color(3);
printf("请选择[1 2 3]:[ ]\b\b");
mciSendString("close song", NULL, 0, NULL);
mciSendString("open sound//anny1.mp3 alias song", NULL, 0, NULL);
mciSendString("play song repeat", NULL, 0, NULL);
s = _getch(); //scanf("%d",&s);
}
void expain()
{
system("cls");
printf(" \n");
color(2);
printf(" __________ ___ \n");
color(1);
printf(" / \\ / \\ \\ |____ __\\__ \n");
color(2);
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
color(3);
printf(" | | |__| _/_ |_| / [|] |/ \n");
color(4);
printf(" | | | | | / _|_ \\__/ \n");
color(5);
printf(" \\ \\_______ / \\ |___/ ____ \n");
color(6);
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
color(7);
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
color(8);
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
color(9);
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
color(10);
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
color(11);
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
color(12);
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
color(6);
for (i = 20; i <= 28; i++) //输出上下边框
{
for (j = 26; j <= 75; j++) //输出左右边框
{
gotoxy(i, j);
if (i == 20 || i == 28)
{
printf("═");
}
else if (j == 26 || j == 75)
{
printf("‖");
}
}
}
gotoxy(18, 43);
color(11);
printf("游 戏 说 明");
gotoxy(22, 28);
color(6);
printf("1.用上W下S左A右D控制吃东西 ");
gotoxy(24, 28);
color(2);
printf("2.不能碰墙,不能咬到自己");
gotoxy(26, 28);
color(5);
printf("3.得分会自动记录到data.txt文件中");
gotoxy(24, 80);
color(2);
printf("按任意键返回主菜单");
mciSendString("close song", NULL, 0, NULL);
mciSendString("open sound//anny2.mp3 alias song", NULL, 0, NULL);
mciSendString("play song repeat", NULL, 0, NULL);
a = _getch();
m = '1';
}
void save()
{
FILE* fp;
fp = fopen("data.txt", "a+");
time_t rawtime;
struct tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime); //时间函数
if (fp == NULL)
{
printf("无法打开文件!");
n = _getch();
exit(0);
}
else
{
if (food.eatgrade > rank[c-2].rank1)
{
rank[c - 2].rank3 = rank[c - 2].rank2;
rank[c - 2].rank2 = rank[c - 2].rank1;
rank[c - 2].rank1 = food.eatgrade;
}
else if (food.eatgrade > rank[c - 2].rank2)
{
rank[c - 2].rank3 = rank[c - 2].rank2;
rank[c - 2].rank2 = food.eatgrade;
}
else if (food.eatgrade > rank[c - 2].rank3)
{
rank[c - 2].rank3 = food.eatgrade;
}
fprintf(fp, "%d %d %d %d\n",food.eatgrade,
rank[c - 2].rank1, rank[c - 2].rank2, rank[c - 2].rank3);
}
fclose(fp);
}
void gotoxy(int x, int y)
{
HANDLE hout;
COORD cor;
hout = GetStdHandle(STD_OUTPUT_HANDLE);//从标准输出设备中取得一个句柄
cor.X = y;
cor.Y = x;
SetConsoleCursorPosition(hout, cor);//定位光标的函数
}
void ranking()
{
system("cls");
printf(" \n");
color(2);
printf(" __________ ___ \n");
color(1);
printf(" / \\ / \\ \\ |____ __\\__ \n");
color(2);
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
color(3);
printf(" | | |__| _/_ |_| / [|] |/ \n");
color(4);
printf(" | | | | | / _|_ \\__/ \n");
color(5);
printf(" \\ \\_______ / \\ |___/ ____ \n");
color(6);
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
color(7);
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
color(8);
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
color(9);
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
color(10);
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
color(11);
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
color(12);
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
color(6);
for (i = 20; i <= 28; i++) //输出上下边框
{
for (j = 26; j <= 75; j++) //输出左右边框
{
gotoxy(i, j);
if (i == 20 || i == 28)
{
printf("═");
}
else if (j == 26 || j == 75)
{
printf("‖");
}
}
}
gotoxy(18, 43);
color(11);
printf("贪 吃 蛇 游 戏");
gotoxy(22, 28);
color(6);
printf("1. %d",rank[c-2].rank1);
gotoxy(24, 28);
color(2);
printf("2. %d", rank[c-2].rank2);
gotoxy(26, 28);
color(5);
printf("3. %d", rank[c-2].rank3);
gotoxy(24, 80);
color(2);
printf("按任意键返回主菜单");
_getch();
m = '1';
}
2.当然如果编译环境是Dev c++和vc++的,这里也有,不过没有背景音乐和easyx,直接复制就可以运行,比较简易
这是运行结果:
#define _CRT_SECURE_NO_WARNINGS
//#define _getch() __getch()
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
#define frame_height 30//地图尺寸
#define frame_width 50
#define UP 'w'//移动
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'
int i, j, k, sp, score, s;
char m = '1', a;
char ch = UP, state = UP, choo, str, n; //初始化方向
int grow = 0;
struct Food//食物
{
int x;//横坐标
int y;//纵坐标
} food;
struct Snake//蛇
{
/*用数组储存蛇的每一部分的坐标*/
int x[100];
int y[100];
int len;//长度
int speed;//速度
} snake;
void save();
void nice();
int color(int c);
void menu();
void difficulty();
void move();
void expain();
void map();//地图
void update_food(void);//更新食物
void move_snake(void);//蛇的移动
int alive(void);//判断蛇是否死亡
void get_speed(void);//更新速度
void gotoxy(int x, int y);//移动光标,进行游戏界面的打印
void speed(int s);
int main()
{
FILE* fp;
fp = fopen("data.txt", "ab+");
while (m == '1')
{
n = '1';
score = 0;
system("cls");
nice();
menu();
switch (n)
{
case '1': //选择游戏难度
difficulty();
speed(s);
system("cls");
map(); //打印地图
move();
break;
case '2': //选择历史榜单
expain();
m = '1';
break;
case '3': //选择退出游戏
gotoxy(30, 28);
exit(0);
break;
default: //输入非1~3之间的选项
color(12);
gotoxy(25, 45);
printf("输入错误!请输入1~3之间的数!");
a=_getch();
system("cls");
m = '1';
break;
}
}
fclose(fp);
gotoxy(30, 48);
}
void move()
{
if (n == '1')
{
while (1)
{
update_food();//生产食物
get_speed();//获取速度
move_snake();//移动
Sleep(snake.speed);//延时函数,speed数值越大延时越长
if (!(alive()))//判断蛇是否死亡
{
save(); //保存数据到data.txt文件
break; //死亡则退出循环
}
}
gotoxy(20, 60);
printf("游戏结束!\n");
gotoxy(22, 60);
printf("1:重新开始\t2:退出");
gotoxy(24, 60);
printf("请选择[1 2 ]:[ ]\b\b");
m = _getch();
}
}
void map()
{
srand(time(NULL));
/*打印第一个食物*/
/*Attention!此处留了一个bug:可能食物
的位置与初始的蛇重合,然后食物就会消
失,读者可以加以改进*/
food.x = rand() % (frame_height - 2) + 1;
food.y = rand() % (frame_width - 2) + 1;//在框内
gotoxy(food.x, food.y);//把光标移动到该坐标
printf("0");//打印食物
/*snake的初始化*/
snake.x[0] = frame_height / 2;
snake.y[0] = frame_width / 2;
gotoxy(snake.x[0], snake.y[0]);
printf("o");
snake.len = 3;
snake.speed = 200;
for (k = 1; k < snake.len; k++)
{
snake.x[k] = snake.x[k - 1] + 1;
snake.y[k] = snake.y[k - 1];
gotoxy(snake.x[k], snake.y[k]);
printf("o");
}
/*墙壁*/
for (j = 0; j < frame_width; j++)
{
gotoxy(0, j);
printf("=");
gotoxy(frame_height - 1, j);
printf("=");
}
for (i = 0; i < frame_height - 1; i++)
{
gotoxy(i, 0);
printf("|");
gotoxy(i, frame_width - 1);
printf("|");
}
gotoxy(2, frame_width + 3);
if (s == '1') printf("难度: 简 单");
else if (s == '2') printf("难度: 普 通");
else if (s == '3') printf("难度: 困 难");
else printf("欢迎来到魔鬼难度!");
gotoxy(4, frame_width + 3);
color(1);
printf("上: w");
gotoxy(6, frame_width + 3);
color(2);
printf("下: s");
gotoxy(8, frame_width + 3);
color(3);
printf("左: a");
gotoxy(10, frame_width + 3);
color(4);
printf("右:d");
gotoxy(12, frame_width + 3);
color(3);
printf("目前得分:%d", score);
gotoxy(28, frame_width + 3);
printf("Made by jack ");
}
/*食物*/
void update_food()
{
if (snake.x[0] == food.x && snake.y[0] == food.y)//吃到食物
{
score += 10;
color(3);
gotoxy(12, frame_width + 3);
printf("目前得分:%d", score);
srand(time(NULL));
int flag = 1; //标记变量
do
{
food.x = rand() % (frame_height - 2) + 1;
food.y = rand() % (frame_width - 2) + 1; //在框内
for (i = 0; i < snake.len; i++)
{
if (food.x == snake.x[i] && food.y == snake.y[i])
{
flag = 0; //有重合
break;
}
}
} while (flag == 0);
/*打印食物*/
gotoxy(food.x, food.y);
printf("0");
snake.len++;
grow = 1; //表明长了,在move_snake函数中有用到
}
}
/*移动蛇*/
void move_snake()
{
while (_kbhit())//键盘有输入
{
ch = _getch();
}
if (!grow)//没有长
{
gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
printf(" ");//走了,在数组的最后打印空格,清除原有的蛇尾
}
for (k = snake.len - 1; k > 0; k--)//更新蛇的坐标,除了蛇头,其余位置继承上一个点的坐标
{
snake.x[k] = snake.x[k - 1];
snake.y[k] = snake.y[k - 1];//移动位置
}
switch (ch)//改变方向
{
case UP:
{
if (state == DOWN)//如果此时方向向下,输入向上的作用要被无视
{
snake.x[0]++;
break;
}
else
{
snake.x[0]--;
state = UP;//其余的改变状态为向上
break;
}
}
case DOWN:
{
if (state == UP)
{
snake.x[0]--;
break;
}
else
{
snake.x[0]++;
state = DOWN;
break;
}
}
case LEFT:
{
if (state == RIGHT)
{
snake.y[0]++;
break;
}
else
{
snake.y[0]--;
state = LEFT;
break;
}
}
case RIGHT:
{
if (state == LEFT)
{
snake.y[0]--;
break;
}
else
{
snake.y[0]++;
state = RIGHT;
break;
}
}
/*摁其余键,保持原有状态*/
default:
{
if (state == DOWN)
{
snake.x[0]++;
break;
}
else if (state == UP)
{
snake.x[0]--;
break;
}
else if (state == LEFT)
{
snake.y[0]--;
break;
}
else if (state == RIGHT)
{
snake.y[0]++;
break;
}
}
}
gotoxy(snake.x[0], snake.y[0]);
printf("o");//打印蛇头
grow = 0;//初始成长状态为0
gotoxy(frame_height, 0);//光标移动到地图左下角下方
}
/*存活状态*/
int alive(void)
{
if (snake.x[0] == 0 || snake.x[0] == frame_height - 1
|| snake.y[0] == 0 || snake.y[0] == frame_width - 1)//撞墙
return 0;
for (k = 1; k < snake.len; k++) //咬到自己
{
if (snake.x[0] == snake.x[k] && snake.y[0] == snake.y[k])
return 0;
}
return 1;
}
/*加速*/
/*speed越大,蛇的速度越小*/
void get_speed()
{
if (snake.len <= 6)
snake.speed = sp;
else if (snake.len <= 10)
snake.speed = sp - 20;
else if (snake.len <= 20)
snake.speed = sp - 50;
else if (snake.len <= 30)
snake.speed = sp - 60;
else
snake.speed = sp - 70;
}
void speed(int s)
{
switch (s)
{
case '1':
{
sp = 300;
break;
}
case '2':
{
sp = 230;
break;
}
case '3':
{
sp = 180;
break;
}
default:
{
printf("恭喜!欢迎来到魔鬼难度!\n");
sp = 120;
break;
}
}
}
/*移动光标*/
void nice()
{
printf(" \n");
Sleep(100); color(2);
printf(" __________ ___ \n");
Sleep(100); color(1);
printf(" / \\ / \\ \\ |____ __\\__ \n");
Sleep(100); color(2);
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
Sleep(100); color(3);
printf(" | | |__| _/_ |_| / [|] |/ \n");
Sleep(100); color(4);
printf(" | | | | | / _|_ \\__/ \n");
Sleep(100); color(5);
printf(" \\ \\_______ / \\ |___/ ____ \n");
Sleep(100); color(6);
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
Sleep(100); color(7);
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
Sleep(100); color(8);
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
Sleep(100); color(9);
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
Sleep(100); color(10);
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
Sleep(100); color(11);
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
Sleep(100); color(12);
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
}
int color(int c)
{
//SetConsoleTextAttribute是API设置控制台窗口字体颜色和背景色的函数
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //更改文字颜色
return 0;
}
void menu()
{
color(6);
for (i = 20; i <= 28; i++) //输出上下边框
{
for (j = 26; j <= 75; j++) //输出左右边框
{
gotoxy(i, j);
if (i == 20 || i == 28)
{
printf("═");
}
else if (j == 26 || j == 75)
{
printf("‖");
}
}
}
gotoxy(18, 43);
color(11);
printf("贪 吃 蛇 游 戏");
gotoxy(22, 28);
color(6);
printf("1.开始游戏");
gotoxy(24, 28);
color(2);
printf("2.游戏说明");
gotoxy(26, 28);
color(5);
printf("3.退出游戏");
gotoxy(23, 45);
color(3);
printf("请选择[1 2 3]:[ ]\b\b");
n = _getch();
}
void difficulty()
{
system("cls");
printf(" \n");
color(2);
printf(" __________ ___ \n");
color(1);
printf(" / \\ / \\ \\ |____ __\\__ \n");
color(2);
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
color(3);
printf(" | | |__| _/_ |_| / [|] |/ \n");
color(4);
printf(" | | | | | / _|_ \\__/ \n");
color(5);
printf(" \\ \\_______ / \\ |___/ ____ \n");
color(6);
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
color(7);
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
color(8);
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
color(9);
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
color(10);
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
color(11);
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
color(12);
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
color(6);
for (i = 20; i <= 28; i++) //输出上下边框
{
for (j = 26; j <= 75; j++) //输出左右边框
{
gotoxy(i, j);
if (i == 20 || i == 28)
{
printf("═");
}
else if (j == 26 || j == 75)
{
printf("‖");
}
}
}
gotoxy(18, 43);
color(11);
printf("请 选 择 难 度");
gotoxy(22, 28);
color(6);
printf("1.简 单");
gotoxy(24, 28);
color(2);
printf("2.普 通");
gotoxy(26, 28);
color(5);
printf("3.困 难");
gotoxy(23, 45);
color(3);
printf("请选择[1 2 3]:[ ]\b\b");
s = _getch(); //scanf("%d",&s);
}
void expain()
{
system("cls");
printf(" \n");
color(2);
printf(" __________ ___ \n");
color(1);
printf(" / \\ / \\ \\ |____ __\\__ \n");
color(2);
printf(" / ________ \\ / ___ \\ _/ __ | | / \n");
color(3);
printf(" | | |__| _/_ |_| / [|] |/ \n");
color(4);
printf(" | | | | | / _|_ \\__/ \n");
color(5);
printf(" \\ \\_______ / \\ |___/ ____ \n");
color(6);
printf(" \\ \\ ____ ____ ____ __ | | ___ ______ \n");
color(7);
printf(" \\_______ \\ | |/ \\ / \\_/ / | | / / / \\ \n");
color(8);
printf(" \\ \\ | ___ \\ / ____ / | |/ / / ____ \\ \n");
color(9);
printf(" __ | | | / \\ \\ | | | / | / | /____\\ | \n");
color(10);
printf(" \\ \\_______| | | | | | | |__| | | \\ | ________/ \n");
color(11);
printf(" \\ / | | | | \\ \\ | |\\ \\ \\ \\____ \n");
color(12);
printf(" \\__________/ |__| |__| \\___/\\__\\ |__| \\__\\ \\______/ \n");
color(6);
for (i = 20; i <= 28; i++) //输出上下边框
{
for (j = 26; j <= 75; j++) //输出左右边框
{
gotoxy(i, j);
if (i == 20 || i == 28)
{
printf("═");
}
else if (j == 26 || j == 75)
{
printf("‖");
}
}
}
gotoxy(18, 43);
color(11);
printf("游 戏 说 明");
gotoxy(22, 28);
color(6);
printf("1.用上W下S左A右D控制吃东西,身体越长,速度越快 ");
gotoxy(24, 28);
color(2);
printf("2.不能碰墙,不能咬到自己");
gotoxy(26, 28);
color(5);
printf("3.得分会自动记录到data.txt文件中");
gotoxy(24, 80);
color(2);
printf("按任意键返回主菜单");
a=_getch();
m = 1;
}
void save()
{
FILE* fp;
fp = fopen("data.txt", "ab+");
time_t rawtime;
struct tm* timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime); //时间函数
if (fp == NULL)
{
printf("无法打开文件!");
n=_getch();
exit(0);
}
else if (!(alive())) //判断蛇是否死亡
{
fprintf(fp, "%4d-%02d-%02d %02d:%02d:%02d 得分:%d\n", 1900 + timeinfo->tm_year, 1 + timeinfo->tm_mon,
timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, score);
}
}
void gotoxy(int x, int y)
{
HANDLE hout;
COORD cor;
/*
typedef struct _COORD
{
SHORT X; // horizontal coordinate
SHORT Y; // vertical coordinate
} COORD;
用该结构体来储存坐标
*/
hout = GetStdHandle(STD_OUTPUT_HANDLE);//从标准输出设备中取得一个句柄
/*这其中x,y的赋值对象要注意,不懂的好好想想*/
cor.X = y;
cor.Y = x;
SetConsoleCursorPosition(hout, cor);//定位光标的函数
}