个人网站设计 优帮云,交互式网站定义,wordpress预留邮箱,深圳网站建设ucreator目录 一、游戏说明
编辑
二、地图坐标
编辑
三、头文件
四、蛇身和食物
五、数据结构设计
蛇节点结构如下#xff1a;
封装一个Snake的结构来维护整条贪吃蛇#xff1a;
蛇的方向#xff0c;可以一一列举#xff0c;使用枚举#xff1a;
游戏状态
封装一个Snake的结构来维护整条贪吃蛇
蛇的方向可以一一列举使用枚举
游戏状态可以一一列举使用枚举
六、Snake.c
5.1、游戏开始函数
定位控制台的光标位置
欢迎来到贪吃蛇游戏
创建一个地图
初始化创建蛇身的节点
创建第一个食物
5.2、游戏运行函数
检测按键状态我们封装了一个宏
打印帮助信息
暂停函数
下一个是否是食物
下一步要走的位置处就是食物就吃掉食物
如果下一步不是食物
检测是否撞墙
检测是否撞自己
蛇移动的函数
七、游戏结束的资源释放
八、Test.c 一、游戏说明
贪吃蛇地图绘制蛇吃食物的功能 上、下、左、右方向键控制蛇的动作蛇撞墙死亡蛇撞自身死亡计算得分蛇身加速、减速暂停游戏 二、地图坐标
我们假设实现一个棋盘27行58列的棋盘行和列可以根据自己的情况修改再围绕地图画出墙如下 三、头文件
#includestdio.h
#includestdlib.h
#includewindows.h
#includestdbool.h
#includelocale.h#define Case break;case#define WALL L□
#define BODY L●
#define FOOD L☆//默认的起始坐标
#define POS_X 24
#define POS_Y 5#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) 0x1) ? 1 : 0 )//贪吃蛇,蛇身节点的定义
typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;
}SnakeNode, * pSnakeNode;
//typedef struct SnakeNode* pSnakeNode;enum GAME_STATUS//游戏状态
{OK 1,//正常运行ESC,//按了ESC键退出,正常退出KILL_BY_WALL,//撞墙KILL_BY_SELF//撞到自身
};//行走的方向
enum DIRECTION//方向
{UP 1,DOWN,LEFT,RIGHT
};//贪吃蛇
typedef struct Snake
{pSnakeNode pSnake;//维护整条蛇的指针,是指向蛇头pSnakeNode pFood;//指向食物的指针int Score;//当前累积的分数int FoodWeight;//一个食物的分数,默认每个食物10分int SleepTime;//每走一步休眠时间?//蛇休眠的时间,休眠的时间越短,蛇的速度越快,休眠的时间越长,蛇的速度越慢enum GAME_STATUS status;//游戏当前的状态enum DIRECTION dir;//蛇当前走的方向,蛇头的方向默认是向右//...
}Snake,* pSnake;
//typedef struct Snake* pSnake;//定位控制台的光标位置
void SetPos(int x, int y);//游戏开始的准备
void GameStart(pSnake ps);//打印欢迎界面
void welcomeToGame();//绘制地图
void CreateMap();//初始化蛇
void InitSnake(pSnake ps);//创建食物
void CreateFood(pSnake ps);//游戏运行的整个逻辑
void GameRun(pSnake ps);//打印帮助信息
void PrintHelpInfo();//蛇移动的函数- 每次走一步
void SnakeMove(pSnake ps);//判断蛇头的下一步要走的位置处是否是食物
int NextIsFood(pSnake ps, pSnakeNode pNext);//下一步要走的位置处就是食物就吃掉食物
void EatFood(pSnake ps, pSnakeNode pNext);//下一步要走的位置处不是食物不吃食物
void NotEatFood(pSnake ps, pSnakeNode pNext);//检测是否撞墙
void KillByWall(pSnake ps);//检测是否撞自己
void KillBySelf(pSnake ps);//游戏结束的资源释放
void GameEnd(pSnake ps);
四、蛇身和食物
初始化状态假设蛇的长度是5蛇身的每个节点是●在固定的一个坐标处比如(24, 5)处开始出现蛇连续5个节点。
注意蛇的每个节点的x坐标必须是2个倍数否则可能会出现蛇的一个节点有一半儿出现在墙体中另外一般在墙外的现象坐标不好对齐。 关于食物就是在墙体内随机生成一个坐标x坐标必须是2的倍数坐标不能和蛇的身体重合然后打印★。
五、数据结构设计
在游戏运行的过程中蛇每次吃一个食物蛇的身体就会变长一节如果我们使用链表存储蛇的信 息那么蛇的每一节其实就是链表的每个节点。每个节点只要记录好蛇身节点在地图上的坐标就行。
#define WALL L□ 墙
#define BODY L● 蛇身
#define FOOD L☆ 食物
蛇节点结构如下 //贪吃蛇,蛇身节点的定义
typedef struct SnakeNode
{int x;int y;struct SnakeNode* next;//是一个指向下一个 SnakeNode 类型节点的指针用于构建链表来表示蛇的身体。
}SnakeNode, * pSnakeNode;
//typedef struct SnakeNode* pSnakeNode;
封装一个Snake的结构来维护整条贪吃蛇
pSnakeNode pSnake这是一个指向 SnakeNode 类型的指针代表蛇的头部。通常贪吃蛇的实现会用一个链表来表示蛇的身体其中每个节点SnakeNode代表蛇身体的一部分而 pSnake 指向这个链表的第一个节点即蛇头。
pSnakeNode pFood这是一个指向 SnakeNode 类型的指针代表食物的位置。在贪吃蛇游戏中食物会被随机放置在游戏区域内当蛇吃到食物时这个食物会被移除并且蛇的身体会增长。
enum GAME_STATUS status;这是一个枚举类型表示游戏当前的状态。具体的枚举值没有在代码中给出但可能包括“游戏中”、“游戏结束”等状态。
enum DIRECTION dir;这是一个枚举类型表示蛇当前移动的方向。具体的枚举值也没有在代码中给出但通常包括“向上”、“向下”、“向左”、“向右”等方向。
typedef struct Snake
{pSnakeNode pSnake;//维护整条蛇的指针,是指向蛇头pSnakeNode pFood;//指向食物的指针int Score;//当前累积的分数int FoodWeight;//一个食物的分数,默认每个食物10分int SleepTime;//每走一步休眠时间?//蛇休眠的时间,休眠的时间越短,蛇的速度越快,休眠的时间越长,蛇的速度越慢enum GAME_STATUS status;//游戏当前的状态enum DIRECTION dir;//蛇当前走的方向,蛇头的方向默认是向右//...
}Snake,* pSnake;
//typedef struct Snake* pSnake;蛇的方向可以一一列举使用枚举
//行走的方向
enum DIRECTION//方向
{UP 1,DOWN,LEAF,RIGHT
};
游戏状态可以一一列举使用枚举
enum GAME_STATUS//游戏状态
{OK 1,//正常运行ESC,//按了ESC键退出,正常退出KILL_BY_WALL,//撞墙KILL_BY_SELF//撞到自身
};
六、Snake.c
5.1、游戏开始函数
void GameStart(pSnake ps)
{//设置控制台的信息,窗口大小,窗口名system(mode con cols120 lines40);system(title 贪吃蛇);//隐藏光标HANDLE handle GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO CursorInfo;GetConsoleCursorInfo(handle, CursorInfo);//获取控制台光标信息CursorInfo.bVisible false;SetConsoleCursorInfo(handle, CursorInfo);//设置光标信息//打印欢迎信息welcomeToGame();//绘制地图CreateMap();//初始化蛇InitSnake(ps);//创建食物CreateFood(ps);}
定位控制台的光标位置
//定位控制台的光标位置
void SetPos(int x, int y)
{//获得设备句柄HANDLE handle GetStdHandle(STD_OUTPUT_HANDLE);//根据句柄设置光标的位置COORD pos { x,y };SetConsoleCursorPosition(handle, pos);
}
欢迎来到贪吃蛇游戏
void welcomeToGame()
{//欢迎信息SetPos(35, 10);printf(欢迎来到贪吃蛇小游戏\n);SetPos(38, 20);system(pause);system(cls);//功能介绍信息SetPos(15, 10);printf(用 ↑ . ↓ . ← . → 来控制蛇的移动,F3是加速,F4是减速\n);SetPos(15, 11);printf(加速能得到更高的分数);SetPos(38, 20);system(pause);system(cls);}
创建一个地图
创建地图就是将墙打印出来因为是宽字符打印所有使用wprintf函数打印格式串前使用L 打印地图的关键是要算好坐标才能在想要的位置打印墙体。
void CreateMap()
{int i 0;//上SetPos(0, 0);for (i 0; i 56; i 2){wprintf(L%lc, WALL);}//下SetPos(0, 25);for (i 0; i 56; i 2){wprintf(L%lc, WALL);}//左for (i 1; i 25; i){SetPos(0, i);wprintf(L%lc, WALL);}//右for (i 1; i 25; i){SetPos(56, i);wprintf(L%lc, WALL);}
}
初始化创建蛇身的节点
蛇最开始长度为5节每节对应链表的一个节点蛇身的每一个节点都有自己的坐标。 创建5个节点然后将每个节点存放在链表中进行管理。创建完蛇身后将蛇的每一节打印在屏幕上。再设置当前游戏的状态蛇移动的速度默认的方向初始成绩蛇的状态每个食物的分数。
结构体成员记录它们的坐标x,y和记录下一个位置的前驱结构体指针next。
void InitSnake(pSnake ps)
{//创建五个蛇身的节点pSnakeNode cur NULL;int i 0;for (i 0; i 5; i){cur (pSnakeNode)malloc(sizeof(SnakeNode));if (cur NULL){perror(InsitSnkae():malloc());return;}cur-x POS_X 2 * i;cur-y POS_Y;cur-next NULL;//头插法if (ps-pSnake NULL){ps-pSnake cur;}else {cur-next ps-pSnake;ps-pSnake cur;}}//打印蛇身cur ps-pSnake;while (cur){SetPos(cur-x, cur-y);wprintf(L%lc, BODY);cur cur-next;}//贪吃蛇的其他信息ps-dir RIGHT;ps-FoodWeight 10;ps-pFood NULL;ps-Score 0;ps-SleepTime 200;ps-status OK;}
创建第一个食物
先随机生成食物的坐标x坐标必须是2的倍数食物的坐标不能和蛇身每个节点的坐标重复创建食物节点打印食物
void CreateFood(pSnake ps)
{int x 0;//x范围: 2~54 - 0~52 2 - rand()%53 2int y 0;//y范围: 1~25 - 0~24 1 - rand()%24 1again:do {x rand() % 53 2;y rand() % 24 1;} while (x % 2 ! 0);//坐标和蛇的身体的每个几点的坐标比较pSnakeNode cur ps-pSnake;while (cur){if (x cur-x y cur-y){goto again;}cur cur-next;}//创建食物pSnakeNode pFood malloc(sizeof(SnakeNode));if (pFood NULL){perror(CreateFood:malloc());return;}pFood-x x;pFood-y y;ps-pFood pFood;SetPos(x, y);wprintf(L%lc, FOOD);}
5.2、游戏运行函数
游戏运行期间右侧打印帮助信息提示玩家 根据游戏状态检查游戏是否继续如果是状态是OK游戏继续否则游戏结束。 如果游戏继续就是检测按键情况确定蛇下一步的方向或者是否加速减速是否暂停或者退出游戏。 确定了蛇的方向和速度蛇就可以移动了。
void GameRun(pSnake ps)
{//打印帮助信息PrintHelpInfo();//检测按键do{//当前的分数情况SetPos(62, 10);printf(总分:%5d\n, ps-Score);SetPos(62, 11);printf(食物的分支:%02d\n, ps-FoodWeight);//检测按键//上、下、左、右、ESC、空格、F3、F4if (KEY_PRESS(VK_UP) ps-dir ! DOWN){ps-dir UP;}else if (KEY_PRESS(VK_DOWN) ps-dir ! UP){ps-dir DOWN;}else if (KEY_PRESS(VK_LEFT) ps-dir ! RIGHT){ps-dir LEFT;}else if (KEY_PRESS(VK_RIGHT) ps-dir ! LEFT){ps-dir RIGHT;}else if (KEY_PRESS(VK_ESCAPE)){ps-status ESC;break;}else if (KEY_PRESS(VK_SPACE)){//游戏要暂停pause();//暂停和开始} else if (KEY_PRESS(VK_F3)){if (ps-SleepTime 80){ps-SleepTime - 30;ps-FoodWeight 2;}}else if (KEY_PRESS(VK_F4)){if (ps-FoodWeight 2){ps-SleepTime 30;ps-FoodWeight - 2;}}//走一步SnakeMove(ps);//睡眠一下Sleep(ps-SleepTime);}while(ps-status OK);}
检测按键状态我们封装了一个宏 #define KEY_PRESS(VK) ((GetAsyncKeyState(VK)0x1) ? 1 : 0) 打印帮助信息
//打印帮助信息
void PrintHelpInfo()
{SetPos(62, 15);printf(1. 不能穿墙. 不能咬到自己);SetPos(62, 16);printf(2. 用 ↑ . ↓ . ← . → 来控制蛇的移动);SetPos(62, 17);printf(3. F3是加速,F4是减速);SetPos(62, 19);printf( );}
暂停函数
void pause()
{while (1){Sleep(100);if (KEY_PRESS(VK_SPACE)){break;}}
}
下一个是否是食物
//pSnakeNode psn 是下一个节点的地址
//pSnake ps 维护蛇的指针
int NextIsFood(pSnake ps, pSnakeNode pNext)
{if (ps-pFood-x pNext-x ps-pFood-y pNext-y)return 1;elsereturn 0;
}
下一步要走的位置处就是食物就吃掉食物
//下一步要走的位置处就是食物就吃掉食物
void EatFood(pSnake ps, pSnakeNode pNext)
{pNext-next ps-pSnake;ps-pSnake pNext;pSnakeNode cur ps-pSnake;//打印蛇身while (cur){SetPos(cur-x, cur-y);wprintf(L%lc, BODY);cur cur-next;}ps-Score ps-FoodWeight;//释放旧的食物free(ps-pFood);//新建食物CreateFood(ps);
}如果下一步不是食物
将下一个节点头插入蛇的身体并将之前蛇身最后一个节点打印为空格放弃掉蛇身的最后一个节点
//pSnakeNode psn 是下一个节点的地址
//pSnake ps 维护蛇的指针
void NotEatFood(pSnake ps, pSnakeNode pNext)
{//头插法pNext-next ps-pSnake;ps-pSnake pNext;//释放尾结点pSnakeNode cur ps-pSnake;while (cur-next-next){SetPos(cur-x, cur-y);wprintf(L%lc, BODY);cur cur-next;}//将尾节点的位置打印成空白字符SetPos(cur-next-x, cur-next-y);printf( );free(cur-next);cur-next NULL;//易错
}
检测是否撞墙
判断蛇头的坐标是否和墙的坐标冲突
//检测是否撞墙
void KillByWall(pSnake ps)
{if (ps-pSnake-x 0 ||ps-pSnake-x 56 ||ps-pSnake-y 0 ||ps-pSnake-y 25){ps-status KILL_BY_WALL;}}
检测是否撞自己
判断蛇头的坐标是否和蛇身体的坐标冲突
//检测是否撞自己
void KillBySelf(pSnake ps)
{pSnakeNode cur ps-pSnake-next;//从第二个节点开始while (cur){if (cur-x ps-pSnake-x cur-y ps-pSnake-y){ps-status KILL_BY_SELF;return;}cur cur-next;}
}
蛇移动的函数
先创建下一个节点根据移动方向和蛇头的坐标蛇移动到下一个位置的坐标。 确定了下一个位置后看下一个位置是否是食物NextIsFood是食物就做吃食物处理 EatFood如果不是食物则做前进一步的处理NoFood。 蛇身移动后判断此次移动是否会造成撞墙KillByWall或者撞上自己蛇身KillBySelf从而影响游戏的状态。
void SnakeMove(pSnake ps)
{pSnakeNode pNext (pSnakeNode)malloc(sizeof(SnakeNode));if (pNext NULL){perror(SnakeMove():malloc());return;}pNext-next NULL;switch (ps-dir){case UP:pNext-x ps-pSnake-x;pNext-y ps-pSnake-y - 1;break;Case DOWN:pNext-x ps-pSnake-x;pNext-y ps-pSnake-y 1;Case LEFT:pNext-x ps-pSnake-x - 2;pNext-y ps-pSnake-y;Case RIGHT:pNext-x ps-pSnake-x 2;pNext-y ps-pSnake-y;break;}//下一个坐标是否是食物if (NextIsFood(ps, pNext)){//是食物就吃掉EatFood(ps, pNext);}else {//不是食物就正常一步NotEatFood(ps, pNext);}//检测撞墙KillByWall(ps);//检测是否撞自己KillBySelf(ps);}
七、游戏结束的资源释放
游戏状态不再是OK游戏继续的时候要告知游戏结束的原因并且释放蛇身节点。
//游戏结束的资源释放
void GameEnd(pSnake ps)
{SetPos(20, 15);switch (ps-status){case ESC:printf(主动退出游戏,正常退出\n);Case KILL_BY_WALL:printf(很遗憾,撞墙了,游戏结束\n);Case KILL_BY_SELF:printf(很遗憾,撞到自己了,游戏结束\n);break;}//释放贪吃蛇的链表资源pSnakeNode cur ps-pSnake;pSnakeNode del NULL;while (cur){del cur;cur cur-next;free(del);}free(ps-pFood);ps NULL;
}
八、Test.c
void test()
{//创建贪食蛇Snake snake { 0 };//GameStart(snake);//游戏开始前的初始化//GameRun();//玩游戏的过程//GameEnd();//善后的工作int ch 0;do{Snake snake { 0 };GameStart(snake);//游戏开始前的初始化GameRun(snake);//玩游戏的过程GameEnd(snake);//善后的工作SetPos(15, 20);printf(再来一局吗(Y/N):);ch getchar();getchar();// 清理\n} while (ch Y || ch y);
}int main()
{//修改适配本地的环境setlocale(LC_ALL, );test();//贪吃蛇游戏的测试SetPos(0, 30);return 0;
}
今天就先到这了 看到这里了还不给博主扣个 ⛳️ 点赞☀️收藏 ⭐️ 关注
你们的点赞就是博主更新最大的动力 有问题可以评论或者私信呢秒回哦。
文章转载自: http://www.morning.trffl.cn.gov.cn.trffl.cn http://www.morning.gjmll.cn.gov.cn.gjmll.cn http://www.morning.lsnnq.cn.gov.cn.lsnnq.cn http://www.morning.lmyq.cn.gov.cn.lmyq.cn http://www.morning.weiwt.com.gov.cn.weiwt.com http://www.morning.jntdf.cn.gov.cn.jntdf.cn http://www.morning.qfzjn.cn.gov.cn.qfzjn.cn http://www.morning.ywqsk.cn.gov.cn.ywqsk.cn http://www.morning.xdttq.cn.gov.cn.xdttq.cn http://www.morning.kjawz.cn.gov.cn.kjawz.cn http://www.morning.fpzz1.cn.gov.cn.fpzz1.cn http://www.morning.taipinghl.cn.gov.cn.taipinghl.cn http://www.morning.wxgd.cn.gov.cn.wxgd.cn http://www.morning.ytrbq.cn.gov.cn.ytrbq.cn http://www.morning.fkdts.cn.gov.cn.fkdts.cn http://www.morning.langlaitech.cn.gov.cn.langlaitech.cn http://www.morning.yhwmg.cn.gov.cn.yhwmg.cn http://www.morning.rqsr.cn.gov.cn.rqsr.cn http://www.morning.sjjq.cn.gov.cn.sjjq.cn http://www.morning.qnrpj.cn.gov.cn.qnrpj.cn http://www.morning.sffwz.cn.gov.cn.sffwz.cn http://www.morning.crfyr.cn.gov.cn.crfyr.cn http://www.morning.thrtt.cn.gov.cn.thrtt.cn http://www.morning.gfqjf.cn.gov.cn.gfqjf.cn http://www.morning.lqgtx.cn.gov.cn.lqgtx.cn http://www.morning.dpppx.cn.gov.cn.dpppx.cn http://www.morning.ybgyz.cn.gov.cn.ybgyz.cn http://www.morning.wbnsf.cn.gov.cn.wbnsf.cn http://www.morning.syglx.cn.gov.cn.syglx.cn http://www.morning.ksggr.cn.gov.cn.ksggr.cn http://www.morning.jwdys.cn.gov.cn.jwdys.cn http://www.morning.qphdp.cn.gov.cn.qphdp.cn http://www.morning.rykw.cn.gov.cn.rykw.cn http://www.morning.qzqjz.cn.gov.cn.qzqjz.cn http://www.morning.tgmfg.cn.gov.cn.tgmfg.cn http://www.morning.tslfz.cn.gov.cn.tslfz.cn http://www.morning.mpnff.cn.gov.cn.mpnff.cn http://www.morning.wjjxr.cn.gov.cn.wjjxr.cn http://www.morning.huayaosteel.cn.gov.cn.huayaosteel.cn http://www.morning.qfdyt.cn.gov.cn.qfdyt.cn http://www.morning.sogou66.cn.gov.cn.sogou66.cn http://www.morning.errnull.com.gov.cn.errnull.com http://www.morning.qbtkg.cn.gov.cn.qbtkg.cn http://www.morning.lbbyx.cn.gov.cn.lbbyx.cn http://www.morning.demoux.com.gov.cn.demoux.com http://www.morning.nzmqn.cn.gov.cn.nzmqn.cn http://www.morning.pluimers.cn.gov.cn.pluimers.cn http://www.morning.fnmgr.cn.gov.cn.fnmgr.cn http://www.morning.mjbjq.cn.gov.cn.mjbjq.cn http://www.morning.ghkgl.cn.gov.cn.ghkgl.cn http://www.morning.tdxlj.cn.gov.cn.tdxlj.cn http://www.morning.junmap.com.gov.cn.junmap.com http://www.morning.ndfwh.cn.gov.cn.ndfwh.cn http://www.morning.lcdtb.cn.gov.cn.lcdtb.cn http://www.morning.ncwgt.cn.gov.cn.ncwgt.cn http://www.morning.jqkrt.cn.gov.cn.jqkrt.cn http://www.morning.ljsxg.cn.gov.cn.ljsxg.cn http://www.morning.xbrxk.cn.gov.cn.xbrxk.cn http://www.morning.yrpd.cn.gov.cn.yrpd.cn http://www.morning.sxfmg.cn.gov.cn.sxfmg.cn http://www.morning.pltbd.cn.gov.cn.pltbd.cn http://www.morning.knmp.cn.gov.cn.knmp.cn http://www.morning.ydwnc.cn.gov.cn.ydwnc.cn http://www.morning.clybn.cn.gov.cn.clybn.cn http://www.morning.lgsfb.cn.gov.cn.lgsfb.cn http://www.morning.bxdlrcz.cn.gov.cn.bxdlrcz.cn http://www.morning.xnlj.cn.gov.cn.xnlj.cn http://www.morning.wkxsy.cn.gov.cn.wkxsy.cn http://www.morning.xfncq.cn.gov.cn.xfncq.cn http://www.morning.rfldz.cn.gov.cn.rfldz.cn http://www.morning.rchsr.cn.gov.cn.rchsr.cn http://www.morning.rfbpq.cn.gov.cn.rfbpq.cn http://www.morning.wrtpk.cn.gov.cn.wrtpk.cn http://www.morning.fmswb.cn.gov.cn.fmswb.cn http://www.morning.skbhl.cn.gov.cn.skbhl.cn http://www.morning.fhsgw.cn.gov.cn.fhsgw.cn http://www.morning.zzjpy.cn.gov.cn.zzjpy.cn http://www.morning.pnfwd.cn.gov.cn.pnfwd.cn http://www.morning.xmjzn.cn.gov.cn.xmjzn.cn http://www.morning.dpqqg.cn.gov.cn.dpqqg.cn