当前位置: 首页 > news >正文

怎么用网站推广wordpress直达按钮

怎么用网站推广,wordpress直达按钮,网上书店网站建设实训总结,做团餐 承包食堂的企业网站目录 C语言贪吃蛇项目 基本功能 需要的基础内容 Win32API 介绍 控制台程序部分指令 设置控制台窗口的长宽 设置控制台的名字 控制台在屏幕上的坐标位置结构体COORD 检索指定标准设备的句柄#xff08;标准输入、标准输出或标准错误#xff09; 光标信息结构体类型CONSOLE_CUR… 目录 C语言贪吃蛇项目 基本功能 需要的基础内容 Win32API 介绍 控制台程序部分指令 设置控制台窗口的长宽 设置控制台的名字 控制台在屏幕上的坐标位置结构体COORD 检索指定标准设备的句柄标准输入、标准输出或标准错误 光标信息结构体类型CONSOLE_CURSOR_INFO 检索有关指定控制台屏幕上的光标大小和可见性的信息 指定的控制台屏幕缓冲区设置光标的大小和可见性 设置指定控制台屏幕缓冲区中的光标位置 获取按键状态 宽字符打印与本地化 宽字符 头文件locale.h与本地化 类项 设置本地化 宽字符的打印 贪吃蛇项目设计 游戏流程设计 贪吃蛇界面的打印 打印游戏欢迎界面 打印游戏规则界面 打印游戏地图界面 打印游戏地图右侧的帮助信息 贪吃蛇结构体设计 贪吃蛇进行过程设计 初始化蛇身以及游戏信息 初始化食物 游戏进行部分 贪吃蛇运行结束 贪吃蛇项目实现 C语言贪吃蛇项目 基本功能 使用C语言在Windows环境的控制台中模拟实现贪吃蛇 贪吃蛇地图绘制蛇吃食物的功能使用键盘按键控制蛇蛇撞墙死亡蛇撞自身死亡计算得分蛇身加速、减速暂停游戏 需要的基础内容 函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32API Win32API 介绍 Windows这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外它同时也是一个很大的服务中心调用这个服务中心的各种服务每一种服务就是一个函数可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的由于这些函数服务的对象是应用程序(Application)所以便称之为Application Programming Interface简称API函数。WIN32API也就是Microsoft Windows 32位平台的应用程序编程接口 控制台程序部分指令 设置控制台窗口的长宽 在运行中输入cmd后打开命令提示符输入mode con cols100 lines30后按Enter执行cols表示列lines表示行 如图所示 参考mode命令文档mode | Microsoft Learn 设置控制台的名字 在运行中输入cmd后打开命令提示符输入title (需要的名字)后按Enter执行 参考title命令文档title | Microsoft Learn 可以在C语言中使用system函数执行上述命令 使用system函数需要包含头文件stdlib.h #define _CRT_SECURE_NO_WARNINGS 1#include stdlib.h//使用system函数需要包含头文件stdlib.h #include stdio.hint main() {//设置控制台窗口的长宽mode con cols100 lines30system(mode con cols100 lines30);//设置列为100列行为30行//设置控制台窗口的名称title 贪吃蛇system(title 贪吃蛇);getchar();//防止程序提前自动结束//等价于使用system(pause);return 0; } 控制台在屏幕上的坐标位置结构体COORD COORD是WindowsAPI中定义的⼀个结构体表示一个字符在控制台屏幕上显示时的坐标坐标系(0, 0)的原点位于屏幕的顶部左侧单元格 //COORD结构体原型 typedef struct _COORD {SHORT X;SHORT Y; } COORD, *PCOORD;//对_COORD结构体进行重命名为COORD以及对_COORD结构体指针重命名为*PCOORD 参考COORD文档COORD 结构 - Windows Console | Microsoft Learn 使用COORD设置字符显示坐标 使用COORD结构体需要包含头文件windows.h COORD pos {10, 15};//将x轴坐标设置为10y轴坐标设置为15 检索指定标准设备的句柄标准输入、标准输出或标准错误 使用GetStdHandle函数进行获取。 GetStdHandle是⼀个WindowsAPI函数。它用于从⼀个特定的标准设备标准输入、标准输出或标 准错误中取得⼀个句柄用来标识不同设备的数值使用这个句柄可以操作设备 参考GetStdHandle文档GetStdHandle 函数 - Windows Console | Microsoft Learn //函数原型 HANDLE WINAPI GetStdHandle(_In_ DWORD nStdHandle);//参数说明 nStdHandle [in]标准设备。 此参数的取值可为下列值之一 STD_INPUT_HANDLE((DWORD)-10) 标准输入设备。 最初这是输入缓冲区 CONIN$ 的控制台 STD_OUTPUT_HANDLE((DWORD)-11) 标准输出设备。 最初这是活动控制台屏幕缓冲区 CONOUT$ STD_ERROR_HANDLE((DWORD)-12) 标准错误设备。 最初这是活动控制台屏幕缓冲区 CONOUT$返回类型 如果函数执行成功则返回值为指定设备的句柄 如果函数执行失败则返回值为 INVALID_HANDLE_VALUE 如果应用程序没有关联的标准句柄例如在交互式桌面上运行的服务并且尚未重定向这些句柄则返回值为 NULL 使用GetStdHandle函数需要包含头文件windows.h 代码实例 HANDLE hOutput NULL;//hOutput相当于一个指针类型的变量 //获取标准输出的句柄(用来标识不同的标准输出设备的数值) 即需要操作的控制台程序 hOutput GetStdHandle(STD_OUTPUT_HANDLE); 对于句柄的简单理解需要操作按键响应等控制台程序时首先得获取到控制台这个应用而句柄就是帮助获取控制台应用的一个“把手” 光标信息结构体类型CONSOLE_CURSOR_INFO //光标信息结构体原型 typedef struct _CONSOLE_CURSOR_INFO {DWORD dwSize;//光标占比大小BOOL bVisible;//光标是否可见 } CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;//将结构体类型重命名为CONSOLE_CURSOR_INFO并将结构体指针类型重命名为*PCONSOLE_CURSOR_INFOdwSize 由游标填充的字符单元的百分比。 该值介于 1 到 100 之间。 游标外观各不相同范围从完全填充单元到显示为单元底部的横线。bVisible 光标的可见性。 如果光标可见则此成员为 TRUE默认为可见 dwsize的表现形式默认为25 参考CONSOLE_CURSOR_INFO结构体类型文档CONSOLE_CURSOR_INFO 结构 - Windows Console | Microsoft Learn 使用CONSOLE_CURSOR_INFO需要包含头文件windows.h 代码实例 CONSOLE_CURSOR_INFO CursorInfo.bVisible false;//隐藏光标 检索有关指定控制台屏幕上的光标大小和可见性的信息 使用函数GetConsoleCursorInfo进行获取 //函数原型 BOOL WINAPI GetConsoleCursorInfo(_In_ HANDLE hConsoleOutput, _Out_ PCONSOLE_CURSOR_INFO lpConsoleCursorInfo );//参数说明 第一个参数hConsoleOutput [in]获取指定控制台屏幕缓冲区的句柄。可以通过GetStdHandle函数获取 第二个参数lpConsoleCursorInfo [out]指向 CONSOLE_CURSOR_INFO 结构的指针该结构接收有关控制台光标的信息返回类型 如果该函数成功则返回值为非零值 如果函数失败则返回值为零 参考GetConsoleCursorInfo函数文档GetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn 使用GetConsoleCursorInfo函数需要包含头文件windows.h 代码实例 HANDLE hOutput NULL; //获取标准输出的句柄(⽤来标识不同设备的数值) hOutput GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_CURSOR_INFO CursorInfo;//使用光标结构体类型定义变量 GetConsoleCursorInfo(hOutput, CursorInfo);//获取控制台光标信息 指定的控制台屏幕缓冲区设置光标的大小和可见性 使用SetConsoleCursorInfo 进行设置 //函数原型 BOOL WINAPI SetConsoleCursorInfo(_In_ HANDLE hConsoleOutput,_In_ const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo );//参数说明 第一个参数hConsoleOutput [in]控制台屏幕缓冲区的句柄 第二个参数pConsoleCursorInfo [in]指向 CONSOLE_CURSOR_INFO 结构的指针该结构为控制台屏幕缓冲区的光标提供新的参数//返回类型 如果该函数成功则返回值为非零值 如果函数失败则返回值为零 参考SetConsoleCursorInfo函数文档SetConsoleCursorInfo 函数 - Windows Console | Microsoft Learn 使用SetConsoleCursorInfo函数需要包含windows.h 代码实例 HANDLE hOutput GetStdHandle(STD_OUTPUT_HANDLE); //隐藏光标操作 CONSOLE_CURSOR_INFO CursorInfo; GetConsoleCursorInfo(hOutput, CursorInfo);//获取控制台光标信息 CursorInfo.bVisible false; //隐藏控制台光标 SetConsoleCursorInfo(hOutput, CursorInfo);//设置控制台光标状态 设置指定控制台屏幕缓冲区中的光标位置 使用函数SetConsoleCursorPosition 进行设置 //函数原型 BOOL WINAPI SetConsoleCursorPosition(_In_ HANDLE hConsoleOutput,_In_ COORD dwCursorPosition );//参数说明 第一个参数为hConsoleOutput [in]获取控制台屏幕缓冲区的句柄 第二个参数为dwCursorPosition [in]指定新光标位置以字符为单位的 COORD 结构。 坐标是屏幕缓冲区字符单元的列和行。 坐标必须位于控制台屏幕缓冲区的边界以内//返回类型 如果该函数成功则返回值为非零值 如果函数失败则返回值为零 参考SetConsoleCursorPosition文档SetConsoleCursorPosition 函数 - Windows Console | Microsoft Learn 代码实例 COORD pos { 10, 5}; HANDLE hOutput NULL; //获取标准输出的句柄(⽤来标识不同设备的数值) hOutput GetStdHandle(STD_OUTPUT_HANDLE); //设置标准输出上光标的位置为pos SetConsoleCursorPosition(hOutput, pos); 获取按键状态 使用GetAsyncKeyState 函数获取 将键盘上每个键的虚拟键值传递给函数函数通过返回值来分辨按键的状态。 GetAsyncKeyState 的返回值是short类型在上⼀次调用 GetAsyncKeyState 函数后如果返回的16位的short数据中最高位是1说明按键的状态是按下如果最高是0说明按键的状态是抬起如果最低位被置为1则说明该按键被按过否则为0 //函数原型 SHORT GetAsyncKeyState([in] int vKey);//参数说明 [in] vKey类型 int虚拟密钥代码。 参考GetAsyncKeyState函数文档getAsyncKeyState 函数 (winuser.h) - Win32 apps | Microsoft Learn 参考虚拟密钥代码文档虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn 定义宏检测按键是否被按过 #define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) 0x1) ? 1 : 0 ) 使用GetAsyncKeyState函数需要包含头文件windows.h 宽字符打印与本地化 宽字符 在游戏地图上打印墙体使用宽字符□打印蛇使用宽字符●打印食物使用宽字符★ 普通的字符即窄字符是占1个字节的而宽字符是占用2个字节 出现窄字符和宽字符区别的原因 C语言字符默认是采用ASCII编码的ASCII字符集采用的是单字节编码且只使用了单字节中的低7位最高位是没有使用的可表示为0xxxxxxx故ASCII字符集共包含128个字符在英语国家中128个字符是基本够用的但是在其他国家语言中例如在法语中字母上方有注音符号它就无法用基本的ASCII码表示。于是⼀些欧洲国家就决定利用字节中闲置的最高位编入新的符号。比如法语中的é的编码为130二进制10000010。这样一来这些欧洲国家使用的编码体系可以表示最多256个符号。但是不同的国家有不同的字母因此尽管都使用256个符号的编码方式代表的字母却不⼀样。例如130在法语编码中代表了é在希伯来语编码中却代表了字母Gimel在俄语编码中代表另⼀个符号。但是所有这些编码方式中0--127表示的符号是一样的不一样的只是128--255的这⼀段。 至于亚洲国家的文字使用的符号就更多了汉字就多达10万左右。一个字节只能表示256种符号就必须使用多个字节表达⼀个符号。比如简体中文常见的编码方式是GB2312使用两个字节表示⼀个汉字所以理论上最多可以表示256x25665536个符号 为了使C语言适应国际化C语言的标准中不断加入了国际化的支持。例如加入宽字符的类型wchar_t 和宽字符的输入wscanf()和输出函数wprintf()并且使用时需要包含头文件locale.h其中提供了允许程序员针对特定地区通常是国家或者说某种特定语言的地理区域调整程序行为的函数 头文件locale.h与本地化 locale.h提供的函数用于控制C标准库中对于不同的地区会产生不一样行为的部分。 在标准可以中依赖地区的部分有以下几项 数字量的格式货币量的格式字符集日期和时间的表示形式 类项 通过修改地区程序可以改变它的行为来适应世界的不同区域。但地区的改变可能会影响库的许多部分其中一部分可能是不希望修改的。所以C语言支持针对不同的类项进行修改下面的一个宏指定一个类项 类项 影响内容 LC_ALL 以下列出的所有类别 LC_COLLATE strcoll、_stricoll、wcscoll、_wcsicoll、strxfrm、_strncoll、_strnicoll、_wcsncoll、_wcsnicoll 和 wcsxfrm 函数 LC_CTYPE 字符处理函数不受影响的 isdigit、isxdigit、mbstowcs 和 mbtowc 除外 LC_MONETARY localeconv 函数返回的货币格式信息 LC_NUMERIC 格式化输出例程例如printf、数据转换例程和localeconv返回的非货币格式设置信息的十进制点字符。 除小数点字符之外LC_NUMERIC 还设置返回localeconv的千位分隔符和分组控制字符串 LC_TIME strftime 和 wcsftime 函数 设置本地化 使用函数setlocale函数进行设置 setlocale函数用于修改当前地区可以针对一个类项修改也可以针对所有类项 //函数原型 char *setlocale(int category, const char *locale);//参数说明 第一个参数为category表示受区域设置影响的分类。 第二个参数为locale表示区域设置说明符//返回类型 如果提供了有效的locale和category函数会返回指向与指定的locale和category关联的字符串的指针。 如果locale参数为NULL函数会返回当前区域设置。 如果将无效参数传递给任一函数则返回值为NULL。 setlocale的第一个参数可以是前面说明的类项中的某一个那么每次只会影响一个类项如果第一个参数是LC_ALL就会影响所有的类项 C标准给第⼆个参数仅定义了2种可能取值C(即NULL)和 在任意程序执行开始都会隐藏式执行调用: setlocale(LC_ALL, C);//当地区设置为C时库函数按正常方式执行 需要改变地区时就只能显示调用setlocale函数。将 作为第2个参数调用setlocale函数就可以切换到本地模式这种模式下程序会适应本地环境。 例如切换到我们的本地模式后则支持宽字符汉字的输出等 setlocale(LC_ALL, );//切换到本地环境 函数参考文档setlocale | Microsoft Learn 代码实例 #define _CRT_SECURE_NO_WARNINGS 1#include stdio.h #include locale.hint main() {printf(当前环境为%s\n, setlocale(LC_ALL, NULL));printf(设置后的本地环境为%s\n, setlocale(LC_ALL, ));return 0; } 输出结果 当前环境为C 设置后的本地环境为Chinese (Simplified)_China.936 宽字符的打印 在C语言中宽字符的字面量前必须加上前缀L否则C语言会把字面量当作窄字符类型处理。前缀L在单引号前面表示宽字符。 宽字符的打印使用函数wprintf()对应wprintf()的占位符为%lc打印宽字符串时对应的占位符为%ls并且在双引号前需要加上前缀L 代码实例 #define _CRT_SECURE_NO_WARNINGS 1#include stdio.h #include locale.hint main() {printf(设置后的本地环境为%s\n, setlocale(LC_ALL, ));wchar_t c L中;wchar_t c1 L国;wchar_t c2 L■;wchar_t c3 L●;wchar_t c4 L★;char* string ab;wprintf(L%lc\n, c);wprintf(L%lc\n, c1);printf(%s\n, string);wprintf(L%lc\n, c2);wprintf(L%lc\n, c3);wprintf(L%lc\n, c4);return 0; } 输出结果如下图 普通字符和宽字符打印的宽度展示如下 贪吃蛇项目设计 游戏流程设计 贪吃蛇界面的打印 打印游戏欢迎界面 效果图 设计思路 游戏开始界面只需要打印文字但是需要确定文字的打印位置 设置光标隐藏封装成函数void HideCursor();防止出现打印完成后光标闪烁问题设置控制台的大小和标题使用mode命令和title命令设置光标位置将该操作封装成函数void SetPos(int x, int y);将欢迎界面的打印和设置光标位置封装成函数void Welcome();调用pause指令显示“请按任意键继续...”亦可防止程序提前结束最后调用cls指令清除当前页面打印的内容方便打印下一界面实现页面跳转的效果 代码示例 //隐藏光标 void HideCursor() {HANDLE hOutput GetStdHandle(STD_OUTPUT_HANDLE);//隐藏光标CONSOLE_CURSOR_INFO cursor { 0 };//先获取光标信息GetConsoleCursorInfo(hOutput, cursor);cursor.bVisible false;//设置光标为不可见//再传入新的光标信息SetConsoleCursorInfo(hOutput, cursor); }//设置光标位置 void SetPos(int x, int y) {HANDLE hOutput GetStdHandle(STD_OUTPUT_HANDLE);COORD pos { x, y };SetConsoleCursorPosition(hOutput, pos); }//欢迎界面 void Welcome() {system(mode con cols100 lines30);system(title 贪吃蛇);//定位光标SetPos(33, 12);printf(欢迎来到贪吃蛇的世界尽情游玩吧);SetPos(40, 28);system(pause);system(cls); } 打印游戏规则界面 效果图如下 设计思路 游戏规则界面同样只是打印基本文字信息 通过调用SetPos函数在每一次打印过程中设置光标位置将游戏规则的打印和设置光标位置函数的调用封装成函数void Rules();调用pause指令显示“请按任意键继续...”亦可防止程序提前结束最后调用cls指令清除当前页面打印的内容方便打印下一界面实现页面跳转的效果 注意设置光标隐藏函数只需要在程序运行起来后执行一次即可故在游戏界面打印部分只需要调用一次不需要放置到Welcome()函数内 代码示例 //游戏规则介绍界面 void Rules() {SetPos(45, 10);printf(游戏规则);SetPos(35, 12);printf(使用WASD或↑↓←→键操作蛇的移动);SetPos(30, 13);//重新设置坐标位置防止出现文字打印覆盖printf(按下空格即可加速按下左alt或右alt取消加速);SetPos(22, 14);printf(加速可以加分加速一次2分最高加8分取消加速-2分直到减到初始值);SetPos(40, 28);system(pause);system(cls); } 打印游戏地图界面 效果图 设计思路 游戏地图的打印依旧是纯打印字符但是需要注意打印的是宽字符 参考下图 地图的打印封装成函数void Map();在该函数中调用SetPos函数设置每次打印的位置在打印地图上半部分边界和下半部分边界时需要注意因为宽字符横向占两个宽度故需要确保宽字符的数量尽量保证其为2的倍数而纵向方向上依旧是占用一个宽度在打印左右部分边界时需要注意此时宽字符纵向是一个宽度 代码示例 //打印游戏地图界面 void Map() {//设置地区setlocale(LC_ALL, );//打印地图上部分边界SetPos(0, 0);for (int i 0; i 29; i){wprintf(L%lc, MAP);}//打印地图下部分边界SetPos(0, 26);for (int i 0; i 29; i){wprintf(L%lc, MAP);}//打印地图左部分边界for (int i 1; i 25; i){SetPos(0, i);wprintf(L%lc, MAP);}//打印地图右部分边界for (int i 1; i 25; i){SetPos(56, i);//注意此处是56而不是28因为宽字符横向占两个宽度wprintf(L%lc, MAP);}getchar(); } 打印游戏地图右侧的帮助信息 效果图 设计思路 帮助信息依旧是纯打印文字只需要设置好打印位置即可 将帮助信息的打印封装成函数void Help(); //打印游戏地图右侧帮助信息 void Help() {SetPos(60, 20);printf(不能穿墙不能咬到自己);SetPos(60, 21);printf(用WASD或↑↓←→控制蛇的移动方向);SetPos(60, 22);printf(按下空格进入加速按下左alt或右alt取消加速);SetPos(60, 23);printf(使用ESC退出游戏使用P暂停游戏);SetPos(60, 26);printf(Copy RightEPSDA); } 贪吃蛇结构体设计 需要进行设计的结构体类型有 蛇身节点游戏状态蛇的移动方向游戏信息 设计时需要注意蛇吃掉食物食物变成自身节点这一过程相当于食物也是蛇身节点类型 //枚举游戏状态 enum state {Normal 1,//正常状态Error,//错误状态KillBySelf,//自己咬到自己KillbByWall//撞墙 };//枚举蛇的方向 enum dir {Up 1,Down,Left,Right };//定义蛇身节点 typedef struct SnakeNode {int x;int y;struct SnakeNode* next; }Snode;//定义游戏信息结构体 typedef struct GameInfo {Snode* pSnake;//指向蛇头的指针Snode* pFood;//指向食物的指针int FoodWeight;//一个食物的得分int score;//当前总得分enum dir direct;//蛇的移动方向默认向右enum state Srun;//游戏状态int sleepTime;//蛇的移动速度睡眠时间越短蛇越快默认为200 }Sinfo; 贪吃蛇进行过程设计 初始化蛇身以及游戏信息 //初始化蛇身以及除食物以外的游戏信息 void Init(Sinfo* ps) {//确保有蛇对象assert(ps);//优先蛇身的尾结点//通过头插实现蛇身整体Snode* cur NULL;for (int i 0; i 4; i){//创建蛇节点cur (Snode*)malloc(sizeof(Snode));assert(cur);cur-x 24 2 * i;cur-y 5;cur-next NULL;//将节点连起来if (ps-pSnake NULL){ps-pSnake cur;//使游戏信息中维护蛇身的指针指向蛇尾}else{cur-next ps-pSnake;ps-pSnake cur;}}//打印蛇遍历链表//使用指向头结点的ps-pSnake指针Snode* pcur ps-pSnake;setlocale(LC_ALL, );while (pcur){SetPos(pcur-x, pcur-y);wprintf(L%lc, BODY);pcur pcur-next;}//初始化其他信息ps-FoodWeight 10;ps-sleepTime 200;ps-score 0;ps-Srun Normal;ps-direct Right; } 初始化食物 //初始化食物 //食物本质也是蛇身所以依旧可以使用蛇身结构体 void FoodInit(Sinfo* pf) {assert(pf);//随机生成食物Snode* food (Snode*)malloc(sizeof(Snode));assert(food);pf-pFood food;//设置食物坐标//但是食物坐标不能与蛇坐标重合 create:do{//确保食物坐标不会超出地图范围pf-pFood-x rand() % 53 2;pf-pFood-y rand() % 24 1;} while (pf-pFood-x % 2 ! 0);//确保食物的x坐标为2的倍数//确保食物所在位置不是蛇的位置并且蛇身每个节点都需要比较Snode* cur pf-pSnake;while (cur){if (pf-pFood-x cur-x pf-pFood-y cur-y){goto create;}cur cur-next;}//打印食物setlocale(LC_ALL, );SetPos(pf-pFood-x, pf-pFood-y);wprintf(L%lc, FOOD); } 游戏进行部分 //判断下一个坐标是不是食物 bool NextIsFood(Sinfo* snake, Snode* pfood) {assert(snake);assert(pfood);if (snake-pSnake-x snake-pFood-x snake-pSnake-y snake-pFood-y){return true;}else{return false;} }//吃食物 void EatFood(Sinfo* snake, Snode* pfood) {assert(snake);assert(pfood);//是食物进行头插pfood-next snake-pSnake;snake-pSnake pfood;//打印新蛇身Snode* pcur snake-pSnake;setlocale(LC_ALL, );while (pcur){SetPos(pcur-x, pcur-y);wprintf(L%lc, BODY);pcur pcur-next;}snake-score snake-FoodWeight;//释放原来旧的食物free(snake-pFood);//重新创建食物FoodInit(snake); }//不是食物则正常移动 void NotEatFood(Sinfo* snake, Snode* pnext) {assert(snake);assert(pnext);pnext-next snake-pSnake;snake-pSnake pnext;//不是食物时蛇移动不会增加身体的长度Snode* pcur snake-pSnake;setlocale(LC_ALL, );while (pcur-next-next ! NULL){SetPos(pcur-x, pcur-y);wprintf(L%lc, BODY);pcur pcur-next;}//释放掉最后一个节点防止蛇身长度增加SetPos(pcur-next-x, pcur-next-y);printf( );free(pcur-next);pcur-next NULL; }//撞到自身 void Kill_Self(Sinfo* snake) {assert(snake);//不可撞到自身相当于不可以撞到自身的第二个之后的所有节点Snode* pcur snake-pSnake-next;while (pcur){if (pcur-x snake-pSnake-x pcur-y snake-pSnake-y){snake-Srun KillBySelf;return;}pcur pcur-next;} }//撞到墙 void Kill_Wall(Sinfo* snake) {assert(snake);//不可以撞到墙相当于头结点不可以等于墙的坐标Snode* pcur snake-pSnake;if (pcur-x 0 || pcur-x 56 || pcur-y 0 || pcur-y 26){snake-Srun KillByWall;return;} }//蛇的移动 void Move(Sinfo* snake) {//默认移动方向向右assert(snake);//创建新节点用于移动时存储新坐标Snode* psnake (Snode*)malloc(sizeof(Snode));assert(psnake);psnake-next NULL;switch (snake-direct){case Up:psnake-x snake-pSnake-x;psnake-y snake-pSnake-y - 1;break;case Down:psnake-x snake-pSnake-x;psnake-y snake-pSnake-y 1;break;case Left:psnake-x snake-pSnake-x - 2;psnake-y snake-pSnake-y;break;case Right:psnake-x snake-pSnake-x 2;psnake-y snake-pSnake-y;break;default:break;}//移动过程中是否遇到食物if (NextIsFood(snake, psnake))//遇到食物{EatFood(snake, psnake);}else{NotEatFood(snake, psnake);}Kill_Self(snake);Kill_Wall(snake); }//游戏暂停 void SleepStatus() {while (1){//循环睡眠Sleep(200);//同时检测按键if (KEYPRESSED(0x50)){break;}} }//游戏过程部分 void GameRun(Sinfo* snake) {//读取键盘输入控制蛇的移动do{//打印得分情况SetPos(60, 10);printf(一个食物%02d分, snake-FoodWeight);SetPos(60, 11);printf(当前得分%02d, snake-score);//向上走原方向不能向下if (KEYPRESSED(VK_UP) snake-direct ! Down){snake-direct Up;}//向下走原方向不能向上else if (KEYPRESSED(VK_DOWN) snake-direct ! Up){snake-direct Down;}//向左走原方向不能向右else if (KEYPRESSED(VK_LEFT) snake-direct ! Right){snake-direct Left;}//向右走原方向不能向左else if (KEYPRESSED(VK_RIGHT) snake-direct ! Left){snake-direct Right;}else if (KEYPRESSED(VK_ESCAPE)){snake-Srun Quit;break;}else if (KEYPRESSED(0x50)){SleepStatus();//暂停游戏}else if (KEYPRESSED(VK_SPACE)){//加速最多加到320if (snake-sleepTime 320){snake-sleepTime 30;snake-FoodWeight 2;}}else if (KEYPRESSED(VK_LMENU) || KEYPRESSED(VK_RMENU)){//减速if (snake-sleepTime 200){snake-sleepTime - 30;snake-FoodWeight - 2;}}//蛇的移动Move(snake);Sleep(snake-sleepTime);} while (snake-Srun Normal); } 贪吃蛇运行结束 //游戏结束 void GameEnd(Sinfo* snake) {assert(snake);//释放开辟过的空间SetPos(15, 12);switch (snake-Srun){case Quit:printf(游戏退出);break;case KillByWall:printf(墙可不是食物嗷头部出现大包);break;case KillBySelf:printf(没有闹饥荒嗷自己不好吃);break;}while (snake-pSnake){Snode* BlockToFree snake-pSnake;snake-pSnake snake-pSnake-next;free(BlockToFree);}free(snake-pFood);snake NULL; } 贪吃蛇项目实现 //测试文件 #define _CRT_SECURE_NO_WARNINGS 1#include Snake_game.hvoid gameTest() {int ch 0;do{//游戏开始GameStart();//游戏进行srand((unsigned int)time(NULL));Sinfo snake { 0 };Init(snake);//初始化蛇身以及除食物以外的游戏信息//初始化食物FoodInit(snake);GameRun(snake);//游戏结束GameEnd(snake);SetPos(15, 10);printf(还要继续嘛(Y/N));ch getchar();getchar();//清理缓冲区的\n} while (ch Y || ch y);}int main() {gameTest();SetPos(0, 28);return 0; }//头文件 #pragma once#include stdio.h #include windows.h #include stdlib.h #include assert.h #include locale.h #include stdbool.h #include time.h//定义宏检测按键是否被按过 #define KEYPRESSED(vk) (GetAsyncKeyState(vk) 0x1 ? 1 : 0) //定义蛇身图案 #define BODY L● //定义食物图案 #define FOOD L★ //定义地图图案 #define MAP L□//枚举游戏状态 enum state {Normal 1,//正常状态Quit,//退出状态KillBySelf,//自己咬到自己KillByWall//撞墙 };//枚举蛇的方向 enum dir {Up 1,Down,Left,Right };//定义蛇身节点 typedef struct SnakeNode {int x;int y;struct SnakeNode* next; }Snode;//定义游戏信息结构体 typedef struct GameInfo {Snode* pSnake;//指向蛇头的指针Snode* pFood;//指向食物的指针int FoodWeight;//一个食物的得分int score;//当前总得分enum dir direct;//蛇的移动方向默认向右enum state Srun;//游戏状态int sleepTime;//蛇的移动速度睡眠时间越短蛇越快默认为200 }Sinfo;//游戏开始部分 void GameStart(); //隐藏光标 void HideCursor(); //设置光标位置决定打印内容位置 void SetPos(int x, int y); //打印欢迎界面 void Welcome(); //打印游戏规则介绍界面 void Rules(); //打印游戏地图界面 void Map(); //打印游戏地图右侧帮助信息 void Help();//游戏进行 void GameRun(Sinfo* snake); //初始化蛇身以及游戏信息 void Init(Sinfo* ps); //初始化食物 void FoodInit(Sinfo* pf); //判断下一个坐标是不是食物 bool NextIsFood(Sinfo* snake, Snode* pfood); //吃食物 void EatFood(Sinfo* snake, Snode* pfood); //不是食物则正常移动 void NotEatFood(Sinfo* snake, Snode* pfood); //游戏暂停 void SleepStatus(); //蛇的移动 void Move(Sinfo* snake); //撞到自身 void Kill_Self(Sinfo* snake); //撞到墙 void Kill_Wall(Sinfo* snake);//游戏结束 void GameEnd(Sinfo* snake);//项目文件 #define _CRT_SECURE_NO_WARNINGS 1#include Snake_game.h//隐藏光标 void HideCursor() {HANDLE hOutput GetStdHandle(STD_OUTPUT_HANDLE);//隐藏光标CONSOLE_CURSOR_INFO cursor { 0 };//先获取光标信息GetConsoleCursorInfo(hOutput, cursor);cursor.bVisible false;//设置光标为不可见//再传入新的光标信息SetConsoleCursorInfo(hOutput, cursor); }//设置光标位置 void SetPos(int x, int y) {HANDLE hOutput GetStdHandle(STD_OUTPUT_HANDLE);COORD pos { x, y };SetConsoleCursorPosition(hOutput, pos); }//欢迎界面 void Welcome() {system(mode con cols105 lines30);system(title 贪吃蛇);//定位光标SetPos(33, 12);printf(欢迎来到贪吃蛇的世界尽情游玩吧);SetPos(40, 28);system(pause);system(cls); }//游戏规则介绍界面 void Rules() {SetPos(45, 10);printf(游戏规则);SetPos(35, 12);printf(使用↑↓←→键操作蛇的移动);SetPos(30, 13);//重新设置坐标位置防止出现文字打印覆盖printf(按下空格即可加速按下左alt或右alt取消加速);SetPos(22, 14);printf(加速可以加分加速一次2分最高加8分取消加速-2分直到减到初始值);SetPos(40, 28);system(pause);system(cls); }//打印游戏地图界面 void Map() {//设置地区setlocale(LC_ALL, );//打印地图上部分边界SetPos(0, 0);for (int i 0; i 29; i){wprintf(L%lc, MAP);}//打印地图下部分边界SetPos(0, 26);for (int i 0; i 29; i){wprintf(L%lc, MAP);}//打印地图左部分边界for (int i 1; i 25; i){SetPos(0, i);wprintf(L%lc, MAP);}//打印地图右部分边界for (int i 1; i 25; i){SetPos(56, i);//注意此处是56而不是28因为宽字符横向占两个宽度wprintf(L%lc, MAP);} }//打印游戏地图右侧帮助信息 void Help() {SetPos(60, 20);printf(不能穿墙不能咬到自己);SetPos(60, 21);printf(用↑↓←→控制蛇的移动方向);SetPos(60, 22);printf(按下空格进入加速按下左alt或右alt取消加速);SetPos(60, 23);printf(使用ESC退出游戏使用P暂停游戏);SetPos(60, 26);printf(Copy RightEPSDA); }//游戏开始部分 void GameStart() {//隐藏光标HideCursor();//打印欢迎界面Welcome();//打印游戏规则界面Rules();//打印游戏地图界面Map();//打印游戏地图右侧帮助信息Help(); }//初始化蛇身以及除食物以外的游戏信息 void Init(Sinfo* ps) {//确保有蛇对象assert(ps);//优先蛇身的尾结点//通过头插实现蛇身整体Snode* cur NULL;for (int i 0; i 4; i){//创建蛇节点cur (Snode*)malloc(sizeof(Snode));assert(cur);cur-x 24 2 * i;cur-y 5;cur-next NULL;//将节点连起来if (ps-pSnake NULL){ps-pSnake cur;//使游戏信息中维护蛇身的指针指向蛇尾}else{cur-next ps-pSnake;ps-pSnake cur;}}//打印蛇遍历链表//使用指向头结点的ps-pSnake指针Snode* pcur ps-pSnake;setlocale(LC_ALL, );while (pcur){SetPos(pcur-x, pcur-y);wprintf(L%lc, BODY);pcur pcur-next;}//初始化其他信息ps-FoodWeight 10;ps-sleepTime 200;ps-score 0;ps-Srun Normal;ps-direct Right; }//初始化食物 //食物本质也是蛇身所以依旧可以使用蛇身结构体 void FoodInit(Sinfo* pf) {assert(pf);//随机生成食物Snode* food (Snode*)malloc(sizeof(Snode));assert(food);pf-pFood food;//设置食物坐标//但是食物坐标不能与蛇坐标重合 create:do{//确保食物坐标不会超出地图范围pf-pFood-x rand() % 53 2;pf-pFood-y rand() % 24 1;} while (pf-pFood-x % 2 ! 0);//确保食物的x坐标为2的倍数//确保食物所在位置不是蛇的位置并且蛇身每个节点都需要比较Snode* cur pf-pSnake;while (cur){if (pf-pFood-x cur-x pf-pFood-y cur-y){goto create;}cur cur-next;}//打印食物setlocale(LC_ALL, );SetPos(pf-pFood-x, pf-pFood-y);wprintf(L%lc, FOOD); }//判断下一个坐标是不是食物 bool NextIsFood(Sinfo* snake, Snode* pfood) {assert(snake);assert(pfood);if (snake-pSnake-x snake-pFood-x snake-pSnake-y snake-pFood-y){return true;}else{return false;} }//吃食物 void EatFood(Sinfo* snake, Snode* pfood) {assert(snake);assert(pfood);//是食物进行头插pfood-next snake-pSnake;snake-pSnake pfood;//打印新蛇身Snode* pcur snake-pSnake;setlocale(LC_ALL, );while (pcur){SetPos(pcur-x, pcur-y);wprintf(L%lc, BODY);pcur pcur-next;}snake-score snake-FoodWeight;//释放原来旧的食物free(snake-pFood);//重新创建食物FoodInit(snake); }//不是食物则正常移动 void NotEatFood(Sinfo* snake, Snode* pnext) {assert(snake);assert(pnext);pnext-next snake-pSnake;snake-pSnake pnext;//不是食物时蛇移动不会增加身体的长度Snode* pcur snake-pSnake;setlocale(LC_ALL, );while (pcur-next-next ! NULL){SetPos(pcur-x, pcur-y);wprintf(L%lc, BODY);pcur pcur-next;}//释放掉最后一个节点防止蛇身长度增加SetPos(pcur-next-x, pcur-next-y);printf( );free(pcur-next);pcur-next NULL; }//撞到自身 void Kill_Self(Sinfo* snake) {assert(snake);//不可撞到自身相当于不可以撞到自身的第二个之后的所有节点Snode* pcur snake-pSnake-next;while (pcur){if (pcur-x snake-pSnake-x pcur-y snake-pSnake-y){snake-Srun KillBySelf;return;}pcur pcur-next;} }//撞到墙 void Kill_Wall(Sinfo* snake) {assert(snake);//不可以撞到墙相当于头结点不可以等于墙的坐标Snode* pcur snake-pSnake;if (pcur-x 0 || pcur-x 56 || pcur-y 0 || pcur-y 26){snake-Srun KillByWall;return;} }//蛇的移动 void Move(Sinfo* snake) {//默认移动方向向右assert(snake);//创建新节点用于移动时存储新坐标Snode* psnake (Snode*)malloc(sizeof(Snode));assert(psnake);psnake-next NULL;switch (snake-direct){case Up:psnake-x snake-pSnake-x;psnake-y snake-pSnake-y - 1;break;case Down:psnake-x snake-pSnake-x;psnake-y snake-pSnake-y 1;break;case Left:psnake-x snake-pSnake-x - 2;psnake-y snake-pSnake-y;break;case Right:psnake-x snake-pSnake-x 2;psnake-y snake-pSnake-y;break;default:break;}//移动过程中是否遇到食物if (NextIsFood(snake, psnake))//遇到食物{EatFood(snake, psnake);}else{NotEatFood(snake, psnake);}Kill_Self(snake);Kill_Wall(snake); }//游戏暂停 void SleepStatus() {while (1){//循环睡眠Sleep(200);//同时检测按键if (KEYPRESSED(0x50)){break;}} }//游戏过程部分 void GameRun(Sinfo* snake) {//读取键盘输入控制蛇的移动do{//打印得分情况SetPos(60, 10);printf(一个食物%02d分, snake-FoodWeight);SetPos(60, 11);printf(当前得分%02d, snake-score);//向上走原方向不能向下if (KEYPRESSED(VK_UP) snake-direct ! Down){snake-direct Up;}//向下走原方向不能向上else if (KEYPRESSED(VK_DOWN) snake-direct ! Up){snake-direct Down;}//向左走原方向不能向右else if (KEYPRESSED(VK_LEFT) snake-direct ! Right){snake-direct Left;}//向右走原方向不能向左else if (KEYPRESSED(VK_RIGHT) snake-direct ! Left){snake-direct Right;}else if (KEYPRESSED(VK_ESCAPE)){snake-Srun Quit;break;}else if (KEYPRESSED(0x50)){SleepStatus();//暂停游戏}else if (KEYPRESSED(VK_SPACE)){//加速最多加到320if (snake-sleepTime 320){snake-sleepTime 30;snake-FoodWeight 2;}}else if (KEYPRESSED(VK_LMENU) || KEYPRESSED(VK_RMENU)){//减速if (snake-sleepTime 200){snake-sleepTime - 30;snake-FoodWeight - 2;}}//蛇的移动Move(snake);Sleep(snake-sleepTime);} while (snake-Srun Normal); }//游戏结束 void GameEnd(Sinfo* snake) {assert(snake);//释放开辟过的空间SetPos(15, 12);switch (snake-Srun){case Quit:printf(游戏退出);break;case KillByWall:printf(墙可不是食物嗷头部出现大包);break;case KillBySelf:printf(没有闹饥荒嗷自己不好吃);break;}while (snake-pSnake){Snode* BlockToFree snake-pSnake;snake-pSnake snake-pSnake-next;free(BlockToFree);}free(snake-pFood);snake NULL; }
文章转载自:
http://www.morning.kjyhh.cn.gov.cn.kjyhh.cn
http://www.morning.knmby.cn.gov.cn.knmby.cn
http://www.morning.kaweilu.com.gov.cn.kaweilu.com
http://www.morning.gxfpk.cn.gov.cn.gxfpk.cn
http://www.morning.pwmpn.cn.gov.cn.pwmpn.cn
http://www.morning.btwlp.cn.gov.cn.btwlp.cn
http://www.morning.kmprl.cn.gov.cn.kmprl.cn
http://www.morning.vjdofuj.cn.gov.cn.vjdofuj.cn
http://www.morning.jgnst.cn.gov.cn.jgnst.cn
http://www.morning.srnhk.cn.gov.cn.srnhk.cn
http://www.morning.znnsk.cn.gov.cn.znnsk.cn
http://www.morning.sqhtg.cn.gov.cn.sqhtg.cn
http://www.morning.kdtdh.cn.gov.cn.kdtdh.cn
http://www.morning.ptwrz.cn.gov.cn.ptwrz.cn
http://www.morning.lnyds.cn.gov.cn.lnyds.cn
http://www.morning.rgpsq.cn.gov.cn.rgpsq.cn
http://www.morning.xyrss.cn.gov.cn.xyrss.cn
http://www.morning.knpmj.cn.gov.cn.knpmj.cn
http://www.morning.mdjtk.cn.gov.cn.mdjtk.cn
http://www.morning.rykmf.cn.gov.cn.rykmf.cn
http://www.morning.thntp.cn.gov.cn.thntp.cn
http://www.morning.dpgdj.cn.gov.cn.dpgdj.cn
http://www.morning.lmxzw.cn.gov.cn.lmxzw.cn
http://www.morning.rqlbp.cn.gov.cn.rqlbp.cn
http://www.morning.jwqqd.cn.gov.cn.jwqqd.cn
http://www.morning.rzdzb.cn.gov.cn.rzdzb.cn
http://www.morning.tmtrl.cn.gov.cn.tmtrl.cn
http://www.morning.rwqk.cn.gov.cn.rwqk.cn
http://www.morning.dmchips.com.gov.cn.dmchips.com
http://www.morning.pmptm.cn.gov.cn.pmptm.cn
http://www.morning.xhgxd.cn.gov.cn.xhgxd.cn
http://www.morning.lbggk.cn.gov.cn.lbggk.cn
http://www.morning.qwmpn.cn.gov.cn.qwmpn.cn
http://www.morning.ylqpp.cn.gov.cn.ylqpp.cn
http://www.morning.ygqjn.cn.gov.cn.ygqjn.cn
http://www.morning.tbzcl.cn.gov.cn.tbzcl.cn
http://www.morning.hxrg.cn.gov.cn.hxrg.cn
http://www.morning.rydhq.cn.gov.cn.rydhq.cn
http://www.morning.xwqxz.cn.gov.cn.xwqxz.cn
http://www.morning.ghzfx.cn.gov.cn.ghzfx.cn
http://www.morning.yzxlkj.com.gov.cn.yzxlkj.com
http://www.morning.prmbb.cn.gov.cn.prmbb.cn
http://www.morning.plqqp.cn.gov.cn.plqqp.cn
http://www.morning.fbrshjf.com.gov.cn.fbrshjf.com
http://www.morning.btblm.cn.gov.cn.btblm.cn
http://www.morning.bkwd.cn.gov.cn.bkwd.cn
http://www.morning.msbmp.cn.gov.cn.msbmp.cn
http://www.morning.rkck.cn.gov.cn.rkck.cn
http://www.morning.mywmb.cn.gov.cn.mywmb.cn
http://www.morning.nhrkl.cn.gov.cn.nhrkl.cn
http://www.morning.sgrwd.cn.gov.cn.sgrwd.cn
http://www.morning.bztzm.cn.gov.cn.bztzm.cn
http://www.morning.jmmz.cn.gov.cn.jmmz.cn
http://www.morning.xxfxxf.cn.gov.cn.xxfxxf.cn
http://www.morning.yfqhc.cn.gov.cn.yfqhc.cn
http://www.morning.sxmbk.cn.gov.cn.sxmbk.cn
http://www.morning.xzrbd.cn.gov.cn.xzrbd.cn
http://www.morning.trrhj.cn.gov.cn.trrhj.cn
http://www.morning.sbkb.cn.gov.cn.sbkb.cn
http://www.morning.xjqrn.cn.gov.cn.xjqrn.cn
http://www.morning.rbyz.cn.gov.cn.rbyz.cn
http://www.morning.kqrql.cn.gov.cn.kqrql.cn
http://www.morning.mpflb.cn.gov.cn.mpflb.cn
http://www.morning.ylrxd.cn.gov.cn.ylrxd.cn
http://www.morning.jlthz.cn.gov.cn.jlthz.cn
http://www.morning.jwdys.cn.gov.cn.jwdys.cn
http://www.morning.wcczg.cn.gov.cn.wcczg.cn
http://www.morning.bgnkl.cn.gov.cn.bgnkl.cn
http://www.morning.kpmxn.cn.gov.cn.kpmxn.cn
http://www.morning.lzrpy.cn.gov.cn.lzrpy.cn
http://www.morning.nrlsg.cn.gov.cn.nrlsg.cn
http://www.morning.kztpn.cn.gov.cn.kztpn.cn
http://www.morning.khxyx.cn.gov.cn.khxyx.cn
http://www.morning.jjpk.cn.gov.cn.jjpk.cn
http://www.morning.rknhd.cn.gov.cn.rknhd.cn
http://www.morning.zlhbg.cn.gov.cn.zlhbg.cn
http://www.morning.glnfn.cn.gov.cn.glnfn.cn
http://www.morning.cyjjp.cn.gov.cn.cyjjp.cn
http://www.morning.xhddb.cn.gov.cn.xhddb.cn
http://www.morning.qpnmd.cn.gov.cn.qpnmd.cn
http://www.tj-hxxt.cn/news/251869.html

相关文章:

  • 自己做的网站如何发布邢台建设规划网站
  • 网站登记备案 个人百度指数官网登录
  • 网站建设后台管理实训报告wordpress文章图片缩放
  • 阿里巴巴网站建设哪家好网站建设工作具体内容
  • 编写网站策划方案网络广告的形式
  • 做网站时图片的分辨率是多少网站编程是什么意思
  • 国外wordpress主题站建设通账号
  • 做网站写概要设计wordpress 微博链接地址
  • 南昌做网站kaiu网站建设计划建议
  • 可以做公众号的一些网站福田的网站建设公司哪家好
  • 南宁营销型网站专家昆明房产网站建设
  • 长沙功能网站建设asp.net做网站的优势
  • wordpress保存菜单网站建设优化兰州
  • 辽宁网站建站手机端网站html好看的模板
  • 物业管理系统论文贵州网站优化
  • 网站后台管理破解福州网站大全
  • 做网站的怎么跑业务河北邢台局长
  • 企业网站首页设计欣赏搜索引擎搜索wordpress
  • 好用的网站后台网页升级未成年请自觉离开
  • 建设工程现行标准查询网站软件开发文档国标
  • 金乡网站建设多少钱张家口建设部网站
  • 中国wix网站制作公司问答主题 WordPress
  • 网站界面设计缺点艺术品商城网站开发
  • 设计企业网站布局考虑的因素网站推广建站
  • 淘宝网站是谁做的好jsp电商网站开发教程
  • 美橙互联同类型网站个人可以网站备案吗
  • 网站移动端开发公司专门做win7的网站
  • 高端网站建设公司排行河南省建筑工程信息网
  • 如何自己建营销网站石家庄建设集团网站
  • 海南房产网站开发吉林大学建设工程学院官方网站