/********************************************************************************
* @File name: main.c
* @Description: 用于详细说明此程序文件完成的主要功能
* @ Function List: void drawMap(); //绘制游戏边框
void createFood(); //随机生成食物
void keyDown(); //按键操作
bool snakeStatus(); //判断蛇的状态
void getxy(int x, int y); //从控制台移动光标
* @Author: 王成军
* @Version: 1.1
* @Date: 2019-12-05
* @History: 修改历史记录列表,应包括修改日期、修改者及修改内容简述(可有可无)。
********************************************************************************/
#include
#include
/*stdlib.h里面定义了五种类型,一些宏和通用工具函数类型例如为size_t,wchar_t的,div_t,ldiv_t和lldiv_t;宏例如EXIT_FAILURE,EXIT_SUCCESS RAND_MAX和MB_CUR_MAX等等;
常用的函数如malloc(),calloc(),realloc(),free(),system(),atoi(),atol(),rand(),srand(),exit()等。可以打开编译器的包括目录里面的stdlib.h头文件查看。
*/
#include
#include
#include
#include
#define snakesize 100 //蛇的最大身体长度
#define mapheigt 26 //地图的高度
#define mapwidth 75 //地图的宽度
int key = 72; //表示蛇移动的方向,72为按下“↑”所代表的数字
int changeFlag = 0; //用来判断蛇是否吃掉了食物,
int sorce = 0; //记录玩家的得
void drawMap(); //绘制游戏边框
void createFood(); //随机生成食物
void keyDown(); //按键操作
bool snakeStatus(); //蛇的状态
void getxy(int x, int y); //从控制台移动光标
void gameEnd();
void creatInterface(); //功能菜单
struct //定义食物结构体
{
int x;
int y;
int c;
}food;
struct //定义蛇结构体
{
int speed;
int len;
int x[snakesize];
int y[snakesize];
}snake;
/*******************************************************
*
* Function name :set_color(int x)
* Description : 修改颜色
* Parameter :
* @STD_OUTPUT_HANDLE 标准输出的句柄
* Return :无
SetConsoleTextAttribute是一个可以在API(应用程序编程接口)中设置控制台窗口字体颜色和背景色的计算机函数
该函数被广泛应用于电脑编程与软件开发中。
**********************************************************/
void set_color(int x)
{
HANDLE winHandle;
winHandle = GetStdHandle((STD_OUTPUT_HANDLE)) ;//用来修改命令行窗口的颜色
SetConsoleTextAttribute(winHandle,x) ;
}
/*******************************************************
*
* Function name : getxy()
* Description : 函数功能描述
* Parameter :int x,int y
* @x 表示光标的x坐标值
* @y 表示光标的y坐标值
*
* Return :无
*COORD是Windows API中定义的一种结构,表示一个字符在控制台屏幕上的坐标。
其定义为:
typedef struct _COORD {
SHORT X; // horizontal coordinate
SHORT Y; // vertical coordinate
} COORD;
**********************************************************/
void getxy(int x,int y)
{
COORD get;
get.X=x;
get.Y=y;
GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), get);
/*句柄: 在windows程序中,有各种各样的资源(窗口、图标、光标等),系统在创建这些资源时会为他们分配内存,
并返回标示这些资源的标示 。*/
}
/*******************************************************
*
* Function name : drawMap()
* Description ://绘制游戏边框,定义蛇的移动
* Parameter :int i 局部变量 用于循环
* @i 用于循环时打印墙体,和蛇
* @参数名2 参数说明
* @参数名3 参数说明
* Return :函数返回值的说明
**********************************************************/
void drawMap() //绘制地图
{
int i;
for(i=0;i {
getxy(i,0);
printf(“■”);
set_color(3);
getxy(i,mapheigt);
printf(“■”); //将光标移动依次到(i,mapheight)处打印下边框
set_color(2);
}
for ( i = 0; i {
getxy(0, i); //将光标移动依次到(0,i)处打印左边框
printf(“■”);
set_color(14);
}
for ( i = 0; i { getxy(mapwidth-1, i);//将光标移动依次到(mapwidth i)处打印左边框
printf(“■”);
set_color(14);
}
while(1)
{
srand((unsigned int)time(NULL)); //srand函数是随机数发生器的初始化函数。原型:void srand(unsigned int seed);srand和rand()配合使用产生伪随机数序列。
food.x = rand() % (mapwidth – 4) + 2;
food.y = rand() % (mapheigt – 2) + 1;
if (food.x % 2 == 0)
break;
}
getxy(food.x,food.y); 将光标移到食物的坐标处打印食物
set_color(3);
printf(“★”);
snake.len = 3; // 初始化蛇的属性
snake.speed = 200;
snake.x[0] = mapwidth / 2 + 1;//x坐标为偶数
snake.y[0] = mapheigt / 2;
getxy(snake.x[0], snake.y[0]);
set_color(4);
printf(“■”); //打印蛇头
for ( i = 1; i {
snake.x[i] = snake.x[i – 1] + 2; //蛇身的打印,纵坐标不变,横坐标为上一节蛇身的坐标值+2
snake.y[i] = snake.y[i – 1];
getxy(snake.x[i], snake.y[i]);
set_color(14);
printf(“■”);
}
getxy(mapwidth – 2, 0);
return;
}
/*******************************************************
*
* Function name :void keyDown()
* Description : 判断键盘是否有键按下
* Parameter : pre_key
* @ pre_key 获取按下的键盘值
* @参数名2 参数说明
* @参数名3 参数说明
* Return :无
*kbhit()是一个C和C++函数,用于非阻塞地响应键盘输入事件。其中文可译为“键盘敲击”(keyboard hit)。
getch()是编程中所用的函数,这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性!
getch()读取方向键的时候,会返回两次,第一次调用返回0或者224,第二次调用返回的才是实际值
**********************************************************/
void keyDown()
{
int pre_key=key;
if (kbhit())//判断按下了键盘中的某个键
{
fflush(stdin);//清空缓冲区的字符
key = getch();
key = getch();
}
if (changeFlag == 0)
{
getxy(snake.x[snake.len – 1], snake.y[snake.len – 1]);
printf(” “); //在蛇尾处输出空格即擦去蛇尾
}
for (int 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;
}
getxy(snake.x[0], snake.y[0]);
printf(“■”);
set_color(9);
getxy(mapwidth- 2, 0);
changeFlag = 0; //由于目前没有吃到食物,changFlag值为0
return;
}
/*******************************************************
*
* Function name :createFood()
* Description : 随机创造食物
* Parameter :
* @flag 判断蛇是否吃到食物
* @
* 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() % (mapheigt – 2) + 1;
food.c=rand()%15;
for (int i = 0; i {
if (snake.x[i] == food.x && snake.y[i] == food.y)
{
flag = 0;
break;
}
}
if (flag && food.x % 2 == 0) //随机生成的食物不能横坐标为奇数,也不能在蛇身,否则重新生成
break;
}
getxy(food.x, food.y); //绘制食物
printf(“★”);
set_color(food.c);
snake.len++;//吃到食物,蛇身长度加1
sorce += 10;//每个食物得10分
snake.speed -= 5;//随着吃的食物越来越多,速度会越来越快
changeFlag = 1;//很重要,因为吃到了食物,就不用再擦除蛇尾的那一节,以此来造成蛇身体增长的效果
}
return;
}
/*******************************************************
*
* Function name :snakeStatus()
* Description : 判断蛇致死的情况
* Parameter :
* @ false bool蛇进行了违规操作
* @ true bool蛇进行了违规操作
* Return :无
**********************************************************/
bool snakeStatus()
{
if (snake.y[0] == 0 || snake.y[0] == mapheigt) //蛇头碰到上下边界,游戏结束
return false;
if (snake.x[0] == 0 || snake.x[0] == mapwidth)//蛇头碰到左右边界,游戏结束
return false;
for (int i = 1; i {
if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
return false;
}
return true;
}
bool snakel() //改写后的程序会出现蛇能闯过右边墙体不死的情况此函数进行纠正
{
if(snake.x[0]>=74)
return false;
}
/*******************************************************
*
* Function name :welcomePage( )
* Description : 游戏的进入菜单
* Parameter :
* @ 无
* @ 无
* Return :无
**********************************************************/
void welcomePage( )
{
getxy(35,2);
printf(“欢迎来到贪吃蛇”);
set_color(1);
getxy(15, 5);
printf(“游戏规则”);
set_color(2);
getxy(15, 7);
printf(“1. 用↑,↓,←,→,来控制方向”);
set_color(3);
getxy(15, 9);
printf(“2. 撞到自己蛇会死 “);
set_color(11);
getxy(15, 11);
printf(“3.撞到墙蛇会死 “);
set_color(4);
getxy(15, 13);
printf(“4.吃到食物增加积分”);
set_color(4);
getxy(15, 15);
printf(“祝你游戏愉快”);
set_color(10);
getxy(28, 23);
printf(“Press any key to continue…”);
getxy(0, 28);
getchar();
system(“cls”); //system(“CLS”) 是在C语言程序中,调用系统命令cls完成清屏操作。
}
/*******************************************************
*
* Function name :gameEnd()
* Description : 游戏的结束菜单
* Parameter :在游戏结束后用一页显示玩家的分数
* @ 无
* @ 无
* Return :无
**********************************************************/
void gameEnd()
{
system(“cls”);
getxy(32, 14);
printf(“Your final score is %d”, sorce);
getchar();
getxy(0, 25);
exit(0);
}
/*******************************************************
*
* Function name :creatInterface()
* Description : 绘制游戏旁菜单
* Parameter :
* @ str_title 游戏标题
* @ title_pos 光标起始位置
* Return :无
**********************************************************/
void creatInterface( )
{
getxy(78, 2);
printf(“Score:”);
set_color(1);
getxy(78, 4);
printf(“Score Per Food:”);
set_color(3);
getxy(82, 6);
printf(“介 绍”);
set_color(3);
getxy(78,8);
printf(“↑.向上移动.”);
set_color(4);
getxy(78,10);
printf(“↓.向下移动.”);
set_color(12);
getxy(78,12);
printf(“←.向左移动.”);
getxy(78,14);
printf(“→.向右移动.”);
set_color(15);
getxy(78,16);
printf(“SpacetGame pause.”);
set_color(3);
getxy(78, 18);
printf(“ESCtQuit the game.”);
set_color(11);
getxy(78, 20);
printf(“@.王成军”);
set_color(15);
}
/*******************************************************
*
* Function name :main()
* Description : 驱动整个程序
* Parameter :
* @ 无
* @无
* Return :0
Sleep函数可以使计算机程序(进程,任务或线程)进入休眠,使其在一段时间内处于非活动状态。
当函数设定的计时器到期,或者接收到信 、程序发生中断都会导致程序继续执行。
**********************************************************/
int main()
{ welcomePage();
drawMap();
creatInterface();
while (1)
{
keyDown();
if (!snakeStatus()) //判死操作
break;
if(!snakel()) //判死操作
break;
createFood();
Sleep(snake.speed);
getxy(86, 2);
printf(“%d”, sorce);
getxy(94, 4);
printf(“%d “,sorce/10);
}
gameEnd();
return 0;
}
文章知识点与官方知识档案匹配,可进一步学习相关知识算法技能树首页概览35168 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!