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

做网站的优势有哪些百度网站申诉

做网站的优势有哪些,百度网站申诉,wordpress怎么适应手机端,郑州小程序定制#x1f4a1;目录 效果图 界面设计思路 1. 基本布局 2. 视觉元素 游戏机制设计 基本规则 游戏代码 前期准备 游戏代码详解 数据结构设计 宏定义 数据结构定义 函数原型#xff08;详见后文#xff09; 主函数代码 核心代码 Review 效果图 界面设计思路 1. 基…目录 效果图 界面设计思路 1. 基本布局 2. 视觉元素 游戏机制设计 基本规则 游戏代码 前期准备 游戏代码详解 数据结构设计 宏定义 数据结构定义 函数原型详见后文 主函数代码 核心代码 Review 效果图 界面设计思路 1. 基本布局 游戏区域屏幕中央占据大部分面积用于显示游戏地图地图通常被设计成一个矩形网格每个单元格代表蛇可以移动的一个位置得分显示位于屏幕的顶部或角落实时更新并显示玩家当前的得分鼓励玩家追求更高的分数控制提示初学者友好设计简短说明如何控制蛇的移动如使用箭头键通常在游戏开始前或暂停时显示 2. 视觉元素 蛇使用不同的字符或颜色块来表示蛇的身体和头部头部可能有特殊标记以区分蛇移动时通过改变字符或颜色的位置来模拟动画效果食物采用醒目的颜色或符号使其在地图上易于识别吸引玩家去追逐边界地图边缘用特殊的符号或颜色加重提醒玩家避免碰撞 游戏机制设计 基本规则 移动玩家通过键盘控制蛇的前进方向蛇会在每一帧自动向前移动一格无法倒退或立即转向180度生长当蛇头触碰到食物时蛇的长度增加同时分数增加并在地图上的随机空白处生成新的食物死亡条件蛇碰到自己的身体或地图边界时游戏结束。此外可以设定时间限制或生命值系统增加挑战性速度控制玩家可通过按键调整蛇的移动速度 游戏代码 snake.h #pragma once#define _CRT_SECURE_NO_WARNINGS 1 #define _KEY_STATE(x) (GetAsyncKeyState(x)1?1:0) #define _SNAKE_LENTH_ 5 #define GAME_WIDTH 26 #define GAME_HEIGHT 26#includestdio.h #includestdlib.h #includewindows.h #includestdbool.h #includelocale.h #includeio.h #includefcntl.h #includetime.htypedef enum DIRECTION//蛇的方向 {UP,DOWN,LEFT,RIGHT }DIRECTION;typedef enum STATE//蛇的状态 {RUN,PAUSE,KILL_BY_SELF,KILL_BY_WALL }STATE;typedef struct Psnake //用于记录蛇的各个节点 {int x;int y;struct Psnake* next; }Psnake; Psnake* PsnakeNode;typedef struct Food {int x;int y;int score; }Food;typedef struct object {Psnake* psnakenode;Food food;int score;int speed;DIRECTION dir;STATE state; }object; object SNAKE;void set_pos(short x, short y);//设置光标坐标void cursor(bool state, int x);//设置光标可见性和大小void map();//打印地图void cover();//打印封面void GameStart();//游戏初始化void printInstruction(int y, const wchar_t* message);//打印提示信息void PrintFood(Food* pos);//打印食物void CreateFood(Psnake* snake);//创建食物bool FoodJudge(Psnake* next);//判断下一节点是否为食物Psnake* buynode(int x, int y);//申请节点Psnake* InitSnake(Psnake** head);//初始化蛇void PrintSnake(Psnake* head);//打印蛇void IsDie();//判断满足结束条件void SnakeMove(Psnake** head);//移动蛇void ClearScreen();//清屏void GameOver(int score);//游戏结束void GameRun(Psnake** head);//运行游戏void GameStart();//游戏前准备 snake.c #include snake.h//设置坐标 void set_pos(short x, short y) {HANDLE hConsole GetStdHandle(STD_OUTPUT_HANDLE);COORD coord;coord.X x;coord.Y y;SetConsoleCursorPosition(hConsole, coord); }//设置坐标//设置光标信息 void cursor(bool state, int x) {HANDLE op GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO con;con.dwSize x;con.bVisible state;SetConsoleCursorInfo(op, con); }//打印提示信息 void printInstruction(int y, const wchar_t* message) {set_pos(60, y);wprintf(message); }//打印地图 void map() {// Draw top borderset_pos(0, 0);for (int i 0; i 29; i) {wprintf(L□);}// Draw left and right bordersfor (int i 1; i 29; i) {set_pos(0, i);wprintf(L□);set_pos(28 * 2, i); //右边的坐标28*2 iwprintf(L□);}// Draw bottom borderset_pos(0, 29);for (int i 0; i 29; i) {wprintf(L□);}const wchar_t* instructions[] {L操作指南: 使用方向键←↑→↓,L速度控制: F2 加速, F3 减速,L暂停游戏: 按 P,L退出游戏: 按 ESC};for (int i 0; i sizeof(instructions) / sizeof(instructions[0]); i) {printInstruction(10 i, instructions[i]);} }//打印封面 void cover() {system(mode con cols120 lines50);system(title 贪吃蛇);set_pos(40, 10);wprintf(L \n);wprintf(L .-----------------. .-----------------. .----------------. .----------------. .---------------- .\n);wprintf(L | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |\n);wprintf(L | | _______ | || | ____ _____ | || | __ | || | ______ | || | ___ ____ | |\n);wprintf(L | | / ___ | | || ||_ \\ |_ _| | || | / \\ | || | . ___ | | || | |_ ||_ _| | |\n);wprintf(L | | | (__ \\_| | || | | \\ | | | || | / /\\ \\ | || | / . \\_| | || | | |_/ / | |\n);wprintf(L | | .___-. | || | | |\\ \\| | | || | / ____ \\ | || | | | | || | | __. | |\n);wprintf(L | | |\\____) | | || | _| |_\\ | |_ | || | / / \\ \\_ | || | \\ .___.\\ | || | _| | \\ \\_ | |\n);wprintf(L | | |_______. | || ||_____|\\____| | || ||____| |____|| || | ._____. | || | |____ || __|_| |\n);wprintf(L | | | || | | || | | || | | || | | |\n);wprintf(L | -------------- || -------------- || -------------- || -------------- || -------------- |\n);wprintf(L ---------------- --------------- ---------------- --------------- ---------------\n);set_pos(45, 29);system(pause);system(cls);map();}//打印食物坐标 void PrintFood(Food* pos) {set_pos((*pos).x, (*pos).y);wprintf(L◆); }//创造食物 void CreateFood(Psnake* snake) {Food* pos (Food*)malloc(sizeof(Food));if (!pos){perror(MALLOC FAILED:);return;}Psnake* cur snake;//生成随机数srand((unsigned int)time(NULL));again:(*pos).x (rand() % GAME_WIDTH 2) * 2; // rand() % 27 会得到0到26之间的数加2后变为2到28(*pos).y rand() % GAME_HEIGHT 2; // rand() % 27 会得到0到26之间的数加2后变为2到28(*pos).score 1;while (cur){if ((*pos).x cur-x (*pos).y cur-y)goto again;cur cur-next;}SNAKE.food *pos;PrintFood(pos); }//判断下一个节点是否为食物 bool FoodJudge(Psnake* next) {return ((next-x SNAKE.food.x) (next-y SNAKE.food.y)) ? true : false; }//申请一个节点 Psnake* buynode(int x,int y) {Psnake* newnode (Psnake*)calloc(1, sizeof(Psnake));if (newnode NULL){perror(calloc:);return NULL;}newnode-next NULL;newnode-x x;newnode-y y;return newnode; }//初始化蛇的信息 Psnake* InitSnake(Psnake**head) {if (!(head*head)) {fprintf(stderr, Memory allocation failed\n);return NULL;}(*head) (Psnake*)calloc(1, sizeof(Psnake));// 初始化成员(*head)-x 6;(*head)-y 10;(*head)-next NULL;Psnake* cur *head;if (!cur){perror(head is nullptr);return NULL;}int x _SNAKE_LENTH_;while (x--){Psnake* newnode buynode((cur-x)2, cur-y);newnode-next cur;cur newnode;}SNAKE.dir RIGHT;SNAKE.psnakenode cur;SNAKE.state RUN;SNAKE.speed 150;return cur; }//打印蛇 void PrintSnake(Psnake* head) {Psnake* cur SNAKE.psnakenode;while (cur){set_pos(cur-x, cur-y);wprintf(L●);cur cur-next;} }void IsDie() {Psnake* cur SNAKE.psnakenode-next; // 从第二个节点开始Psnake* prev SNAKE.psnakenode; // 保存蛇头节点用于比较while (cur-next) {cur cur-next;if (cur-x prev-x cur-y prev-y) { // 检查当前节点是否与之前的节点重合SNAKE.state KILL_BY_SELF;return;}}if (SNAKE.psnakenode-x 56||SNAKE.psnakenode-x0 ||SNAKE.psnakenode-y0||SNAKE.psnakenode-y 28) {SNAKE.state KILL_BY_WALL;return;} }//蛇的移动 void SnakeMove(Psnake** head) {// 首先检查蛇头的下一个位置Psnake* next (Psnake*)calloc(1, sizeof(Psnake));if (!next) {perror(Failed to allocate memory for next snake node);exit(EXIT_FAILURE);}// 根据当前方向设置蛇头的下一个位置switch (SNAKE.dir){case UP:next-x SNAKE.psnakenode-x;next-y SNAKE.psnakenode-y - 1;break;case DOWN:next-x SNAKE.psnakenode-x;next-y SNAKE.psnakenode-y 1;break;case LEFT:next-x SNAKE.psnakenode-x - 2;next-y SNAKE.psnakenode-y;break;case RIGHT:next-x SNAKE.psnakenode-x 2;next-y SNAKE.psnakenode-y;break;default:free(next);return; // 如果方向无效不移动蛇}// 检查下一个位置是否有食物if (FoodJudge(next)){SNAKE.score SNAKE.food.score; // 增加得分next-next (*head); // 将新节点放在头部*head next; // 更新头指针CreateFood(*head); // 生成新的食物}else{// 没有食物移动蛇的尾部到头部Psnake* tail SNAKE.psnakenode;Psnake* prev NULL;if (!(tail || prev)){perror(POINTER IS NULL:);return;}// 找到尾节点和其前一个节点while (tail-next) {prev tail;tail tail-next;}// 将尾部节点移动到头部prev-next NULL; // 将前一个节点的next设置为NULL它现在是尾部set_pos(tail-x, tail-y);wprintf(L );tail-next SNAKE.psnakenode; // 将原尾部节点放在头部SNAKE.psnakenode tail; // 更新头指针// 更新头部位置SNAKE.psnakenode-x next-x;SNAKE.psnakenode-y next-y;// 释放之前分配的next节点因为我们只是移动了尾部节点free(next);}IsDie();PrintSnake(SNAKE.psnakenode); }// //运行游戏void ClearScreen() { // 定义清屏函数适用于Windows和Linux/macOS #ifdef _WIN32system(cls); #elsesystem(clear); #endif }void GameOver(int score) {// 游戏结束后的善后处理ClearScreen(); // 清除屏幕wprintf(LGame Over!\n); // 打印游戏结束信息wprintf(L总分: %d\n, score); // 显示玩家得分// 询问玩家是否想再玩一次wprintf(L再来一次(y/n): );system(pause nul);if (_KEY_STATE(0x59)){GameStart();fflush(stdin);}else {wprintf(L感谢游玩\n);exit(0); // 结束程序} }void GameRun(Psnake**head) {do{set_pos(60, 6);wprintf(L当前分数: %d, SNAKE.score);if ((_KEY_STATE(VK_UP) || _KEY_STATE(0x57)) SNAKE.dir ! DOWN){SNAKE.dir UP;}else if ((_KEY_STATE(VK_DOWN) || _KEY_STATE(0x53)) SNAKE.dir ! UP){SNAKE.dir DOWN;}else if ((_KEY_STATE(VK_LEFT) || _KEY_STATE(0x41)) SNAKE.dir ! RIGHT){SNAKE.dir LEFT;}else if ((_KEY_STATE(VK_RIGHT) || _KEY_STATE(0x44)) SNAKE.dir ! LEFT){SNAKE.dir RIGHT;}else if (_KEY_STATE(0x71)SNAKE.speed0SNAKE.speed500){(SNAKE.speed) - 30;} else if (_KEY_STATE(0x72)SNAKE.speed0SNAKE.speed500){(SNAKE.speed) 30;}else if (_KEY_STATE(0x50)){SNAKE.speed 2147483647;}SnakeMove(head);Sleep(SNAKE.speed);} while (SNAKE.state RUN);GameOver(SNAKE.score); }//开始游戏及游戏前准备 void GameStart() {cover();SNAKE.psnakenode (Psnake*)malloc(sizeof(Psnake));InitSnake(SNAKE.psnakenode);PrintSnake(SNAKE.psnakenode);CreateFood(SNAKE.psnakenode);set_pos(40, 36);GameRun(SNAKE.psnakenode); } main.c #includesnake.hint main() { // 环境配置 // // 可打印宽字符_setmode(_fileno(stdout), _O_U16TEXT);//切换到本地setlocale(LC_ALL, );system(mode con cols10 lines20);set_pos(0, 20);cursor(false, 10); // // 正式开始GameStart();set_pos(0, 40);return 0; } 前期准备 在 visual studio 2022中默认窗口为cmd终端无法实现预期效果我们需要以下设置。若为其他开发环境请自查资料。 游戏代码详解 数据结构设计 snake.h #pragma once#define _CRT_SECURE_NO_WARNINGS 1 #define _KEY_STATE(x) (GetAsyncKeyState(x)1?1:0) #define _SNAKE_LENTH_ 5 #define GAME_WIDTH 26 #define GAME_HEIGHT 26#includestdio.h #includestdlib.h #includewindows.h #includestdbool.h #includelocale.h #includeio.h #includefcntl.h #includetime.htypedef enum DIRECTION//蛇的方向 {UP,DOWN,LEFT,RIGHT }DIRECTION;typedef enum STATE//蛇的状态 {RUN,PAUSE,KILL_BY_SELF,KILL_BY_WALL }STATE;typedef struct Psnake //用于记录蛇的各个节点 {int x;int y;struct Psnake* next; }Psnake; Psnake* PsnakeNode;typedef struct Food {int x;int y;int score; }Food;typedef struct object {Psnake* psnakenode;Food food;int score;int speed;DIRECTION dir;STATE state; }object; object SNAKE;void set_pos(short x, short y);//设置光标坐标void cursor(bool state, int x);//设置光标可见性和大小void map();//打印地图void cover();//打印封面void GameStart();//游戏初始化void printInstruction(int y, const wchar_t* message);//打印提示信息void PrintFood(Food* pos);//打印食物void CreateFood(Psnake* snake);//创建食物bool FoodJudge(Psnake* next);//判断下一节点是否为食物Psnake* buynode(int x, int y);//申请节点Psnake* InitSnake(Psnake** head);//初始化蛇void PrintSnake(Psnake* head);//打印蛇void IsDie();//判断满足结束条件void SnakeMove(Psnake** head);//移动蛇void ClearScreen();//清屏void GameOver(int score);//游戏结束void GameRun(Psnake** head);//运行游戏void GameStart();//游戏前准备 宏定义 #pragma once: 用于防止头文件被重复包含。_CRT_SECURE_NO_WARNINGS 1: 禁用Visual Studio中的某些不安全函数警告比如使用scanf等。_KEY_STATE(x) (GetAsyncKeyState(x)1?1:0): 自定义宏用来检查给定虚拟键是否被按下。GetAsyncKeyState是Windows API函数( 配合虚拟键码使用 )用于检查按键状态。_SNAKE_LENTH_ 5: 定义初始蛇的长度为5个单位。GAME_WIDTH 26 和 GAME_HEIGHT 26: 定义游戏地图的宽度和高度均为26个单位。 数据结构定义 enum DIRECTION: 定义蛇的移动方向包括上、下、左、右。enum STATE: 定义蛇的状态包括运行中、暂停、自杀死亡、撞墙死亡。struct Psnake: 蛇的节点结构体包含位置坐标(x, y)和指向下一个节点的指针。struct Food: 食物结构体包含位置坐标(x, y)和分数。struct object: 游戏对象结构体整合蛇、食物、得分、速度、方向和状态等游戏所需的所有信息。 将蛇、食物抽象成一个结构体用宽字符来打印enum STATE、enum DIRECTION 来表示蛇的状态。将以上数据放在object结构体中进行管理。 函数原型详见后文 set_pos(short x, short y): 设置控制台光标位置。cursor(bool state, int x): 设置控制台光标的可见性和大小。map(): 打印游戏地图。cover(): 打印游戏封面。GameStart(): 游戏初始化入口可能包含了封面展示、地图绘制、蛇的初始化等。printInstruction(int y, const wchar_t* message): 在指定行打印宽字符格式的提示信息。PrintFood(Food* pos): 在指定位置打印食物。CreateFood(Psnake* snake): 随机生成食物并确保不与蛇身重叠。FoodJudge(Psnake* next): 判断蛇的下一个位置是否为食物。buynode(int x, int y): 申请一个新的蛇节点内存。InitSnake(Psnake** head): 初始化蛇的链表结构。PrintSnake(Psnake* head): 打印蛇的当前位置。IsDie(): 判断游戏是否结束即蛇是否撞墙或自相残杀。SnakeMove(Psnake** head): 处理蛇的移动逻辑包括方向改变和吃到食物的处理。ClearScreen(): 清除屏幕内容。GameOver(int score): 游戏结束时的操作显示分数并可能询问是否重新开始。GameRun(Psnake** head): 游戏主循环处理用户输入和游戏逻辑。 整个框架围绕着贪吃蛇的基本逻辑展开包括了游戏的初始化、地图绘制、蛇的移动与增长、食物的生成与检测、游戏状态管理以及用户交互。 主函数代码 main.c #includesnake.hint main() { // 环境配置 // // 可打印宽字符_setmode(_fileno(stdout), _O_U16TEXT);//切换到本地setlocale(LC_ALL, );system(mode con cols10 lines20);set_pos(0, 20);cursor(false, 10); // // 正式开始GameStart();set_pos(0, 40);return 0; } _setmode(_fileno(stdout) , _O_U16TEXT);    将输出模式设置为 _O_U16TEXT 模式以便后续打印宽字符。 _setmode 函数来自 io.h 头文件。_fileno 函数来自 stdio.h 头文件。_O_U16TEXT 宏定义通常在 fcntl.h 或 io.h 中找到 setlocale(LC_ARR,);    切换到本地模式 LC_ALL是一个宏代表所有类别包括日期和时间格式、数字表示、货币符号、语言等。使用 LC_ALL 意味着你想改变所有方面的区域设置。 作为第二个参数是一个特殊的值它告诉函数使用用户默认的或者环境变量如 LANG 或 LC_ALL指定的区域设置。 system(mode con cols10 lines20);     将窗口设置为20行高10列宽在vs控制台中字符高度一致但宽度不一致一般来说宽字符是窄字符的两倍为了达到预期效果需按照以上比例设置。 set_pos(0,20);      设置打印字符的位置这是我自己封装的函数后续会讲到。 cursor(false,10);    设置光标状态自己封装的函数后续会讲到。 GameStart();    正式进入游戏。跳转到snake.c文件中。 核心代码 snake.c #include snake.h//设置坐标 void set_pos(short x, short y) {HANDLE hConsole GetStdHandle(STD_OUTPUT_HANDLE);COORD coord;coord.X x;coord.Y y;SetConsoleCursorPosition(hConsole, coord); }//设置坐标//设置光标信息 void cursor(bool state, int x) {HANDLE op GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO con;con.dwSize x;con.bVisible state;SetConsoleCursorInfo(op, con); }//打印提示信息 void printInstruction(int y, const wchar_t* message) {set_pos(60, y);wprintf(message); }//打印地图 void map() {// Draw top borderset_pos(0, 0);for (int i 0; i 29; i) {wprintf(L□);}// Draw left and right bordersfor (int i 1; i 29; i) {set_pos(0, i);wprintf(L□);set_pos(28 * 2, i); //右边的坐标28*2 iwprintf(L□);}// Draw bottom borderset_pos(0, 29);for (int i 0; i 29; i) {wprintf(L□);}const wchar_t* instructions[] {L操作指南: 使用方向键←↑→↓,L速度控制: F2 加速, F3 减速,L暂停游戏: 按 P,L退出游戏: 按 ESC};for (int i 0; i sizeof(instructions) / sizeof(instructions[0]); i) {printInstruction(10 i, instructions[i]);} }//打印封面 void cover() {system(mode con cols120 lines50);system(title 贪吃蛇);set_pos(40, 10);wprintf(L \n);wprintf(L .-----------------. .-----------------. .----------------. .----------------. .---------------- .\n);wprintf(L | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |\n);wprintf(L | | _______ | || | ____ _____ | || | __ | || | ______ | || | ___ ____ | |\n);wprintf(L | | / ___ | | || ||_ \\ |_ _| | || | / \\ | || | . ___ | | || | |_ ||_ _| | |\n);wprintf(L | | | (__ \\_| | || | | \\ | | | || | / /\\ \\ | || | / . \\_| | || | | |_/ / | |\n);wprintf(L | | .___-. | || | | |\\ \\| | | || | / ____ \\ | || | | | | || | | __. | |\n);wprintf(L | | |\\____) | | || | _| |_\\ | |_ | || | / / \\ \\_ | || | \\ .___.\\ | || | _| | \\ \\_ | |\n);wprintf(L | | |_______. | || ||_____|\\____| | || ||____| |____|| || | ._____. | || | |____ || __|_| |\n);wprintf(L | | | || | | || | | || | | || | | |\n);wprintf(L | -------------- || -------------- || -------------- || -------------- || -------------- |\n);wprintf(L ---------------- --------------- ---------------- --------------- ---------------\n);set_pos(45, 29);system(pause);system(cls);map();}//打印食物坐标 void PrintFood(Food* pos) {set_pos((*pos).x, (*pos).y);wprintf(L◆); }//创造食物 void CreateFood(Psnake* snake) {Food* pos (Food*)malloc(sizeof(Food));if (!pos){perror(MALLOC FAILED:);return;}Psnake* cur snake;//生成随机数srand((unsigned int)time(NULL));again:(*pos).x (rand() % GAME_WIDTH 2) * 2; // rand() % 27 会得到0到26之间的数加2后变为2到28(*pos).y rand() % GAME_HEIGHT 2; // rand() % 27 会得到0到26之间的数加2后变为2到28(*pos).score 1;while (cur){if ((*pos).x cur-x (*pos).y cur-y)goto again;cur cur-next;}SNAKE.food *pos;PrintFood(pos); }//判断下一个节点是否为食物 bool FoodJudge(Psnake* next) {return ((next-x SNAKE.food.x) (next-y SNAKE.food.y)) ? true : false; }//申请一个节点 Psnake* buynode(int x,int y) {Psnake* newnode (Psnake*)calloc(1, sizeof(Psnake));if (newnode NULL){perror(calloc:);return NULL;}newnode-next NULL;newnode-x x;newnode-y y;return newnode; }//初始化蛇的信息 Psnake* InitSnake(Psnake**head) {if (!(head*head)) {fprintf(stderr, Memory allocation failed\n);return NULL;}(*head) (Psnake*)calloc(1, sizeof(Psnake));// 初始化成员(*head)-x 6;(*head)-y 10;(*head)-next NULL;Psnake* cur *head;if (!cur){perror(head is nullptr);return NULL;}int x _SNAKE_LENTH_;while (x--){Psnake* newnode buynode((cur-x)2, cur-y);newnode-next cur;cur newnode;}SNAKE.dir RIGHT;SNAKE.psnakenode cur;SNAKE.state RUN;SNAKE.speed 150;return cur; }//打印蛇 void PrintSnake(Psnake* head) {Psnake* cur SNAKE.psnakenode;while (cur){set_pos(cur-x, cur-y);wprintf(L●);cur cur-next;} }void IsDie() {Psnake* cur SNAKE.psnakenode-next; // 从第二个节点开始Psnake* prev SNAKE.psnakenode; // 保存蛇头节点用于比较while (cur-next) {cur cur-next;if (cur-x prev-x cur-y prev-y) { // 检查当前节点是否与之前的节点重合SNAKE.state KILL_BY_SELF;return;}}if (SNAKE.psnakenode-x 56||SNAKE.psnakenode-x0 ||SNAKE.psnakenode-y0||SNAKE.psnakenode-y 28) {SNAKE.state KILL_BY_WALL;return;} }//蛇的移动 void SnakeMove(Psnake** head) {// 首先检查蛇头的下一个位置Psnake* next (Psnake*)calloc(1, sizeof(Psnake));if (!next) {perror(Failed to allocate memory for next snake node);exit(EXIT_FAILURE);}// 根据当前方向设置蛇头的下一个位置switch (SNAKE.dir){case UP:next-x SNAKE.psnakenode-x;next-y SNAKE.psnakenode-y - 1;break;case DOWN:next-x SNAKE.psnakenode-x;next-y SNAKE.psnakenode-y 1;break;case LEFT:next-x SNAKE.psnakenode-x - 2;next-y SNAKE.psnakenode-y;break;case RIGHT:next-x SNAKE.psnakenode-x 2;next-y SNAKE.psnakenode-y;break;default:free(next);return; // 如果方向无效不移动蛇}// 检查下一个位置是否有食物if (FoodJudge(next)){SNAKE.score SNAKE.food.score; // 增加得分next-next (*head); // 将新节点放在头部*head next; // 更新头指针CreateFood(*head); // 生成新的食物}else{// 没有食物移动蛇的尾部到头部Psnake* tail SNAKE.psnakenode;Psnake* prev NULL;if (!(tail || prev)){perror(POINTER IS NULL:);return;}// 找到尾节点和其前一个节点while (tail-next) {prev tail;tail tail-next;}// 将尾部节点移动到头部prev-next NULL; // 将前一个节点的next设置为NULL它现在是尾部set_pos(tail-x, tail-y);wprintf(L );tail-next SNAKE.psnakenode; // 将原尾部节点放在头部SNAKE.psnakenode tail; // 更新头指针// 更新头部位置SNAKE.psnakenode-x next-x;SNAKE.psnakenode-y next-y;// 释放之前分配的next节点因为我们只是移动了尾部节点free(next);}IsDie();PrintSnake(SNAKE.psnakenode); }// //运行游戏void ClearScreen() { // 定义清屏函数适用于Windows和Linux/macOS #ifdef _WIN32system(cls); #elsesystem(clear); #endif }void GameOver(int score) {// 游戏结束后的善后处理ClearScreen(); // 清除屏幕wprintf(LGame Over!\n); // 打印游戏结束信息wprintf(L总分: %d\n, score); // 显示玩家得分// 询问玩家是否想再玩一次wprintf(L再来一次(y/n): );system(pause nul);if (_KEY_STATE(0x59)){GameStart();fflush(stdin);}else {wprintf(L感谢游玩\n);exit(0); // 结束程序} }void GameRun(Psnake**head) {do{set_pos(60, 6);wprintf(L当前分数: %d, SNAKE.score);if ((_KEY_STATE(VK_UP) || _KEY_STATE(0x57)) SNAKE.dir ! DOWN){SNAKE.dir UP;}else if ((_KEY_STATE(VK_DOWN) || _KEY_STATE(0x53)) SNAKE.dir ! UP){SNAKE.dir DOWN;}else if ((_KEY_STATE(VK_LEFT) || _KEY_STATE(0x41)) SNAKE.dir ! RIGHT){SNAKE.dir LEFT;}else if ((_KEY_STATE(VK_RIGHT) || _KEY_STATE(0x44)) SNAKE.dir ! LEFT){SNAKE.dir RIGHT;}else if (_KEY_STATE(0x71)SNAKE.speed0SNAKE.speed500){(SNAKE.speed) - 30;} else if (_KEY_STATE(0x72)SNAKE.speed0SNAKE.speed500){(SNAKE.speed) 30;}else if (_KEY_STATE(0x50)){SNAKE.speed 2147483647;}SnakeMove(head);Sleep(SNAKE.speed);} while (SNAKE.state RUN);GameOver(SNAKE.score); }//开始游戏及游戏前准备 void GameStart() {cover();SNAKE.psnakenode (Psnake*)malloc(sizeof(Psnake));InitSnake(SNAKE.psnakenode);PrintSnake(SNAKE.psnakenode);CreateFood(SNAKE.psnakenode);set_pos(40, 36);GameRun(SNAKE.psnakenode); } 1.    set_pos( short  x , short y )  void set_pos(short x, short y) {HANDLE hConsole GetStdHandle(STD_OUTPUT_HANDLE);COORD coord;coord.X x;coord.Y y;SetConsoleCursorPosition(hConsole, coord); }//设置坐标 作用: 设置光标在控制台上的位置以便在指定坐标输出字符。思路: 使用GetStdHandle获得控制台光标句柄 --- 修改值 --- SetConsoleCursorPosition实现对光标的控制。            注SetConsoleCursorPosition的使用需一个COORD结构体将x和y改成目标值。 知识点: Windows API使用、句柄概念、坐标系统。 2.    cursor ( bool state , short x )  //设置光标信息 void cursor(bool state, int x) {HANDLE op GetStdHandle(STD_OUTPUT_HANDLE);CONSOLE_CURSOR_INFO con;con.dwSize x;con.bVisible state;SetConsoleCursorInfo(op, con); } 作用: 控制光标的显示状态可见或隐藏及大小。思路: 使用 GetStdHandle 获得光标句柄 --- 进行值的修改 --- 使用SetConsoleCursorInfo进行设置 。 注SetConsoleCursorInfo需要定义 CONSOLE_CURSOR_INFO类型的结构体 知识点: 控制台编程、光标属性设置。 3. printInstruction( int y , const wchar_t* message ) //打印提示信息 void printInstruction(int y, const wchar_t* message) {set_pos(60, y);wprintf(message); } 作用: 在指定的行上打印游戏的指令或提示信息。思路: 调用set_pos定位光标然后使用宽字符输出信息。知识点: 宽字符输出、动态打印信息布局。 4.  map( ) //打印地图 void map() {// Draw top borderset_pos(0, 0);for (int i 0; i 29; i) {wprintf(L□);}// Draw left and right bordersfor (int i 1; i 29; i) {set_pos(0, i);wprintf(L□);set_pos(28 * 2, i); //右边的坐标28*2 iwprintf(L□);}// Draw bottom borderset_pos(0, 29);for (int i 0; i 29; i) {wprintf(L□);}const wchar_t* instructions[] {L操作指南: 使用方向键←↑→↓,L速度控制: F2 加速, F3 减速,L暂停游戏: 按 P,L退出游戏: 按 ESC};for (int i 0; i sizeof(instructions) / sizeof(instructions[0]); i) {printInstruction(10 i, instructions[i]);} } 作用: 绘制游戏的地图边界和游戏说明。思路: 分别绘制上、下、左、右边界并在固定位置打印游戏规则。 注宽字符打印需要wprintfwprintf( L   ) ; 知识点: 循环结构、字符串输出、坐标计算。 5.  cover ( ) //打印封面 void cover() {system(mode con cols120 lines50);system(title 贪吃蛇);set_pos(40, 10);wprintf(L \n);wprintf(L .-----------------. .-----------------. .----------------. .----------------. .---------------- .\n);wprintf(L | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |\n);wprintf(L | | _______ | || | ____ _____ | || | __ | || | ______ | || | ___ ____ | |\n);wprintf(L | | / ___ | | || ||_ \\ |_ _| | || | / \\ | || | . ___ | | || | |_ ||_ _| | |\n);wprintf(L | | | (__ \\_| | || | | \\ | | | || | / /\\ \\ | || | / . \\_| | || | | |_/ / | |\n);wprintf(L | | .___-. | || | | |\\ \\| | | || | / ____ \\ | || | | | | || | | __. | |\n);wprintf(L | | |\\____) | | || | _| |_\\ | |_ | || | / / \\ \\_ | || | \\ .___.\\ | || | _| | \\ \\_ | |\n);wprintf(L | | |_______. | || ||_____|\\____| | || ||____| |____|| || | ._____. | || | |____ || __|_| |\n);wprintf(L | | | || | | || | | || | | || | | |\n);wprintf(L | -------------- || -------------- || -------------- || -------------- || -------------- |\n);wprintf(L ---------------- --------------- ---------------- --------------- ---------------\n);set_pos(45, 29);system(pause);system(cls);map();} 作用: 打印游戏封面。思路: 使用特殊字符和格式化输出来设计一个吸引人的启动画面随后清除屏幕并进入游戏。知识点: 字符串操作、系统调用改变窗口尺寸、标题、多行输出。 6. void PrintFoodFood* pos //打印食物坐标 void PrintFood(Food* pos) {set_pos((*pos).x, (*pos).y);wprintf(L◆); } 作用: 在指定位置打印食物图标。思路: 移动光标至食物坐标输出食物的符号。Food 在 snake.h 会详解知识点: 结构体使用、函数传参。 7. CreateFood ( Psnake* snake ) //创造食物 void CreateFood(Psnake* snake) {Food* pos (Food*)malloc(sizeof(Food));if (!pos){perror(MALLOC FAILED:);return;}Psnake* cur snake;//生成随机数srand((unsigned int)time(NULL));again:(*pos).x (rand() % GAME_WIDTH 2) * 2; // rand() % 27 会得到0到26之间的数加2后变为2到28(*pos).y rand() % GAME_HEIGHT 2; // rand() % 27 会得到0到26之间的数加2后变为2到28(*pos).score 1;while (cur){if ((*pos).x cur-x (*pos).y cur-y)goto again;cur cur-next;}SNAKE.food *pos;PrintFood(pos); } 作用: 随机生成食物并确保不与蛇身重叠。思路: 使用 rand 随机生成食物 x、y 坐标食物遍历贪吃蛇每个节点的坐标然后更新食物位置信息。知识点: 随机数生成、链表遍历、内存管理malloc。 8. FoodJudge(Psnake* next) //判断下一个节点是否为食物 bool FoodJudge(Psnake* next) {return ((next-x SNAKE.food.x) (next-y SNAKE.food.y)) ? true : false; } 作用: 判断下一个节点位置是否为食物所在。思路: 比较节点坐标与食物坐标。知识点: 简单逻辑判断、结构体成员访问。 9.buynode(int x, int y) //申请一个节点 Psnake* buynode(int x,int y) {Psnake* newnode (Psnake*)calloc(1, sizeof(Psnake));if (newnode NULL){perror(calloc:);return NULL;}newnode-next NULL;newnode-x x;newnode-y y;return newnode; } 作用: 创建一个新的蛇节点。思路: 申请内存初始化节点数据链接到链表。 蛇按照方向进行移动需要对蛇头的前左右进行申请节点 知识点: 动态内存分配、链表操作。 10.InitSnake(Psnake**head) //初始化蛇的信息 Psnake* InitSnake(Psnake**head) {if (!(head*head)) {fprintf(stderr, Memory allocation failed\n);return NULL;}(*head) (Psnake*)calloc(1, sizeof(Psnake));// 初始化成员(*head)-x 6;(*head)-y 10;(*head)-next NULL;Psnake* cur *head;if (!cur){perror(head is nullptr);return NULL;}int x _SNAKE_LENTH_;while (x--){Psnake* newnode buynode((cur-x)2, cur-y);newnode-next cur;cur newnode;}SNAKE.dir RIGHT;SNAKE.psnakenode cur;SNAKE.state RUN;SNAKE.speed 150;return cur; }作用: 初始化蛇的结构创建初始蛇身。思路: 设置蛇头位置、按照长度申请节点并设置蛇其他信息知识点: 指针引用、循环构造链表、内存管理。 11.PrintSnake(Psnake* head) //打印蛇 void PrintSnake(Psnake* head) {Psnake* cur SNAKE.psnakenode;while (cur){set_pos(cur-x, cur-y);wprintf(L●);cur cur-next;} }作用: 打印蛇身在屏幕上。思路: 遍历链表逐个输出蛇身位置的字符。知识点: 链表遍历、光标移动打印。 12. IsDie() void IsDie() {Psnake* cur SNAKE.psnakenode-next; // 从第二个节点开始Psnake* prev SNAKE.psnakenode; // 保存蛇头节点用于比较while (cur-next) {cur cur-next;if (cur-x prev-x cur-y prev-y) { // 检查当前节点是否与之前的节点重合SNAKE.state KILL_BY_SELF;return;}}if (SNAKE.psnakenode-x 56||SNAKE.psnakenode-x0 ||SNAKE.psnakenode-y0||SNAKE.psnakenode-y 28) {SNAKE.state KILL_BY_WALL;return;} } 作用: 检查游戏是否结束撞墙或自食。思路: 检测是否撞到自身将蛇头坐标与每个蛇身节点坐标相比较撞墙蛇头与游戏边界重叠。之后将蛇的状态修改。知识点: 边界条件检测、循环逻辑。 13. SnakeMove(Psnake** head) //蛇的移动 void SnakeMove(Psnake** head) {// 首先检查蛇头的下一个位置Psnake* next (Psnake*)calloc(1, sizeof(Psnake));if (!next) {perror(Failed to allocate memory for next snake node);exit(EXIT_FAILURE);}// 根据当前方向设置蛇头的下一个位置switch (SNAKE.dir){case UP:next-x SNAKE.psnakenode-x;next-y SNAKE.psnakenode-y - 1;break;case DOWN:next-x SNAKE.psnakenode-x;next-y SNAKE.psnakenode-y 1;break;case LEFT:next-x SNAKE.psnakenode-x - 2;next-y SNAKE.psnakenode-y;break;case RIGHT:next-x SNAKE.psnakenode-x 2;next-y SNAKE.psnakenode-y;break;default:free(next);return; // 如果方向无效不移动蛇}// 检查下一个位置是否有食物if (FoodJudge(next)){SNAKE.score SNAKE.food.score; // 增加得分next-next (*head); // 将新节点放在头部*head next; // 更新头指针CreateFood(*head); // 生成新的食物}else{// 没有食物移动蛇的尾部到头部Psnake* tail SNAKE.psnakenode;Psnake* prev NULL;if (!(tail || prev)){perror(POINTER IS NULL:);return;}// 找到尾节点和其前一个节点while (tail-next) {prev tail;tail tail-next;}// 将尾部节点移动到头部prev-next NULL; // 将前一个节点的next设置为NULL它现在是尾部set_pos(tail-x, tail-y);wprintf(L );tail-next SNAKE.psnakenode; // 将原尾部节点放在头部SNAKE.psnakenode tail; // 更新头指针// 更新头部位置SNAKE.psnakenode-x next-x;SNAKE.psnakenode-y next-y;// 释放之前分配的next节点因为我们只是移动了尾部节点free(next);}IsDie();PrintSnake(SNAKE.psnakenode); } 作用: 处理蛇的移动逻辑包括食物检测和身体跟随。思路:申请三个节点蛇头前左右 用switch对蛇的方向进行判断先让蛇头走一步判断该方向下一节点是否为食物将蛇身剩下的节点逐个移动一个节点。 移动分两部分蛇头移动和蛇身移动先让蛇头走一步蛇身每个节点进行移动 知识点: 方向判断、链表头节点更新、内存释放。 14.ClearScreen( ) void ClearScreen() { // 定义清屏函数适用于Windows和Linux/macOS #ifdef _WIN32system(cls); #elsesystem(clear); #endif } 作用: 清除屏幕内容。思路: 根据操作系统调用不同的清屏命令。 #ifdef 与 #endif 要成对存在 知识点: 条件编译、系统调用。 15.GameOver( int score ) void GameOver(int score) {// 游戏结束后的善后处理ClearScreen(); // 清除屏幕wprintf(LGame Over!\n); // 打印游戏结束信息wprintf(L总分: %d\n, score); // 显示玩家得分// 询问玩家是否想再玩一次wprintf(L再来一次(y/n): );system(pause nul);if (_KEY_STATE(0x59)){GameStart();fflush(stdin);}else {wprintf(L感谢游玩\n);exit(0); // 结束程序} } 作用: 游戏结束时显示分数并询问是否重新开始。思路: 显示最终得分根据用户输入决定是否重启游戏。 system(pausenul); 与 system(pause); 效果类似后者会打印按任意键继续字样前者不会 知识点: 用户输入读取、流程控制。 16.  GameRun(Psnake**head) void GameRun(Psnake**head) {do{set_pos(60, 6);wprintf(L当前分数: %d, SNAKE.score);if ((_KEY_STATE(VK_UP) || _KEY_STATE(0x57)) SNAKE.dir ! DOWN){SNAKE.dir UP;}else if ((_KEY_STATE(VK_DOWN) || _KEY_STATE(0x53)) SNAKE.dir ! UP){SNAKE.dir DOWN;}else if ((_KEY_STATE(VK_LEFT) || _KEY_STATE(0x41)) SNAKE.dir ! RIGHT){SNAKE.dir LEFT;}else if ((_KEY_STATE(VK_RIGHT) || _KEY_STATE(0x44)) SNAKE.dir ! LEFT){SNAKE.dir RIGHT;}else if (_KEY_STATE(0x71)SNAKE.speed0SNAKE.speed500){(SNAKE.speed) - 30;} else if (_KEY_STATE(0x72)SNAKE.speed0SNAKE.speed500){(SNAKE.speed) 30;}else if (_KEY_STATE(0x50)){SNAKE.speed 2147483647;}SnakeMove(head);Sleep(SNAKE.speed);} while (SNAKE.state RUN);GameOver(SNAKE.score); } 作用: 游戏主循环处理用户输入和游戏逻辑。思路: 此处do while效果要比while效果要好通过检测检测按键状态来确定蛇的移动方向。 虚拟键码Virtual Key Codes是在计算机键盘输入中使用的一套编码标准用于标识键盘上的每一个按键无论键盘的实际物理布局如何。 知识点: 主循环控制、事件响应、时间延迟。 17.  GameStart () //开始游戏及游戏前准备 void GameStart() {cover();SNAKE.psnakenode (Psnake*)malloc(sizeof(Psnake));InitSnake(SNAKE.psnakenode);PrintSnake(SNAKE.psnakenode);CreateFood(SNAKE.psnakenode);set_pos(40, 36);GameRun(SNAKE.psnakenode); } 作用: 游戏启动入口包含初始化、封面展示和游戏开始。思路: 先展示封面初始化游戏环境然后进入游戏主循环。 将蛇“创建”出来作为游戏运行的主体 知识点: 函数调用顺序、程序入口点。 Review 整理一下思路 需求分析 明确游戏目标控制蛇吃食物变长避免碰撞自身或边界。确定基本功能初始化游戏、绘制游戏界面、处理用户输入、蛇的移动与增长、食物的随机生成、碰撞检测、得分计算、游戏结束与重开机制。 技术选型与环境搭建 准备vs2022 核心模块设计 游戏界面设计简洁直观的游戏界面包括游戏区域、分数显示、游戏说明等。蛇的实现 数据结构链表或数组来存储蛇身的各个部分。移动逻辑根据用户输入改变蛇头方向自动延伸蛇身。食物管理随机位置生成食物检测蛇头碰撞并重新生成。碰撞检测检查蛇头是否触碰边界或自身身体。得分系统每次吃到食物增加分数记录最高分。 用户交互 接收用户输入键盘/触摸转换为游戏内操作指令。提供开始新游戏、退出游戏等选项。 性能与优化 优化游戏循环确保流畅运行。考虑内存管理避免内存泄漏。 在这个数字编织的宇宙中你已悄然绘制了一条属于自己的璀璨轨迹。         每一次思考与实践都在为你的技能之树浇灌成长的甘露。愿你带着这份宝贵的经历继续遨游于代码的星辰大海发现更多的奇遇与美好。       加油程序员之旅的探险者们前路广阔星辰大海我们共勉✨
http://www.dnsts.com.cn/news/116713.html

相关文章:

  • 事业单位网站备案百度升级最新版本下载安装
  • 网站开发和网站制作的区别预售网站开发
  • 土巴兔网站开发开封景区网站建设方案
  • 合肥网站建设王道下拉??安卓Wordpress汉化版
  • 网站开发业务好做吗管理咨询公司注册资本
  • 蓝色网站素材wordpress数据表格作用
  • 桥梁建设杂志网站高明网站设计服务
  • 网站怎么搭建盐渎网
  • 作品推广开封seo推广
  • 网站建设插件网站检测
  • 网站接单做项目广安网络推广
  • 苏州好的做网站的公司有哪些网站目录怎么做
  • 好的设计师互动网站昆明网站建设技术公司
  • 建站公司 网络服务阜阳建设工程质量监督局网站
  • 网站文章怎么做分享qq私人注册企业邮箱
  • 江门公司做网站青岛公司网站建设公司
  • 做静态网站的软件行业网站模板
  • 项目合作网站工业软件开发工具
  • 互联网门户网站是什么WordPress仿站助手
  • seo网站源码魔站网站开发
  • 重庆做网站建设网站建设与设计ppt模板下载
  • 公司网站备案必须是企业信息么撰写网站建设策划书范文
  • 网站开发 写文档安装wordpress+000
  • 网站设计用什么字体好网站分哪些种类
  • 开发工程师网站开发工程师做业务不花钱的网站有哪些
  • 桂林公司做网站怎么做游戏代理
  • 哪些网站是用php编写的怎么在服务器里面建设网站
  • 中信建设有限责任公司项目人员配置百度seo网站优化怎么做
  • 建设一个会员积分网站建设网站费用如何入账
  • 做水果网站行阜阳讯拓网站建设