In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "how to realize gluttonous snake in C language". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how C language realizes gluttonous snakes.
First, the game description 1.1 game button description
Press the direction keys up and down, you can change the direction of snake movement.
Press one of the direction keys up and down for a short time, which can accelerate the snake to move in that direction for a short time.
Press the space bar to pause, press any key to continue the game after the pause.
Press the ESC key to exit the game directly. Press the R key to restart the game.
1.2 scoring system
Keep the highest player record in history
Second, the game runs 2.1 the game effect is displayed
2.2 Correction of an error report
If this happens, please believe that this is the problem with the compiler.
(in order to prevent this article from being too long, some knowledge points that do not affect the logic of the game are displayed in the form of links.)
Solution.
2.3 Game Code
Description: the code test environment is visual studio 2017
Music file (extraction code 6666)
# include# include#pragma comment (lib, "Winmm.lib") / / define the size of the game interface first Define the number of rows and columns in the game area # define ROW 22 / / number of rows in the game area # define COL 42 / / number of rows in the game area # define KONG 0 / / marked empty (nothing) # define WALL 1 / / marked wall # define FOOD 2 / / marked food # define HEAD 3 / / marked snakehead # define BODY 4 / / marked snake body # define UP 72 / / direction key: up # define DOWN 80 / / direction key: down # define LEFT 75 / / direction key : left # define RIGHT 77 / / arrow key: right # define SPACE 32 / / pause # define ESC 27 / exit / / Snakehead struct Snake {int len / / record snake body length int x; / / snake head Abscissa int y; / / Snake head ordinate} snake; / / Snake body struct Body {int x; / / Snake body Abscissa int y; / / Snake body ordinate} body [row * COL]; / / Open up an array of structures sufficient to store snake bodies [ROW] [COL] Store the location of the game area, such as wall or empty or snake body, snake head, you can achieve the goal by storing different numbers on the menu bar void menu (); / / hide the cursor void HideCursor (); / / cursor jump void CursorJump (int x, int y); / / initialize the interface void InitInterface (); / / color setting void color (int c); / / read the highest score void ReadGrade from the file () / / update the highest score file void WriteGrade (); / / initialize snake void InitSnake (); / / randomly generate food void RandFood (); / / judge score and end void JudgeFunc (int x, int y); / / print snake and overlay snake void DrawSnake (int flag); / / Mobile snake void MoveSnake (int x, int y); / / execute keys void run (int x, int y); / / Game subject logic function void Game (); int max, grade / / Global variable int main () {/ / # pragma warning (disable: n) sets an alert to fail # pragma warning (disable:4996) / / you can use the library function menu () provided by the standard C language; max = 0, grade = 0; / / initialize the variable srand ((size_t) time (NULL)) / / generate random seed system ("title gluttonous Snake") according to the current time; / / set the name of the cmd window system ("mode con cols=84 lines=23"); / / set the size of the cmd window HideCursor (); / / hide the cursor ReadGrade (); / / read the highest score from the file to the max variable InitInterface (); / / initialize the interface InitSnake () / / initialize snake RandFood (); / / randomly generate food DrawSnake (1); / / print snake PlaySound (TEXT ("bgmusic.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); Game (); / / start the game return 0;} void menu () {system ("title gluttonous Snake"); system ("mode con cols=84 lines=23") / / set the size of the cmd window color (14); / / set the text to light yellow printf ("*\ n") Printf ("* Welcome to the game of Snake! *\ n "); printf (" *\ n ") Printf ("* press the arrow keys up and down to change the direction of snake movement *\ n") Printf ("*\ n") Printf ("* Press the spacebar to pause, press any key to continue the game *\ n") Printf ("*\ n") Printf ("* press the Esc key to exit the game directly * *\ n") Printf ("* press R key to restart the game *\ n") Printf ("*\ n"); system ("pause") } / / when developing game programs in C language, for the problem of cursor flicker, you can hide the cursor function to solve void HideCursor () {CONSOLE_CURSOR_INFO curInfo; / / define the structure variable of cursor information, header file curInfo.dwSize = 1; / / if no value is assigned, cursor hiding is invalid / / curInfo.bVisible = TRUE; / / set the cursor to visible curInfo.bVisible = FALSE / / set the cursor to invisible HANDLE handle = GetStdHandle (STD_OUTPUT_HANDLE); / / get the console handle SetConsoleCursorInfo (handle, & curInfo); / / set cursor information} / / cursor jump void CursorJump (int x, int y) {COORD pos; / / the structure variable pos.X = x; / / Abscissa pos.Y = y that defines the location of the cursor / / ordinate HANDLE handle = GetStdHandle (STD_OUTPUT_HANDLE); / / get console handle SetConsoleCursorPosition (handle, pos); / / set cursor position} / / initialize interface void InitInterface () {color (3); / / set the color to lake blue for (int I = 0; I)
< ROW; i++) { for (int j = 0; j < COL; j++) { if (j == 0 || j == COL - 1) { face[i][j] = WALL; //标记该位置为墙 CursorJump(2 * j, i); printf("■"); } else if (i == 0 || i == ROW - 1) { face[i][j] = WALL; //标记该位置为墙 printf("■"); } else { face[i][j] = KONG; //标记该位置为空 } } } color(4); //颜色设置为红色 CursorJump(0, ROW); printf("当前得分:%d", grade); CursorJump(COL, ROW); printf("历史最高得分:%d", max);}//颜色设置void color(int c){ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //颜色设置 //注:SetConsoleTextAttribute是一个API(应用程序编程接口)}//从文件读取最高分void ReadGrade(){ FILE* pf = fopen("贪吃蛇最高得分记录.txt", "r"); //以只读的方式打开文件 if (pf == NULL) //打开文件失败 { pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件 fwrite(&max, sizeof(int), 1, pf); //将max写入文件(此时max为0),即将最高得分初始化为0 } fseek(pf, 0, SEEK_SET); //使文件指针pf指向文件开头 fread(&max, sizeof(int), 1, pf); //读取文件当中的最高得分到max当中 fclose(pf); //关闭文件 pf = NULL; //文件指针及时置空}//更新最高分到文件void WriteGrade(){ FILE* pf = fopen("贪吃蛇最高得分记录.txt", "w"); //以只写的方式打开文件 if (pf == NULL) //打开文件失败 { printf("保存最高得分记录失败\n"); exit(0); } fwrite(&grade, sizeof(int), 1, pf); //将本局游戏得分写入文件当中 fclose(pf); //关闭文件 pf = NULL; //文件指针及时置空}//初始化蛇void InitSnake(){ snake.len = 2; //蛇的身体长度初始化为2 snake.x = COL / 2; //蛇头位置的横坐标 snake.y = ROW / 2; //蛇头位置的纵坐标 //蛇身坐标的初始化 body[0].x = COL / 2 - 1; body[0].y = ROW / 2; body[1].x = COL / 2 - 2; body[1].y = ROW / 2; //将蛇头和蛇身位置进行标记 face[snake.y][snake.x] = HEAD; face[body[0].y][body[0].x] = BODY; face[body[1].y][body[1].x] = BODY;}//随机生成食物int my_time = 1;void RandFood(){ int i, j; do { //随机生成食物的横纵坐标 i = rand() % ROW; j = rand() % COL; } while (face[i][j] != KONG); //确保生成食物的位置为空,若不为空则重新生成 face[i][j] = FOOD; //将食物位置进行标记 color(12); //颜色设置为红色 CursorJump(2 * j, i); //光标跳转到生成的随机位置处 printf("●"); //打印食物}//判断得分与结束void JudgeFunc(int x, int y){ //若蛇头即将到达的位置是食物,则得分 if (face[snake.y + y][snake.x + x] == FOOD) { snake.len++; //蛇身加长 grade += 10; //更新当前得分 color(7); //颜色设置为白色 CursorJump(0, ROW); printf("当前得分:%d", grade); //重新打印当前得分 RandFood(); //重新随机生成食物 } //若蛇头即将到达的位置是墙或者蛇身,则游戏结束 else if (face[snake.y + y][snake.x + x] == WALL || face[snake.y + y][snake.x + x] == BODY) { Sleep(1000); //留给玩家反应时间 system("cls"); //清空屏幕 color(7); //颜色设置为白色 CursorJump(2 * (COL / 3), ROW / 2 - 3); if (grade >Max) {printf ("Congratulations on breaking the highest record, updated to% d", grade); WriteGrade () } else if (grade = = max) {printf ("even with the record:% d, come on and do well again", grade) } else {printf ("Please keep refueling, current difference from record% d", max-grade);} CursorJump (2 * (COL / 3), ROW / 2); printf ("GAME OVER") While (1) / / ask the player if they want to play another round {char ch; CursorJump (2 * (COL / 3), ROW / 2 + 3); printf ("another round? (Yzone):"); scanf ("% c", & ch) If (ch = ='y' | | ch = ='Y') {system ("cls"); main () } else if (ch = ='n' | | ch = ='N') {CursorJump (2 * (COL / 3), ROW / 2 + 5); exit (0) } else {CursorJump (2 * (COL / 3), ROW / 2 + 5); printf ("wrong choice, please select again") } / / print snake and cover snake void DrawSnake (int flag) {if (flag = = 1) / / print snake {color (10); / / Color set to green CursorJump (2 * snake.x, snake.y); printf ("■") / / print snakehead for (int I = 0; I
< snake.len; i++) { CursorJump(2 * body[i].x, body[i].y); printf("□"); //打印蛇身 } } else //覆盖蛇 { if (body[snake.len - 1].x != 0) //防止len++(即蛇变长)后将(0, 0)位置的墙覆盖 { //将蛇尾覆盖为空格即可 CursorJump(2 * body[snake.len - 1].x, body[snake.len - 1].y); printf(" "); } }}//移动蛇void MoveSnake(int x, int y){ DrawSnake(0); //先覆盖当前所显示的蛇 face[body[snake.len - 1].y][body[snake.len - 1].x] = KONG; //蛇移动后蛇尾重新标记为空 face[snake.y][snake.x] = BODY; //蛇移动后蛇头的位置变为蛇身 //蛇移动后各个蛇身位置坐标需要更新 for (int i = snake.len - 1; i >0; iMel -) {body.x = body [i1] .x; body.y = body [i1] .y;} / / after the snake moves, the position information of the snake head becomes the position information of the first snake body body [0] .x = snake.x; body [0] .y = snake.y / / change the position of the snakehead snake.x = snake.x + x; snake.y = snake.y + y; DrawSnake (1); / / print the moved snake} / / execute the button void run (int x, int y) {int t = 0; while (1) {if (t = 0) t = 3000 / / the smaller the t here, the faster the snake moves (you can set the difficulty of the game according to the time) while (--t) / / if the movement speed is controlled, 3000 cycles will take a little time {if (kbhit ()! = 0) / / if the keyboard is tapped, exit the loop break } if (t = = 0) / / the keyboard is not tapped {JudgeFunc (x, y); / / to determine whether the score is related to the game end MoveSnake (x, y) after reaching this position. / / Mobile Snake} else / / Keyboard is tapped {break; / / return Game function to read key value} / / Game body logic function void Game () {int n = RIGHT; / / when starting the game, move backwards by default int tmp = 0 / / record the moving direction of the snake goto first; / / enter the loop for the first time and move to the default direction first. While (1) {n = getch () / / read key value / / before execution Need to adjust the keystroke read switch (n) {case UP: case DOWN: / / if you hit "up" or "down" if (tmp! = LEFT & & tmp! = RIGHT) / / and the last snake moved in a direction other than "left" or "right" {n = tmp / / then the next snake's moving direction is set to the previous snake's moving direction} break Case LEFT: case RIGHT: / / if you hit "left" or "right" if (tmp! = UP & & tmp! = DOWN) / / and the last snake did not move in the direction of "up" or "down" {n = tmp / / then the next snake's moving direction is set to the previous snake's moving direction} case SPACE: case ESC: case'ringing: case'ringing: break / / these four keys do not need to be adjusted default: n = tmp; / / other keys are invalid. Default is the direction in which the snake moved last time break. } first: / / enter the loop for the first time and first move forward to the default direction switch (n) {case UP: / / key: run (0,-1) / / move up (Abscissa offset is 0, ordinate offset is-1) tmp = UP; / / record the current direction of snake movement break; case DOWN: / / direction key: lower run (0,1) / / move down (Abscissa offset is 0, ordinate offset is 1) tmp = DOWN; / / record the current direction of snake movement break; case LEFT: / / direction key: left run (- 1,0) / / move to the left (Abscissa offset is-1, ordinate offset is 0) tmp = LEFT; / / record the current direction of snake movement break; case RIGHT: / / key: right run (1,0) / / move to the right (Abscissa offset is 1, ordinate offset is 0) tmp = RIGHT; / / record the current direction of snake movement break; case SPACE: / / pause system ("pause > nul"); / / press any key after pause to continue break Case ESC: / / exit system ("cls"); / / clear screen color (7); / / set color to white CursorJump (COL-8, ROW / 2); printf ("Game over") CursorJump (COL-8, ROW / 2 + 2); exit (0); case'ringing: case'Rays: / / restart system ("cls"); / / clear screen main () / / re-execute the main function}} 3. Game framework construction 3.1 size of the game interface
First, define the size of the game interface, and define the number of rows and columns in the game area.
# define ROW 22 / / number of rows in the game area # define COL 42 / / number of game area columns
Here, the area where the snake is active is called the game area, and the area where the score is prompted is called the prompt area (the prompt area occupies one line).
3.2 Snakeheads and snakebodies
In addition, we need two structures to represent the snake head and the snake body. The current length of the snake body and the position coordinates of the snake head are stored in the snake head structure.
3.2.1 Snakehead struct Snake {int len; / / record snakebody length int x; / snakehead Abscissa int y; / / Snakehead ordinate} snake;3.2.2 snakebody
The position coordinates of the snake body are stored in the snake body structure.
Struct Body {int x; / / Snake body Abscissa int y; / / Snake body ordinate} Body [row * COL]; / / Open up an array of structures sufficient to store the snake body 3.3.1.What are the locations of the game area 3.3.1?
At the same time, we need a two-dimensional array to store the locations of the game area (empty, walls, food, snakeheads and snakebodies).
Int face [ROW] [COL]; / / store the location of the game area, which can be achieved by storing different numbers.
3.3.2 use macros to make certain numbers have special meaning
To increase the readability of the code, it is best to use macros to define emptiness, walls, food, snakeheads, and snakebodies
# define KONG 0 / / Mark empty (nothing) # define WALL 1 / / Mark Wall # define FOOD 2 / / Mark Food # define HEAD 3 / / Mark Snakehead # define BODY 4 / / Mark Snake body
Of course, for the readability of the code, we'd better also use macros to define the key values of the keys we need to use.
# define UP 72 / / Direction key: top # define DOWN 80 / / Direction key: bottom # define LEFT 75 / / Direction key: left # define RIGHT 77 / / Direction key: right # define SPACE 32 / / pause # define ESC 27 / / exit from the menu bar void menu () {system ("title gluttonous Snake"); / / set the window title system ("mode con cols=84 lines=23"); / / set the size of the cmd window color (14) / / set the text to light yellow printf ("*\ n"); printf ("* Welcome to the game of Snake! *\ n "); printf (" *\ n ") Printf ("* press the arrow keys up and down to change the direction of snake movement *\ n") Printf ("*\ n") Printf ("* Press the spacebar to pause, press any key to continue the game *\ n") Printf ("*\ n") Printf ("* press the Esc key to exit the game directly * *\ n") Printf ("* press R key to restart the game *\ n") Printf ("*\ n"); system ("pause"); / / pause the program, press any key to continue}
The functions that appear in this will be explained below to ensure that everyone will not be confused!
four。 Hide settings for the cursor
It is relatively simple to hide the cursor, define a structure variable of the cursor information (the structure type system has been defined), and then assign the cursor information. finally, the cursor information can be set with the structure variable of the cursor information.
4.1 structural members of cursor information
Members' detailed explanation
4.2 implementation of hidden cursor void HideCursor () {CONSOLE_CURSOR_INFO curInfo; / / defines the structural body variable of the cursor information, header file curInfo.dwSize = 1; / / random value if no value is assigned, invalid cursor curInfo.bVisible = FALSE; / / sets the cursor to invisible HANDLE handle = GetStdHandle (STD_OUTPUT_HANDLE) / / get the console handle SetConsoleCursorInfo (handle, & curInfo); / / set the cursor information} 4.3GetStdHandle function
Introduction to use
4.4 SetConsoleCursorInfo function
Introduction to use
five。 Settings for cursor jump
The cursor jumps, that is, the cursor jumps to the specified location for output. Similar to the procedure of hiding the cursor, first define a structural variable of the cursor position, then set the horizontal and vertical coordinates of the cursor, and finally use the structural variable of the cursor position to set the cursor position.
5.1 structure type typedef struct _ COORD {SHORT X; SHORT Y;} COORD, * PCOORD of cursor position
Among them, typedef short SHORT
5.2 SetConsoleCursorPosition function
Introduction to use
Void CursorJump (int x, int y) {COORD pos; / / defines the structure variable pos.X = x; / Abscissa pos.Y = y; / / ordinate HANDLE handle = GetStdHandle (STD_OUTPUT_HANDLE); / / gets the console handle SetConsoleCursorPosition (handle, pos); / / sets the cursor position} VI. Initialization interface
Initialize the interface to complete the printing of the "wall" of the game area, and the printing of the prompt area.
Code int main () {/ / # pragma warning (disable: n) sets an alarm to fail # pragma warning (disable:4996) / / you can use the library function system provided by the standard C language ("title gluttonous Snake"); / / set the name of the cmd window system ("mode con cols=84 lines=23"); / / set the size of the cmd window HideCursor (); / / hide the cursor InitInterface () / / initialize interface Sleep (10000); / / pause 10000ms with header file return 0;} / initialize interface void InitInterface () {color (6); / / set color to khaki for (int I = 0; I)
< ROW; i++) { for (int j = 0; j < COL; j++) { if (j == 0 || j == COL - 1) { face[i][j] = WALL; //标记该位置为墙 CursorJump(2 * j, i); printf("■"); } else if (i == 0 || i == ROW - 1) { face[i][j] = WALL; //标记该位置为墙 printf("■"); } else { face[i][j] = KONG; //标记该位置为空 } } } color(4); //颜色设置为红色 CursorJump(0, ROW); printf("当前得分:%d", grade); CursorJump(COL, ROW); printf("历史最高得分:%d", max);}//颜色设置void color(int c){ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c); //颜色设置 //注:SetConsoleTextAttribute是一个API(应用程序编程接口)} 6.2 system函数 使用介绍 注意:一个程序中永远是最后一个system("color xx")起作用 因此本游戏中不使用system("color xx")来控制游戏界面颜色,而是使用SetConsoleTextAttribute函数 6.3 SetConsoleTextAttribute函数 使用介绍 七.初始化蛇 初始化蛇时将蛇身的长度初始化为2,蛇头的起始位置在游戏区的中央,蛇头向左依次是第0个蛇身、第1个蛇身。 //初始化蛇void InitSnake(){ snake.len = 2; //蛇的身体长度初始化为2 snake.x = COL / 2; //蛇头位置的横坐标 snake.y = ROW / 2; //蛇头位置的纵坐标 //蛇身坐标的初始化 body[0].x = COL / 2 - 1; body[0].y = ROW / 2; body[1].x = COL / 2 - 2; body[1].y = ROW / 2; //将蛇头和蛇身位置进行标记 face[snake.y][snake.x] = HEAD; face[body[0].y][body[0].x] = BODY; face[body[1].y][body[1].x] = BODY;}八.打印蛇与覆盖蛇 打印蛇和覆盖蛇这里直接使用一个函数来实现,若传入参数flag为1,则打印蛇;若传入参数为0,则用空格覆盖蛇。 打印蛇: 先根据结构体变量snake获取蛇头的坐标,到相应位置打印蛇头。然后根据结构体数组body依次获取蛇身的坐标,到相应位置进行打印即可。 覆盖蛇(请看完移动蛇之后再回来看这部分): 用空格覆盖最后一段蛇身即可。 但需要注意在覆盖前判断覆盖的位置是否为(0,0)位置,因为当得分后蛇身长度增加,而此时新的蛇尾还未进行赋值(编译器一般默认初始化为0),不需要覆盖当前新的蛇尾(只需要将新的蛇尾赋值然后打印蛇就可以了),我们根据最后一段蛇身获取到的坐标便是(0,0),如果进行覆盖,则会用空格对(0,0)位置进行覆盖,而(0,0)位置是墙,那么就会导致(0,0)位置墙消失了。 将该判断去掉,观察蛇吃到食物后(0,0)位置墙的变化再进行分析 //打印蛇与覆盖蛇void DrawSnake(int flag){ if (flag == 1) //打印蛇 { color(10); //颜色设置为绿色 CursorJump(2 * snake.x, snake.y); printf("■"); //打印蛇头 for (int i = 0; i < snake.len; i++) { CursorJump(2 * body[i].x, body[i].y); printf("□"); //打印蛇身 } } else //覆盖蛇 { if (body[snake.len - 1].x != 0) //防止len++(即蛇变长)后将(0, 0)位置的墙覆盖 { //将蛇尾覆盖为空格即可 CursorJump(2 * body[snake.len - 1].x, body[snake.len - 1].y); printf(" "); } }}九、随机生成食物//随机生成食物void RandFood(){ int i, j; do { //随机生成食物的横纵坐标 i = rand() % ROW; j = rand() % COL; } while (face[i][j] != KONG); //确保生成食物的位置为空,若不为空则重新生成 face[i][j] = FOOD; //将食物位置进行标记 color(12); //颜色设置为红色 CursorJump(2 * j, i); //光标跳转到生成的随机位置处 printf("●"); //打印食物}9.1效果展示int main(){//#pragma warning(disable: n)将某个警报置为失效#pragma warning (disable:4996) //可以使用标准C语言提供的库函数 srand((size_t)time(NULL));//根据当前时间生成随机种子 system("title 贪吃蛇"); //设置cmd窗口的名字 system("mode con cols=84 lines=23"); //设置cmd窗口的大小 HideCursor(); //隐藏光标 InitInterface(); //初始化界面 InitSnake(); //初始化蛇 DrawSnake(1); //打印蛇 RandFood(); //随机生成食物 Sleep(10000); return 0;} 9.2 srand与rand函数 使用说明 十、移动蛇 移动蛇函数的作用就是先覆盖当前所显示的蛇,然后再打印移动后的蛇。 参数说明: x:蛇移动后的横坐标相对于当前蛇的横坐标的变化。 y:蛇移动后的纵坐标相对于当前蛇的纵坐标的变化。 蛇移动后,各种信息需要变化: 最后一段蛇身在游戏区当中需要被重新标记为空。蛇头位置在游戏区当中需要被重新标记为蛇身。存储蛇身坐标信息的结构体数组body当中,需要将第i段蛇身的坐标信息更新为第i-1段蛇身的坐标信息,而第0段,即第一段蛇身的坐标信息需要更新为当前蛇头的坐标信息。蛇头的坐标信息需要根据传入的参数x和y,进行重新计算。(以上过程请想象蛇移动的情景) //移动蛇void MoveSnake(int x, int y){ DrawSnake(0); //先覆盖当前所显示的蛇 face[body[snake.len - 1].y][body[snake.len - 1].x] = KONG; //蛇移动后蛇尾重新标记为空 face[snake.y][snake.x] = BODY; //蛇移动后蛇头的位置变为蛇身 //蛇移动后各个蛇身位置坐标需要更新 for (int i = snake.len - 1; i >0; iMel -) {body.x = body [i1] .x; body.y = body [i1] .y;} / / after the snake moves, the position information of the snake head becomes the position information of the 0th snake body body [0] .x = snake.x; body [0] .y = snake.y; / / position change of the snake head snake.x = snake.x + x Snake.y = snake.y + y; DrawSnake (1); / / print the moved snake} 11, the game body logic function 11.1 body logic function
First enter the function Game for the first time, and the default snake moves to the right, and then the run function is executed. Until the keyboard is tapped, return from the run function to the Game function for keystroke reading. After reading the key value, you need to adjust the read key (this is necessary). After the adjustment, the key execution is carried out, and then the key reading is carried out in a cycle.
/ / Game body logic function void Game () {int n = RIGHT; / / when starting the game, move backward by default int tmp = 0; / / record the moving direction of the snake goto first; / / enter the loop for the first time and advance to the default direction first while (1) {n = getch () / / read key value / / before execution, switch (n) {case UP: case DOWN: / / if the keystroke is "up" or "down" if (tmp! = LEFT & & tmp! = RIGHT) {/ / and the last snake's movement direction is not "left" or "right" n = tmp / / then the next snake's moving direction is set to the previous snake's moving direction} break; case LEFT: case RIGHT: / / if the tap is "left" or "right" if (tmp! = UP & & tmp! = DOWN) {/ / and the last snake's moving direction is not "up" or "down" n = tmp / / then the next snake's moving direction is set to the previous snake's moving direction} case SPACE: case ESC: case'ringing: case 'ringing: break; / / these four keys do not need to be adjusted default: n = tmp; / / other keys are invalid. Default is the last snake's moving direction break. } first: / / the first time you enter the loop, first go to the default direction switch (n) {case UP: / / key: up run (0,-1); / / move up (Abscissa offset is 0, ordinate offset is-1) tmp = UP; / / record the current snake's moving direction break Case DOWN: / / arrow key: lower run (0,1); / / move down (Abscissa offset is 0, ordinate offset is 1) tmp = DOWN; / / record the current direction of snake movement break; case LEFT: / / direction key: left run (- 1,0) / / move to the left (Abscissa offset is-1, ordinate offset is 0) tmp = LEFT; / / record the current direction of snake movement break; case RIGHT: / / key: right run (1,0); / / move right (Abscissa offset is 1, ordinate offset is 0) tmp = RIGHT / / record the current direction of movement of the snake break; case SPACE: / / pause system ("pause > nul"); / / press any key after pause to continue break; case ESC: / / exit system ("cls"); / / clear the screen color (7); / / set the color to white CursorJump (COL-8, ROW / 2) Printf ("Game over"); CursorJump (COL-8, ROW / 2 + 2); exit (0); case'ringing: case'Renewal: / / restart system ("cls"); / / clear screen main (); / / re-execute main function} 11.2Execute key function
Key adjustment mechanism:
If you hit the "up" or "down" keys, and the last snake's movement direction is not "left" or "right", then the next snake's movement direction is set to the previous snake's movement direction, that is, the direction of movement remains the same. If you hit the "left" or "right" keys, and the last snake's movement direction is not "up" or "down", then set the next snake's movement direction to the previous snake's movement direction, that is, the direction of movement remains the same. If the keystroke is a space, Esc, r, or R, no adjustment is made. The rest of the buttons are invalid, the next time the snake moves in the same direction as the last one, that is, the direction of movement remains the same.
/ / execute button void run (int x, int y) {int t = 0; while (1) {if (t = = 0) t = 3000 / / the smaller the t here, the faster the snake moves (you can set the difficulty of the game according to the time) while (--t) {/ / control the moving speed, 3000 cycles will take a little time if (kbhit ()! = 0) / / if the keyboard is tapped, exit the loop break } if (t = = 0) / / the keyboard is not tapped {JudgeFunc (x, y); / / to determine whether to score MoveSnake (x, y) at the end of the game after reaching this position; / / Mobile Snake} else / / the keyboard is tapped {break; / / return the Game function to read the key}
Kbhit () function
Return Value
Kbhit returns a nonzero value if a key has been pressed. Otherwise, it returns 0.
Execute button
Parameter description:
X: the change of the Abscissa of the snake relative to the current Abscissa of the snake.
Y: the change of the ordinate of the snake relative to the current ordinate of the snake.
Given a certain time interval, if the keyboard is tapped within the time interval, exit the run function and return the Game function for keystroke reading. If it is not struck, first judge whether the snake scores after it reaches the moving position or whether the game is over, and then move the snake's position. If the keyboard is not tapped, the while function in the run function will be executed and the snake will move in one direction until the end of the game.
11.3 judging the score and the end
Judge score: if the position that the snakehead is about to reach is food, score. After scoring, you need to lengthen the snake body and update the current score. In addition, you also need to regenerate the food.
End of judgment: if the position that the snakehead is about to reach is a wall or a snake body, the game is over. After the end of the game, compare the score of the game with the highest score in history, give the corresponding prompt sentence, and ask the player whether to play another game, which can be played freely.
Void JudgeFunc (int x, int y) {/ / if the position where the snakehead is about to arrive is food, score if (face [snake.y + y] [snake.x + x] = = FOOD) {snake.len++; / / Snake body lengthened grade + = 10; / / Update current score color (7); / / Color set to white CursorJump (0, ROW); printf ("current score:% d", grade) / / reprint the current score RandFood (); / / randomly generate food} / / if the location where the snakehead is about to arrive is a wall or snakebody, then the game ends else if (face [snake.y + y] [snake.x + x] = = WALL | | face [snake.y + y] [snake.x + x] = BODY) {Sleep (1000); / / leave the player reaction time system ("cls") / / clear screen color (7); / / Color is set to white CursorJump (2 * (COL / 3), ROW / 2-3); if (grade > max) {printf ("Congratulations on breaking the highest record, highest record updated to% d", grade); WriteGrade () } else if (grade = = max) {printf ("even with record% d, refuel for success", grade);} else {printf ("Please keep going, current difference from record% d", max-grade);} CursorJump (2 * (COL / 3), ROW / 2); printf ("GAME OVER") While (1) {/ / ask the player whether to play another round of char ch; CursorJump (2 * (COL / 3), ROW / 2 + 3); printf ("another round? (YSEO):"); scanf ("% c", & ch); if (ch = ='y' | | ch = ='Y') {system ("cls") Main ();} else if (ch = ='n' | | ch = ='N') {CursorJump (2 * (COL / 3), ROW / 2 + 5); exit (0);} else {CursorJump (2 * (COL / 3), ROW / 2 + 5) Printf ("Select error, please select again"); read historical data from file
First of all, you need to use the fopen function to open the "gluttonous Snake highest score record .txt" file, if you run the code for the first time, the file will be automatically created, and the history maximum record will be set to 0, then read the file and store the history record in the max variable, and close the file.
11.5 Update data to file
First, use the fopen function to open the "gluttonous Snake highest score record. Txt", and then write the score of the game grade into the file (overlay).
/ / update the highest score to the file void WriteGrade () {FILE* pf = fopen ("Snake highest score record .txt", "w"); / / Open the file if (pf = = NULL) in a write-only manner / / failed to open the file {printf ("failed to save the highest score record\ n"); exit (0);} fwrite (& grade, sizeof (int), 1, pf) / / write the score of the local game into the file fclose (pf); / / close the file pf = NULL; / / the file pointer is left empty in time} 11.6The main function int main () {/ / # pragma warning (disable: n) sets an alert as invalid # pragma warning (disable:4996) / / you can use the library function menu () provided by the standard C language; max = 0, grade = 0 / / initialize variable srand ((size_t) time (NULL)); / / generate random seed system based on the current time ("title gluttonous snake"); / / set the name of cmd window system ("mode con cols=84 lines=23"); / / set the size of cmd window HideCursor (); / / hide cursor ReadGrade (); / / read the highest score from the file to the max variable InitInterface () / / initialize interface InitSnake (); / initialize snake RandFood (); / / randomly generate food DrawSnake (1); / / print snake PlaySound (TEXT ("bgmusic.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); Game (); / / start the game return 0 At this point, I believe you have a deeper understanding of "how to realize gluttonous Snake in C language". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 279
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.