#include<stdio.h>
#include<conio.h>
#include<windows.h>
#include<time.h>
#define framex 5
#define framey 5
#define wide 20
#define high 20
//#define HEIGHT_POINTS 10
int HEIGHT_POINTS = 0;
int i,j,a[2];
int CLK;
int ECK;
//将光标移动到指定位置
void gotoxy(HANDLE hout,int x,int y) {
//COORD是WindowsAPI中定义的一种结构,表示一个字符在控制台屏幕上的坐标
COORD pos;
pos.X = x;
pos.Y = y;
//SetConsoleCursorPosition是API中定位光标位置的函数。
SetConsoleCursorPosition(hout, pos);
}
//游戏封面
void cover(HANDLE hout) {
gotoxy(hout, framex + wide, framey);
printf("欢迎使用贪吃蛇游戏");
gotoxy(hout, framex + wide, framey + 5);
printf("开始游戏前请关闭中文输入法");
system("pause>nul");
system("cls");
}
//定义蛇的结构体
struct Snake {
int x[100];
int y[100];
int speed;
int length;
int count;
int delay;
int mode;
};
//定义食物的结构体
struct Food {
int x;
int y;
};
//制作框架
void makeframe(struct Snake *snake) {
//定义显示器变量句柄
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
gotoxy(hout, framex + wide * 2 + 5, framey);
printf( " 贪吃蛇游戏");
if (snake->mode == 1) {
printf("初级模式");
}
else if (snake->mode == 1) {
printf("中级模式");
}
else if (snake->mode == 1) {
printf("高级模式");
}
else if (snake->mode == 1) {
printf("挑战模式");
}
gotoxy(hout, framex + wide * 2 + 5, framey + 3);
printf("使用方向键或WASD移动");
gotoxy(hout, framex + wide * 2 + 5, framey + 5);
printf("长按方向键可加速");
gotoxy(hout, framex + wide * 2 + 5, framey + 7);
printf("按任意键暂停,方向键继续");
gotoxy(hout, framex + wide * 2 + 5, framey + 9);
printf("按E键回到主菜单");
//打印上边框
for (i = 0 ; i < wide * 2 + 1 ; i++) {
gotoxy(hout, framex + i, framey);
printf("*");
}
//打印下边框
for (i = 0 ; i < wide * 2 + 2 ; i++) {
gotoxy(hout, framex + i, framey + high);
printf("*");
}
//打印左边框
for (i = 0 ; i < high ; i++) {
gotoxy(hout, framex, framey + i);
printf("*");
}
//打印右边框
for (i = 0 ; i < high ; i++) {
gotoxy(hout, framex + wide * 2 + 1, framey + i);
printf("*");
}
}
//游戏信息
void infor(HANDLE hout, struct Snake* snake) {
gotoxy(hout, framex + wide * 2 + 5, framey + 15);
printf("当前速度:%d", snake->speed);
gotoxy(hout, framex + wide * 2 + 5, framey + 17);
printf("当前得分:%d", snake->count);
gotoxy(hout, framex + wide * 2 + 5, framey + 19);
printf("当前长度:%d", snake->length);
gotoxy(hout, framex + wide * 2 + 5, framey + 21);
printf("已用时间:%02d:%02d:%02d", CLK / 60 / 60, CLK / 60, CLK % 60);
}
//选择游戏难度
void selectcover(HANDLE hout, struct Snake *snake) {
gotoxy(hout, framex + wide, framey);
printf("请选择游戏难度:\n");
printf("\t1.初级\n\n");
printf("\t2.中级\n\n");
printf("\t3.高级\n\n");
printf("\t4.挑战\n");
char s = _getch();
if (s == '1')
{
HEIGHT_POINTS = 10;
snake->speed = 400;
snake->delay = 400;
snake->mode = 1;
}
else if (s == '2')
{
HEIGHT_POINTS = 20;
snake->speed = 450;
snake->delay = 350;
snake->mode = 2;
}
else if (s == '3')
{
HEIGHT_POINTS = 40;
snake->speed = 500;
snake->delay = 300;
snake->mode = 3;
}
else if (s == '4')
{
HEIGHT_POINTS = 100;
snake->speed = 600;
snake->delay = 200;
snake->mode = 4;
}
else
{
gotoxy(hout, framex + wide, framey + 11);
printf("\n\t输入错误!请重新输入。");
Sleep(1000);
system("cls");
selectcover(hout, snake);
}
system("cls");
}
//初始化蛇
void initsnake(struct Snake *snake) {
snake->x[0] = framex + 2;
snake->y[0] = framey + high / 2;
snake->count = 0;
snake->length = 3;
//snake->speed = 400;
//初始化由蛇尾至蛇头的坐标
for (i = 1 ; i < snake->length ; i++) {
snake->x[i] = snake->x[i-1] + 1;
snake->y[i] = snake->y[i-1];
}
}
//打印蛇
void printsnake(HANDLE hout, struct Snake *snake) {
for (i = 0 ; i < snake->length ; i++) {
gotoxy(hout, snake->x[i], snake->y[i]);
if (i == snake->length-1)
printf("@");
else
printf("*");
}
}
//移动蛇
void movesnake(HANDLE hout, struct Snake *snake) {
gotoxy(hout, snake->x[0], snake->y[0]);
//清除蛇尾
printf(" ");
//蛇的后一节坐标变成前一节的坐标
for (i = 1 ; i < snake->length ; i++){
snake->x[i-1] = snake->x[i];
snake->y[i-1] = snake->y[i];
}
}
//打印食物
void printfood(HANDLE hout, struct Snake *snake, struct Food* food) {
//用计算机时间获取随机值
srand((unsigned)time(NULL));
while (1) {
//将食物的横纵坐标的大小限定在窗口大小内
food->x = rand() % (wide - 2) + 1;
food->y = rand() % (high - 2) + 1;
//避免食物出现在边框上
if (food->x == 0 && food->y == 0)
continue;
//将食物的坐标放置在窗口内
food->x = 2 * food->x + framex;
food->y += framey;
//如果食物出现在蛇上,重新产生食物
for (i = 0 ; i < snake->length; i++) {
if(food->x == snake->x[i] && food->y == snake->y[i])
break;
}
//食物不在蛇上,打印食物,结束循环
if (i == snake->length) {
gotoxy(hout, food->x, food->y);
printf("#");
break;
}
}
}
//吃食物
void eatfood(HANDLE hout, struct Snake * snake, struct Food *food) {
//如果蛇头的坐标等于食物的坐标
if (snake->x[snake->length - 1] == food->x && snake->y[snake->length - 1] == food->y) {
//蛇长加一
snake->length++;
//蛇身(不包括蛇尾)整体像前移动一格
for (i = snake->length - 1 ; i > 0 ; i--) {
snake->x[i] = snake->x[i - 1];
snake->y[i] = snake->y[i - 1];
}
//得到蛇尾的坐标(即蛇移动前的蛇尾坐标)
snake->x[0] = a[0];
snake->y[0] = a[1];
printfood(hout, snake, food);
snake->count++;
if (snake->count % 3 == 0)
snake->speed -= 50;
}
}
//死亡判断
int ifdead(struct Snake* snake) {
//如果碰到左边界 返回0;
if (snake->x[snake->length - 1] == framex)
return 0;
//如果碰到右边界 返回0;
if (snake->x[snake->length - 1] == framex + wide * 2)
return 0;
//如果碰到上边界 返回0;
if (snake->y[snake->length - 1] == framey)
return 0;
//如果碰到下边界 返回0;
if (snake->y[snake->length-1] == framey + high)
return 0;
//如果碰到自己身体 返回0;
for (i = 0 ; i < snake->length - 1 ; i++)
if(snake->x[snake->length - 1] == snake->x[i] && snake->y[snake->length - 1] == snake->y[i])
return 0;
//否则返回1;
return 1;
}
//获取时间
void gettime()
{
while (1)
{
::CLK++;
Sleep(1000);
}
}
//开始游戏
int play(HANDLE hout) {
system("cls");
unsigned char ch = 77;
struct Snake s, *snake = &s;
struct Food f, *food = &f;
selectcover(hout, snake);
makeframe(snake);
initsnake(snake);
printfood(hout, snake, food);
Sleep(500);
CLK = 0;
HANDLE hThread;
DWORD ThreadID;
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)gettime, NULL, 0, &ThreadID);
while (1) {
infor(hout, snake);
//保存蛇尾横纵坐标
a[0] = snake->x[0];
a[1] = snake->y[0];
j = 0;
//如果用户敲击键盘
if (kbhit()) {
//用ch接收输入 ,注意是getch(),不需敲击回车
ch = getch();
if (kbhit()) {
//长按时间
Sleep(20);
j = 1;
}
}
switch(ch) {
//向上移动