在上一篇文章中我们已经对于需要用到的知识点进行了讲解,那么本篇文章不说废话,直接带着大家实现贪吃蛇小游戏!
关于部分win32API相关知识有不了解的,可以看上面这篇文章,该文章对于贪吃蛇小游戏中一些不太常用的函数有一定的讲解,希望可以帮助到大家!
目录
1.贪吃蛇游戏的大致流程
该游戏具体玩法是:用游戏把子上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,否则判定为游戏结束。
2.游戏实现的大致思路
还记得我在猜数字游戏的实现中说过的一句话吗?没错,我们在写编程题或者小游戏代码时,最重要的就是理清实现思路——主体是什么?为了实现目的要创建哪些函数?函数的功能都是什么?只有当我们心中有了一个大体的框架,知道该做些什么时,我们才能更高效地编写代码,完成程序设计。而本游戏我们不难看出无非还是常规游戏的大体框架:先展示菜单,由玩家选择是否进行游戏,然后根据其选择进行游戏或者退出程序,再完成一轮游戏后再次询问。(不过,这里为了省事,首次的菜单询问被省略了,具体大家可以根据需求进行添加)当然由于本游戏game部分过于复杂,所以在这里也是将其分解为,游戏开始、游戏进行、游戏结束三大部分,三大函数。
所以大体框架代码如下:
void test()
{
int ch = 0;
srand((unsigned int)time(NULL));
do
{
Snake snake = { 0 };
GameStart(&snake);
GameRun(&snake);
GameEnd(&snake);
SetPos(20, 15);
printf("再来一局吗?(Y / N) :");
getchar();
ch = getchar();
getchar();//清理\n
} while (ch == 'Y' || ch == 'y');
SetPos(0, 27);
}
int main()
{
//修改当前地区为本地模式,为了⽀持中⽂宽字符的打印
setlocale(LC_ALL, "");
//测试逻辑
test();
return 0;
}
具体是否创建test函数包括这些基本成分没有强制要求。
3.对象属性配置
由于本游戏的操作对象是蛇,而对于蛇本身我们需要用多种数据类型才能说明其属性,所以我们就要用到结构体类型。
在任何一门语言中,我们都有专门用来描述一个对象自身属性的自定义类型,在C语言中即是结构体,而在C++中则升级为了更为高级的类。那么在C语言中,我们就用结构体来记录蛇的信息。
代码如下:
//蛇⾝节点
typedef struct SnakeNode
{
int x;
int y;
struct SnakeNode* next;
}SnakeNode, * pSnakeNode;
typedef struct Snake
{
pSnakeNode _pSnake;//维护整条蛇的指针
pSnakeNode _pFood;//维护食物的指针
enum DIRECTION _Dir;//蛇头的方向默认是向右
enum GAME_STATUS _Status;//游戏状态
int _Socre;//当前获得分数
int _Add;//默认每个食物10分
int _SleepTime;//每⾛一步休眠时间
}Snake, * pSnake;
4.各部分功能的具体实现
4.1GameStart函数
void GameStart(pSnake ps)
{
//设置控制台窗⼝的⼤⼩,30⾏,100列
//mode 为DOS命令
system("mode con cols=100 lines=30");
//设置cmd窗⼝名称
system("title 贪吃蛇");
//获取标准输出的句柄(⽤来标识不同设备的数值)
HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//影藏光标操作
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息
CursorInfo.bVisible = false; //隐藏控制台光标
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态
//打印欢迎界⾯
WelcomeToGame();
//打印地图
CreateMap();
//初始化蛇
InitSnake(ps);
//创造第⼀个⻝物
CreateFood(ps);
}
在游戏开始的函数中我们需要实现最基本的一些功能,以确保棋盘的形式和布置是我们所想要的,以下是我们应该在该部分实现的函数:
void HideCursor();//隐藏光标
void Setpos(int x, int y);//光标位置调整
void WelcomeToGme();//打印欢迎界面
void CreateMap();//创建地图
void InitSnake(pSnake snake);//初始化蛇并在出生点打印出蛇
void CreateFood(pSnake snake);//设置第一个食物
4.1.1隐藏光标函数HideCursor
void HideCursor()//隐藏光标
{
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);// 获取输出设备句柄
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(houtput, &CursorInfo);//获取光标属性信息
CursorInfo.bVisible = false;//调整属性隐藏光标
SetConsoleCursorInfo(houtput, &CursorInfo);//重置光标属性
}
4.1.2光标位置调整函数Setpos
void Setpos(int x, int y)//光标位置调整
{
HANDLE houtput = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos = { x,y };
SetConsoleCursorPosition(houtput, pos);
}
4.1.3打印欢迎界面函数WelcomeToGme
void WelcomeToGame()
{
SetPos(50, 15);
printf("欢迎来到贪吃蛇小游戏");
SetPos(50, 25);//让按任意键继续的出现的位置好看点
system("pause");
system("cls");
SetPos(40, 12);
printf("用↑.↓.←.→分别控制蛇的移动,F3为加速,F4为减速\n");
SetPos(40, 13);
printf("加速将能得到更高的分数。\n");
SetPos(40, 25);//让按任意键继续的出现的位置好看点
system("pause");
system("cls");
}
4.1.4创建地图函数CreateMap
void CreateMap()
{
int i = 0;
//上(0, 0) - (56, 0)
SetPos(0, 0);
for (i = 0; i <= 56; i += 2 )
{
wprintf(L"%c ", WALL);
}
//下(0, 26) - (56, 26)
SetPos(0, 26);
for (i = 0; i <= 56; i += 2)
{
wprintf(L"%c ", WALL);
}
//左
//x是0,y从1开始增⻓
for (i = 1; i < 26; i++)
{
SetPos(0, i);
wprintf(L"%c", WALL);
}
//x是56,y从1开始增⻓
for (i = 1; i < 26; i++)
{
SetPos(56, i);
wprintf(L"%c", WALL);
}
}
具体大家根据情况进行修改代码,美观即可。
4.1.5初始化蛇并打印出生点蛇函数InitSnake
void InitSnake(pSnake ps)
{
pSnakeNode cur = NULL;
int i = 0;
//创建蛇身节点,并初始化坐标
/