贪吃蛇小程序,主要采用C语言描述,采用数组进行数据存储的图形化操作界面,会涉及一点点C++ 知识(特别少的一点点),但是有C语言基础就够用了,编译器:VS2015,会涉及部分库函数的安装及使用,我会在文章中给出详细的安装方法和解决方案。

文章目录

文章目录

前言

一、话不多述,先看游戏效果

二、实现步骤

1.新建工程文件及引入库函数

2.框架设计和代码实现

实现设想:

1.游戏界面

2.绘制游戏元素

3.获取按键信息

4.操作贪吃蛇(重点)

5.贪吃长大

6.判断游戏结束

配乐:

总结


前言

在学习C语言的过程中,用小游戏来提高自己的代码实现能力是很不错的,贪吃蛇小程序可以在学习完数组的相关知识后有了一定的代码基础就可以尝试了,由于本游戏采用了图形化界面,可以作为平时的大作业和操作练手,下面我将带着用C语言写一个贪吃蛇小程序,包含图形界面和背景音乐,主要使用数组来实现数据存储,我使用的是VS2015,关于代码兼容性的问题,我会提及并解释,关于各种操作的原理和函数的调用,我会给出详细的解释和参考来源,对小白及其友好,下面,让我们开始吧!

一、话不多述,先看游戏效果

请原谅我那手残的操作 ε=(´ο`*))),(视频是有背景音乐的,但是由于视频不好上传,就只上传了GIF)

贪吃蛇效果

不过可以看到,实现效果还是不错的嘛,对于基本的按键操作都有很好的应对,并且在边界是可以自由穿过和穿出的,一定程度上降低了游戏难度,并且这里我设置的是半秒钟的延迟,对我来说已经比较快了,希望你们可以挑战更高的难度 ε≡٩(๑>₃<)۶

二、实现步骤

1.新建工程文件及引入库函数

新建文件:基本的新建文件及关闭安全检查在这里我就不提了,如果需要可以参考往期博文:如何关闭VS安全检查—三种方法

这里唯一要注意的是在添加文件时要添加 C++ 文件,而不是C文件,因为有使用easyx,必须是C++ 文件,具体细节可以参考EasyX说明文档,这是链接:easyx说明文档

引入库函数:因为我要进行的是图形操作,所以就会设计图形化的库函数引用,可以在VS编译器中是没有预装的,就可以自己选择安装了,这里我也有写过,可以参考往期博文:easyx等图形化库函数的使用

好了,截止目前,我们要做的前期工作就基本完成了,下面要做的就是构建实现框架,编写代码了!(σ゚∀゚)σ..:*☆

2.框架设计和代码实现

实现设想:

首先要有一个图形化的游戏界面,而不一个简单的操作台,也就是我们为什么要在上面要安装easyx了,我所设想的操作界面的大小是640*480的一个矩形,蛇体本身用方形表示,以10*10为基础构成,初始状态为三节的长度,没吃到一个 食物 ,身体长度就增加一节,并且蛇的操作是由方向键控制的,就需要在图形化界面里获取按键信息,并且要可以实时获得蛇的位置信息,我所设计的是可以穿过边界,并在另一侧出现,这样可以减少游戏难度,并且蛇的身体是要不断增加的,在这里我采用的是用数组来实现蛇的身体的增加,每吃到一个食物,将让该数组的长度加一,下面就让我们开始一步一步的实现这些设想吧。

1.游戏界面

首先就是要先实现这有640*480的游戏界面了,我选择定义了两个常量来存储这个数值,并且一起定义了蛇的最大长度在100

#define WIN_WIDTH 640
#define WIN_HEIGHT 480
#define MAX_SNAKE 100  //蛇的最大节数

然后就是初始化一个游戏界面了,initgraph 函数的作用就是产生一个图形化的窗口,参数分别是宽度、高度、属性。

具体可以参考说明文档:initgraph 说明文档

initgraph(WIN_WIDTH,WIN_HEIGHT,SHOWCONSOLE);//初始化一个图形窗口//具体参数见:https://docs.easyx.cn/zh-cn/initgraphprintf("\tWelcome! \n");printf("\tPlay Game Right Now!\n");

然后就是要设置蛇 的参数,并初始化各个元素了,在这里我使用的是数组来存储蛇的信息,其中就包括了蛇的长度,并且需要实时记录蛇头的方向(方便操作)和位置信息,还需要的就是要统计得分使用的分数了,下面是蛇的结构体:关于其详细的解释,我都写在注释里了关于 POINT 结构体,这个是属于库的结构体,可以直接使用。

struct Snake_tlg  //蛇的结构体
{int num;  // 身体的长度int dir;  //蛇的方向int score;  //分数int size;  //蛇的尺寸,身体和高度POINT coor[MAX_SNAKE];  //蛇的位置坐标。一个结构体数组//POINT 也时一个结构体,,可以通过选中转到定义来查看其具体结构,是在 windef.h中的/*typedef struct tagPOINT{LONG  x;LONG  y;} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;*/}snake;

除了蛇的结构体,还要有食物的结构体,我们要记录食物的位置,以及食物是否存在,就是在蛇吃过它之后,它就要消失,并且可以继续产生新的食物,而且这里我还定义了食物的颜色信息,这样可以每次都产生一个不同颜色的食物,具体的实现我会放在 对应的代码中,下面是它的结构体:

struct Food_tlg  //食物的出现 结构体
{POINT fd;  //食物的坐标int flag;  //是否已经被蛇吃掉DWORD color;  //定义食物的颜色/*在DirectX程序中有些地方用DWORD(RGBA)格式表示颜色,其范围是[0 - 255]*/
}food;

下面就可以初始化各个游戏元素了,详细的注释我都放在代码里了,这里有一点是关于随机函数的问题,这里使用的是时间来产生随机值的,随机函数的具体使用,我在这个博客的注释中有解释过:三子棋游戏的操作实现_小鸡在啄米的博客-CSDN博客

rand 函数需要头文件<stdlib.h>,要保证每次产生的随机数都不同,就要借用srand,使用当前时间的毫秒数 来作为种子数,产生随机数

void GameInit()
{srand((unsigned int)time(NULL));   //time 的头文件是 time.h//定义蛇snake.num = 3;  //定义蛇初始有三节身体snake.dir = RIGHT;  //开始时蛇头向右snake.score = 0;  //开始时分数为0snake.size = 10;  //初始化蛇的身体大小snake.coor[2].x = 0;  //第三节身体(尾巴)的坐标snake.coor[2].y = 0;  // 由于初始化时就是在左上角的一个长条,所以y都是0snake.coor[1].x = 0+snake.size;  // 蛇的第二节(身体的坐标snake.coor[1].y = 0;snake.coor[0].x = 0+2*snake.size;  //蛇头,即第一节身体snake.coor[0].y = 0;//初始化食物food.fd.x = rand() % (WIN_WIDTH/10)*10;  //取模确保产生的随机值在范围内food.fd.y = rand() % (WIN_HEIGHT/10)*10;
//这里要先对10取商,再乘10是为了产生一个10的倍数,可以让蛇头和食物接触到,而不是每次都是一个随机数,无法判断food.flag = 1;  //初始化食物存在food.color = RGB(rand() % 256, rand() % 256, rand() % 256);//随机产生食物颜色}

在初始化基本完成之后,我们就可以进行下面的游戏操作了。

2.绘制游戏元素

关于这一块,主要是对游戏初始的一些设置,这里有个小心机就是在设置舌头的时候要用数组的第一个元素来保存,因为蛇头一定是不变的,永远都是在蛇尾变化,在这里我设置蛇在初始时是三个方块的大小,可以随着吃到食物的个数,随着变化。

设置食物的时候,可以通过绘制函数来绘制其他形状的食物,并且由于我之前在定义食物结构体的时候,有单独定义一个颜色,所以在这里食物的颜色是可以随机变化的,当然了每次的位置也是随机变化的

在设置分数的时候,会设计一个像图形界面输出的文字的问题,当时我按照教程编写的时候,总是无法正常的输出显示,很苦恼,最后在参考了这篇文章才成功解决,博主写的超级详细,很感激(〃'▽'〃),这里贴一下我参考的地址: https://codeabc.cn/yangw/a/error-c2665

所以在本代码中,我参考的是博主的第二个建议,在代码的顶端加上这两句代码,完美解决!!

#undef UNICODE
#undef _UNICODE
void GameDraw()
{setbkcolor(RGB(105, 160, 141));  //设置背景颜色,与web开发中的颜色设置一样cleardevice();  //清除其他元素//画蛇setfillcolor(YELLOW);int i;for (i = 0; i < snake.num; i++)  //每次都画一个矩形,共三次{setlinecolor(BLACK);fillrectangle(snake.coor[i].x,snake.coor[i].y,snake.coor[i].x + snake.size,snake.coor[i].y + snake.size);/*在 easyx 中,solidrectangle 这个函数用于画无边框的填充矩形,而fillrectangle用于画有边框的填充矩形void solidrectangle(int left,int top,int right,int bottom);void solidrectangle(矩形左部 x 坐标,    矩形顶部 y 坐标,  矩形右部 x 坐标,  矩形底部 y 坐标);*///printf("%d %d\n", snake.coor[i].x, snake.coor[i].y);  //用于效验坐标,在调试时使用}//画食物if (food.flag == 1) //要确保在食物被吃完之后就消失不见{setfillcolor(food.color);  //设置食物颜色fillellipse(food.fd.x, food.fd.y, food.fd.x + 10, food.fd.y + 10);  //设置食物形状}//显示分数char temp[20] = "";sprintf(temp,"分数:%d", snake.score);//SetBkMode(TRANSPARENT);outtextxy(20, 20, temp);//关于这一部分的详细解释参见:https://codeabc.cn/yangw/a/error-c2665}

好了,到现在,我们就成功实现了游戏的初始化和准备操作,下面就可以实时的对其进行控制了

3.获取按键信息

由于我们是在图形化界面进行的操作,所以我们要获取按键信息也与控制台获取按键信息有些许不同,在这里我主要是参考了其他编程大佬的说法(其实主要是当时查完资料没有保存好网址信息(╥╯^╰╥)):在这里的是我当时的一些理解,将当引用了,如果需要的话可以再自己找一下资料看看  ψ(*`ー´)ψ加油!

可以使用win32API来获取键盘消息,相比使用字符数组来存储并转换为ASCII要快捷很多
    GetAsyncKeyState函数的使用调用,相应按键是处于按下还是弹起状态
    若函数调用成功,返回值指定了自上次调用GetAsyncKeyState以来,指定的按键是否处于按下状态,
    以及该键现在是处于按下还是弹出。如果最高位被置1,表明键被按下,

如果是最低位被置1,则表明自前次调用GetAsyncKeyState一直处于按下状态。

在这里还有一点就是因为要针对方向键来接受信息,同时还可以排除其他操作,在这里使用了枚举类型来定义四个方向,主要是可以很方便的列举四个值,如果有什么不太清楚的可以参考这里的链接:C语言枚举类型(C语言enum用法)详解

个人感觉写的已经很详细了。下面是枚举类型,在最前面定义的

enum DIR
{UP,DOWN,LEFT,RIGHT,
};

下面就是获取按键信息的主要函数了:有关的在注释中也有提及

void KeyControl()
{if (GetAsyncKeyState(VK_UP)&&snake.dir!=DOWN)//后面的条件确保了不可以进行反向操作{snake.dir = UP;}if (GetAsyncKeyState(VK_DOWN) && snake.dir != UP){snake.dir = DOWN;}if (GetAsyncKeyState(VK_LEFT) && snake.dir != RIGHT){snake.dir = LEFT;}if (GetAsyncKeyState(VK_RIGHT) && snake.dir != LEFT){snake.dir = RIGHT;}}

4.操作贪吃蛇(重点)

针对贪吃蛇的操作,主要是在蛇头上,然后蛇的身体只要依次移动到上一个位置就可以了,这样就可以实现贪吃蛇的移动效果(如果是每个的移动都和蛇头一样,那就是俄罗斯方块了),所以我们在这里我们只需要把数组中前一个元素的值 赋值 给后一个元素,就可以了:

int i;for (i = snake.num - 1; i > 0; i--)  //因为是对数组进行操作,所以这里要 -1,并且这里是i-- {snake.coor[i].x = snake.coor[i - 1].x;snake.coor[i].y = snake.coor[i - 1].y;}

下面就睡对于蛇头的操作了,从上一个函数中,我们已经获取了蛇头的信息,这里就可以用switch 语句进行匹配就可以了,在收到相应的信息就修改数组中蛇头的位置信息,并且由于我们的设定是可以穿墙的,就要让蛇在到达边界的时候立刻修改蛇头的位置,让其出现在另一侧,实现穿墙效果,下面是该函数的完整实现效果:

void SnakeMove()
{/*要操作蛇头的移动,蛇的身体随着蛇头一起运动,就是要从最后一节开始,让蛇的每一节身体都随着移动到它前一节身体的位置上*/int i;for (i = snake.num - 1; i > 0; i--)  //因为是对数组进行操作,所以这里要 -1,并且这里是i-- {snake.coor[i].x = snake.coor[i - 1].x;snake.coor[i].y = snake.coor[i - 1].y;}switch (snake.dir){case UP:snake.coor[0].y -= 10;/*这里要实现的是可以在窗口处自由进出因为记录的是蛇头方块左边的坐标,而这里我们要使蛇头在接触到边沿(是蛇头的右边)就进入下面的边界所以这里要有个+10,就是为了去掉蛇头自身的长度*/if (snake.coor[0].y +10 <= 0) {snake.coor[0].y = WIN_HEIGHT;}break; case DOWN:snake.coor[0].y += 10;if (snake.coor[0].y  >= WIN_HEIGHT){snake.coor[0].y = 0;}break;case LEFT:snake.coor[0].x -= 10;if (snake.coor[0].x + 10 <= 0){snake.coor[0].x = WIN_WIDTH;}break;case RIGHT:snake.coor[0].x += 10; if (snake.coor[0].x  >= WIN_WIDTH){snake.coor[0].x = 0;}break;default:printf("错误操作,请重新操作!"); break;}//snake.coor[0].x += 10;}

这事,我们就已经可以对蛇进行各种操作了。下面我们就可以实现吃食物的功能了。

5.贪吃长大

在设计食物这里要注意的是很重要的一点——食物的坐标,由于食物的坐标是随机产生的值, 我们可以通过取模来让其范围在游戏区域内,但是:蛇头的大小是10*10,如果坐标不是十的倍数,蛇头是无法识别并继续的,所以,这里就需要一点操作,让其直接产生在游戏区域内的,十的倍数的,我们可以先让结果取10的商,由于是整数类型,就可以舍掉其他部分,只保留整数,再乘以10就可以产生我们需要的结果了

同时,我们也要保证食物在被蛇头接触之后就要消失,所以在这里我使用的是食物的 flag值,只在flag 为0时产生新的食物,下面是这个函数的实现代码:

void EatFood()
{//判断蛇头和食物的坐标就可以了if (snake.coor[0].x == food.fd.x && snake.coor[0].y == food.fd.y&&food.flag==1){snake.num++;snake.score += 10;food.flag = 0;   //在吃完之后,就让食物不存在}if (food.flag == 0)  //当食物吃完之后就可以继续产生食物了{food.fd.x = rand() % (WIN_WIDTH / 10) * 10;  food.fd.y = rand() % (WIN_HEIGHT / 10) * 10;food.flag = 1; food.color = RGB(rand() % 256, rand() % 256, rand() % 256);}}

6.判断游戏结束

下面我们就可以判断游戏何时结束了,因为是数组存储的信息,我们就只需要判断蛇头(数组首元素)和其他身体的值有没有相等的就可以得出结论了,同时要在游戏结束时显示分数等结束信息,下面是实现代码:

void DontEatSelf()
{for (int i = 4; i < snake.num; i++){if (snake.coor[0].x == snake.coor[i].x && snake.coor[0].y == snake.coor[i].y){outtextxy(200, 200, "Game over!");_getch();  //保持停顿exit(666);}}
}

好了,到现在这个函数的各个部分的信息就已经全都实现了,最后我们就只需要在mine函数汇总设置一个死循环就可以保证一直调用这些函数了,并且在循环里要设置延迟时间,来保证游戏是可以操作的,这里我使用的是Sleep()函数,关于这个函数的具体使用,我在这个博客中有详细介绍:动画效果—时间函数

其他的时间函数我还很不了解,等到日后又机会我再学习补充(^_−)☆

下面是main函数的调用代码:

void main(void)
{initgraph(WIN_WIDTH,WIN_HEIGHT,SHOWCONSOLE);//初始化一个图形窗口printf("\tWelcome! \n");printf("\tPlay Game Right Now!\n");GameInit();  //初始化游戏元素while (1)  //使用死循环来保证可以一直游玩{{SnakeMove();t1 = t2;}t2 = GetTickCount;*/SnakeMove();  //先移动GameDraw();  //再画蛇EatFood();KeyControl(); DontEatSelf();Sleep(50);  //每次都要间隔半秒钟,才可以实时的看见,否则运行速度太快了,没法操作//同理这个操作也可以成为设置游戏难度的选项//Pause();}getchar();//用来防止 游戏窗口一闪而过closegraph();  //关闭游戏图形窗口
}

好了,到现在这个小游戏的完整效果就已经可以实现了,但是还有锦上添花的一点—— 背景音乐及音效

配乐:

这里由于我能力有限,就先只把背景音乐放上吧,这里需要两个特殊的头文件

#include <mmsyscom.h>//包含了可以播放音乐的头文件
#pragma comment(lib,"winmm.lib")//库文件

我选择在初始化那里就播放音乐(我用的是可商用的音乐素材(*^▽^*)),这里需要的函数是这两个:

mciSendString("open Carnival_De_Brazil.mp3 alias a",0,0,0);mciSendString("play a repeat",0,0,0);

如果需要其他音效的话,原理是类似的。

下面就是完整的实现代码了(包含背景音乐):

#define _CRT_SECURE_NO_WARNINGS 1
#undef UNICODE
#undef _UNICODE
/*
自己创建窗口
左上角为(0,0),横着为x轴,竖着为y轴*/#include <stdio.h>
#include <Windows.h>
#include <graphics.h>
#include <time.h>
#include <stdlib.h>#include <mmsyscom.h>//包含了可以播放音乐的头文件
#pragma comment(lib,"winmm.lib")//库文件#include <conio.h>//用宏定义了窗口的显示宽高
#define WIN_WIDTH 640
#define WIN_HEIGHT 480
#define MAX_SNAKE 100  //蛇的最大节数enum DIR
{UP,DOWN,LEFT,RIGHT,};struct Snake_tlg  //蛇的结构体
{int num;  // 身体的长度int dir;  //蛇的方向int score;  //分数int size;  //蛇的尺寸,身体和高度POINT coor[MAX_SNAKE];  //蛇的位置坐标。一个结构体数组//POINT 也时一个结构体,,可以通过选中转到定义来查看其具体结构,是在 windef.h中的/*typedef struct tagPOINT{LONG  x;LONG  y;} POINT, *PPOINT, NEAR *NPPOINT, FAR *LPPOINT;*/}snake;struct Food_tlg  //食物的出现 结构体
{POINT fd;  //食物的坐标int flag;  //是否已经被蛇吃掉DWORD color;  //定义食物的颜色/*在DirectX程序中有些地方用DWORD(RGBA)格式表示颜色,其范围是[0 - 255]*/
}food;void GameInit();  //初始化游戏元素
void GameDraw();  //创建贪吃蛇
void SnakeMove();  // 操作蛇的移动
void KeyControl();  //控制方向函数
void EatFood();  //吃食物
void DontEatSelf();  //游戏结束判断void Pause();  //游戏暂停void main(void)
{initgraph(WIN_WIDTH,WIN_HEIGHT,SHOWCONSOLE);//初始化一个图形窗口//具体参数见:https://docs.easyx.cn/zh-cn/initgraphprintf("\tWelcome! \n");printf("\tPlay Game Right Now!\n");GameInit();  //初始化游戏元素while (1)  //使用死循环来保证可以一直游玩{SnakeMove();  //先移动GameDraw();  //再画蛇EatFood();KeyControl(); DontEatSelf();Sleep(50);  //每次都要间隔半秒钟,才可以实时的看见,否则运行速度太快了,没法操作//同理这个操作也可以成为设置游戏难度的选项Pause();}getchar();//用来防止 游戏窗口一闪而过closegraph();  //关闭游戏图形窗口
}void GameInit()
{srand((unsigned int)time(NULL));   //time 的头文件是 time.h//定义蛇snake.num = 3;  //定义蛇初始有三节身体snake.dir = RIGHT;  //开始时蛇头向右snake.score = 0;  //开始时分数为0snake.size = 10;  //初始化蛇的身体大小snake.coor[2].x = 0;  //第三节身体(尾巴)的坐标snake.coor[2].y = 0;  // 由于初始化时就是在左上角的一个长条,所以y都是0snake.coor[1].x = 0+snake.size;  // 蛇的第二节(身体的坐标snake.coor[1].y = 0;snake.coor[0].x = 0+2*snake.size;  //蛇头,即第一节身体snake.coor[0].y = 0;//初始化食物food.fd.x = rand() % (WIN_WIDTH/10)*10;  //取模确保产生的随机值在范围内food.fd.y = rand() % (WIN_HEIGHT/10)*10;
//这里要先对10取商,再乘10是为了产生一个10的倍数,可以让蛇头和食物接触到,而不是每次都是一个随机数,无法判断food.flag = 1;  //初始化食物存在food.color = RGB(rand() % 256, rand() % 256, rand() % 256);//随机产生食物颜色mciSendString("open Carnival_De_Brazil.mp3 alias a",0,0,0);mciSendString("play a repeat",0,0,0);}void GameDraw()
{setbkcolor(RGB(105, 160, 141));  //设置背景颜色,与web开发中的颜色设置一样cleardevice();  //清除其他元素//画蛇setfillcolor(YELLOW);int i;for (i = 0; i < snake.num; i++)  //每次都画一个矩形,共三次{setlinecolor(BLACK);fillrectangle(snake.coor[i].x,snake.coor[i].y,snake.coor[i].x + snake.size,snake.coor[i].y + snake.size);/*在 easyx 中,solidrectangle 这个函数用于画无边框的填充矩形,而fillrectangle用于画有边框的填充矩形void solidrectangle(int left,int top,int right,int bottom);void solidrectangle(矩形左部 x 坐标,    矩形顶部 y 坐标,  矩形右部 x 坐标,  矩形底部 y 坐标);*///printf("%d %d\n", snake.coor[i].x, snake.coor[i].y);  //用于效验坐标,在调试时使用}//画食物if (food.flag == 1) //要确保在食物被吃完之后就消失不见{setfillcolor(food.color);  //设置食物颜色fillellipse(food.fd.x, food.fd.y, food.fd.x + 10, food.fd.y + 10);  //设置食物形状}//显示分数char temp[20] = "";sprintf(temp,"分数:%d", snake.score);//SetBkMode(TRANSPARENT);outtextxy(20, 20, temp);}void KeyControl()
{if (GetAsyncKeyState(VK_UP)&&snake.dir!=DOWN)//后面的条件确保了不可以进行反向操作{snake.dir = UP;}if (GetAsyncKeyState(VK_DOWN) && snake.dir != UP){snake.dir = DOWN;}if (GetAsyncKeyState(VK_LEFT) && snake.dir != RIGHT){snake.dir = LEFT;}if (GetAsyncKeyState(VK_RIGHT) && snake.dir != LEFT){snake.dir = RIGHT;}}void SnakeMove()
{/*要操作蛇头的移动,蛇的身体随着蛇头一起运动,就是要从最后一节开始,让蛇的每一节身体都随着移动到它前一节身体的位置上*/int i;for (i = snake.num - 1; i > 0; i--)  //因为是对数组进行操作,所以这里要 -1,并且这里是i-- {snake.coor[i].x = snake.coor[i - 1].x;snake.coor[i].y = snake.coor[i - 1].y;}switch (snake.dir){case UP:snake.coor[0].y -= 10;/*这里要实现的是可以在窗口处自由进出因为记录的是蛇头方块左边的坐标,而这里我们要使蛇头在接触到边沿(是蛇头的右边)就进入下面的边界所以这里要有个+10,就是为了去掉蛇头自身的长度*/if (snake.coor[0].y +10 <= 0) {snake.coor[0].y = WIN_HEIGHT;}break; case DOWN:snake.coor[0].y += 10;if (snake.coor[0].y  >= WIN_HEIGHT){snake.coor[0].y = 0;}break;case LEFT:snake.coor[0].x -= 10;if (snake.coor[0].x + 10 <= 0){snake.coor[0].x = WIN_WIDTH;}break;case RIGHT:snake.coor[0].x += 10; if (snake.coor[0].x  >= WIN_WIDTH){snake.coor[0].x = 0;}break;default:printf("错误操作,请重新操作!"); break;}//snake.coor[0].x += 10;}void EatFood()
{//判断蛇头和食物的坐标就可以了if (snake.coor[0].x == food.fd.x && snake.coor[0].y == food.fd.y&&food.flag==1){snake.num++;snake.score += 10;food.flag = 0;   //在吃完之后,就让食物不存在}if (food.flag == 0)  //当食物吃完之后就可以继续产生食物了{food.fd.x = rand() % (WIN_WIDTH / 10) * 10;  food.fd.y = rand() % (WIN_HEIGHT / 10) * 10;food.flag = 1; food.color = RGB(rand() % 256, rand() % 256, rand() % 256);}}void DontEatSelf()
{for (int i = 4; i < snake.num; i++){if (snake.coor[0].x == snake.coor[i].x && snake.coor[0].y == snake.coor[i].y){outtextxy(200, 200, "Game over!");_getch();  //保持停顿exit(666);}}
}void Pause()
{if (_getch() == 32)  //32表示空格{//while (_getch() != ' ');while (1){_getch();}}}

完成!!ヾ(๑╹◡╹)ノ"


总结

好了,到现在就完整的实现了贪吃蛇的游戏效果,通过这个程序的编程实现,对于图形化操作界面、数组的深入、游戏逻辑的判断等等都有了更深入的了解,对于编程的提高有很大的帮助,当然了,这个程序现在也还有遗憾的地方,就是不能在任意时刻停止,我会继续更新然后实现这个更完美的效果的!(>ω・* )ノ

感谢观赏,一起提高,慢慢变强。

C语言贪吃蛇 新手入门(超详细)相关推荐

  1. discuz插件开发新手入门 超详细[转载]

    作为一个新手,目前也是刚刚玩转discuz的插件功能,好东西不敢独享,就拿出来大家一起分享入门的过程. 现在网上很多关于discuz的插件教程都是很简单的教程,原因可能是这个东西是商业化的东西,本着分 ...

  2. (十)Scratch制作《贪吃蛇》,超详细

    几乎在学习任何一种编程语言过程中,都会拿<贪吃蛇>这款游戏来实战练手,那如何用Scratch来制作 <贪吃蛇>呢? 贪吃蛇 首先声明制作<贪吃蛇>方法多种多样,不局 ...

  3. scrapy爬取豆瓣所有电影信息(新手入门超详细版)

    本次小实验目标就是爬取豆瓣所有的电影,我们以豆瓣的分类页(https://movie.douban.com/tag/#/)作为start_urls,首要任务就是分析当前页面是否为动态加载,何为js动态 ...

  4. 超简单的C语言贪吃蛇 不闪屏 双缓冲

    C语言贪吃蛇 今天把以前自己写的贪吃蛇总结了一下,发到博客上,怕放在电脑上哪天丢失了都不知道, 有不当之处还望指教 (*・ω< ) ヾ(◍°∇°◍)ノ゙ 贪吃蛇中, 我们看到的蛇在不断的移动,其 ...

  5. C语言贪吃蛇,流畅版,可继续升级改造

    好久没发博文了,这段时间正在入门kali,不过今天我会给大家讲解一下有关c语言贪吃蛇的小代码, 废话不多说,直接上代码 等等,不急,小编还有一个收藏了半年的文件给大家分享一下: 适合刚入门同学学习的编 ...

  6. c语言贪吃蛇大作业报告,C语言贪吃蛇实验报告

    C语言贪吃蛇实验报告 C 语言程序设计实训报告姓 名 专 业 班 级 指导教师 二 011 年 7 月 14 日I I目录1 实训目的和要求 11.1 实训目的和任务 11.2 实训要求 12 实训任 ...

  7. C语言贪吃蛇课程设计实验报告(包含贪吃蛇项目源码)

    文末有贪吃蛇代码全览,代码有十分细致的注释!!! 文末有贪吃蛇代码全览,代码有十分细致的注释!!! 文末有贪吃蛇代码全览,代码有十分细致的注释!!! 码文不易,给个免费的小星星和免费的赞吧,关注也行呀 ...

  8. C语言贪吃蛇大作业总结,c语言贪吃蛇实训报告.doc

    c语言贪吃蛇实训报告 c语言贪吃蛇实训报告 C语言贪吃蛇实验报告 C语言程序设计实训报告 姓 名专 业班 级指导教师 二011年 7 月 14 日 1 1.1 1.2 目录 实训目的和要求 ..... ...

  9. c语言五子棋代码_基于控制台的C语言贪吃蛇

    相信对很多人来说,学完C语言以后,都会找一些小程序来练练手.例如贪吃蛇.五子棋.俄罗斯方块等等. 今天给大家分享一个基于控制台的C语言贪吃蛇小程序. 基础知识要求:C语言基础. 知识点补充 这里写一些 ...

  10. c语言安卓贪吃蛇代码下载,C语言贪吃蛇代码

    c语言编写贪吃蛇源代码,简单易懂,文件为VC源代码.如果你正在学习c语言,就来下载吧.很经典的 C语言贪吃蛇代码部分 #include #include #include#include #defin ...

最新文章

  1. 用ECMAScript4 ( ActionScript3) 实现Unity的热更新 -- 使用原型链和EventTrigger
  2. 【HTML】处理<br>换行符追加到前端换行无效的问题 --- html中渲染的字符串中包含HTML标签无效的处理方法,字符串中包含HTML标签被转义的问题 解决
  3. 计算机动漫游戏制作 巴中,四川省哪些中专学校有计算机动漫与游戏制作专业...
  4. python 追加到字典_扫描器篇(三)之python编写基于字典的网站目录探测脚本
  5. JAVA编程经验汇总 (载)
  6. java多线程编程_阿里P8熬到秃头肝出来的:Java多线程+并发编程核心笔记
  7. hashmap为什么线程不安全_StringBuilder为什么线程不安全?
  8. linux打包java jar_在linux环境下修改可运行jar包配置并重新打包
  9. Centos 7安装RabbitMQ 3.7.8版本(单机版)-不使用RPM
  10. jQuery的DataTables插件的使用方法[转]
  11. Oracle数据库基本操作
  12. 做数据分析已经会Excel了,还要学Python吗?
  13. 数据结构与算法 php pdf,数据结构与算法之美(完结)云盘分享_IT教程网
  14. markdown 设置目录跳转的简单方法
  15. uc手机浏览器 手机模拟_移动端页面调试工具——UC浏览器开发者版
  16. win10 手动下载升级 Powershell terminal
  17. 【T+】畅捷通T+服务管理中,异步任务服务(TPlusPopAsyncTaskService1700)无法启动
  18. 水晶头的制作的学习经历
  19. windows更新错误0x8024401c
  20. 华为云计算机系统是什么,你了解什么是华为云电脑吗,它有什么用

热门文章

  1. SQL Server2008官方下载地址
  2. 将g++编译器集成到VC2005中
  3. 【数据结构 严蔚敏版】 排序基本操作
  4. Android音视频架构-学习路线规划
  5. 单片机C语言程序设计实训 100例—基于 8051+Proteus仿真
  6. 《重回耶路撒冷——犹太人的三千年》(Return to Jerusalem)读后感
  7. 【计算机网络】网络层 : RIP 协议 ( 路由选择协议分类 | RIP 协议简介 | 信息交换 | 距离向量算法 | 计算示例 )★
  8. dopod566使用小参考
  9. SVN:下载、安装和中文设置
  10. DenseNet解析