//
#include<stdio.h>
//键盘敲击
#include <conio.h>
//屏幕渲染周期,clock函数
#include <time.h>
//
#include <stdlib.h>
//刷新周期,控制游戏速度
#define Period 100
//地图宽度
#define _width 25
//地图高度
#define _height 18
//点 结构
typedef struct point
{
int x;
int y;
};
//----------------全局变量----------------
//地图数组
char g_map[_height][_width];
//蛇长度,初始化为两个
int g_snakeLen = 2;
//蛇:一系列点
struct point g_snake[(_width - 1)*(_height - 1)] = { { _height / 2, _width / 2 }, { 1, 1 } };
//食物坐标
struct point g_food;
//----------------函数声明----------------
//欢迎界面
void Welcome();
//置字符
void SetChars();
//设置食物
void ResetFood();
//处理蛇移动
int JugeSnake(char c);
//空格填充
void Padding(int =0);
//--------------------------------------
int main()
{
//当前时间,上一次刷新时间,单位为ms(毫秒)
long timeNow, timeLast = 0;
int i, j,//计数变量
keyLast = 'd',
keyNow = 'd';
//显示欢迎界面
Welcome();
//置随机数种子
srand((unsigned)time(NULL));
//初始化食物位置
ResetFood();
do
{
//***********************渲染开始***********************
//获取当前时间
timeNow = clock();
//判断是否满足刷新条件
if (timeNow - timeLast >= Period)
{
//记录本次刷新时间
timeLast = clock();
//清屏
system("cls");
//1. 显示图像
//----------------初始化地图界面----------------
for (i = 0; i<_height; i++)
{
for (j = 0; j<_width; j++)
{
g_map[i][j] = ' ';
if (i == 0 || i == _height - 1 || j == 0 || j == _width - 1)
g_map[i][j] = '*';
}
}
//----------------初始化地图界面----------------
//空格填充
Padding(-10);
printf("----------当前长度%d,已游戏时间%ds-----------\n", g_snakeLen, timeNow / 1000);
int resJuge = JugeSnake(keyLast);
//此处若用switch,则不能跳出最外层的do-while循环
//为了避免用goto语句,所以用if-else处理juge结果
if (resJuge == 0)
{
printf("游戏结束!");
break;
}
else if (resJuge == 2)
{
printf("恭喜你打穿游戏了!");
break;
}
SetChars();
for (i = 0; i<_height; i++)
{
//空格填充
Padding();
for (j = 0; j<_width; j++)
{
printf("%c", g_map[i][j]);
}
if (i<_height - 1)
printf("\n");
}
}
//2. 处理键盘事件
if (kbhit() == 1)
{
//
keyNow = getch();
if (keyNow == 'd'&&keyLast == 'a')
keyLast = 'a';
else if (keyNow == 'a'&&keyLast == 'd')
keyLast = 'd';
else if (keyNow == 'w'&&keyLast == 's')
keyLast = 's';
else if (keyNow == 's'&&keyLast == 'w')
keyLast = 'w';
else
{
keyLast = keyNow;
}
}
//***********************渲染结束***********************
} while (1);
system("pause");
}
//
//判断 蛇的移动 并 处理 移动效果
//
int JugeSnake(char c)
{
int i;
int x, y;//目标位置
struct point last;
last = g_snake[g_snakeLen - 1];//记录移动前的尾巴位置
x = g_snake[0].x;
y = g_snake[0].y;
switch (c)
{
case 'w':case 'W':
x--;
break;
case 's':case 'S':
x++;
break;
case 'a':case 'A':
y--;
break;
case 'd':case 'D':
y++;
break;
}
//在这里说明移动成功了
if (x <= 0 || x >= _height - 1)
return 0;
if (y <= 0 || y >= _width - 1)
return 0;
for (i = g_snakeLen - 1; i>0; i--)//除头以外都移动
g_snake[i] = g_snake[i - 1];
//动完之后判断目标位置和移动后的躯体是否重合
for (i = 1; i<g_snakeLen; i++)
{
if (g_snake[i].x == x&&g_snake[i].y == y)
return 0;//重合就撞了,撞了就GG了
}
//没GG。。。
g_snake[0].x = x;
g_snake[0].y = y;
if (g_snake[0].x == g_food.x &&g_snake[0].y == g_food.y)//卧槽吃到食物了
{
g_snakeLen++;
g_snake[g_snakeLen - 1] = last;
ResetFood();
}
if (g_snakeLen == (_width - 1)*(_height - 1))
return 2;
return 1;
}
//
//设置蛇的字和食物字符
//
void SetChars()
{
int i;
g_map[g_snake[0].x][g_snake[0].y] = 'M';
for (i = 1; i<g_snakeLen; i++)
g_map[g_snake[i].x][g_snake[i].y] = 'm';
g_map[g_food.x][g_food.y] = 'O';
}
//
//重置食物位置
//
void ResetFood()
{
do
{
g_food.x = rand() % _height;
g_food.y = rand() % _width;
} while (g_food.x == 0 || g_food.x == _height - 1 || g_food.y == 0 || g_food.y == _width - 1);
}
//
//欢迎界面
//
void Welcome()
{
Padding(-10);printf("欢迎来到贪吃世界!\n");
Padding(-10);printf("上下左右为wsad键(请调整输入法),感受这款经典游戏带来的快感吧!\n");
Padding(-10);printf(" 长沙理工大学 何健伟 QQ:296036136\n");
system("pause");
}
//
//显示一定数量的空格
//参数1:相对偏移
void Padding(int shift)
{
int total=20;
total+=shift;
for(int i=0;i<total;i++)
{
putchar(' ');
}
}