1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 贪吃蛇小游戏——C语言编写

贪吃蛇小游戏——C语言编写

时间:2023-05-01 22:26:02

相关推荐

贪吃蛇小游戏——C语言编写

文章目录

1.效果展示2.设计思路2.1图案显示2.2蛇头的移动2.3食物的生成2.4蛇身体的生成与移动2.5判断是否撞墙和打印得分3.完整代码

1.效果展示

2.设计思路

2.1图案显示

利用二维数组构建图案,总共有墙壁,蛇头,蛇身,食物,空白五种元素,因此只需要二维数组中的元素有五种不同的值即可;

2.2蛇头的移动

贪吃蛇是会自动移动的,我们首先让蛇头能自动移动。由于我们用数组来表示元素在地图中的位置,让元素移动就是让元素的坐标改变。

因此我们需要构建函数来完成蛇头坐标的自动移动,同时需要对我们输入的方向键做出判断,改变移动的方向。

2.3食物的生成

食物的生成很简单,只要种下一个随机数种子,然后给一个变量用来判断是否生成食物即可,需要注意的是食物的坐标别越界

2.4蛇身体的生成与移动

蛇身体的计算:

首先,蛇身体的移动前必须产生身体即是否吃到食物,可以给一个变量当计数器来判断有多少截身体;

蛇身体坐标的保存:

我们需要一个结构体数组,结构体数组的每个元素有两个成员x和y值,这两个值就代表我们的身体在二维数组中的坐标,

即一个数组成员就代表一截身体;

蛇身体坐标的获得:

通过计数器来判断是否有身体,当计数器不为0时,蛇就有了身体,第一截身体的坐标来源就是蛇头吃到食物前的坐标;

同理,后面吃到的食物增加,计数器的数值变大,就代表我们的结构体数组有多少个有效元素,然后给结构体数组里面的成员进行赋值;

最后一截身体的数组下标=计数器-1,后面的身体坐标就是前面的身体移动前的坐标,由于我们的头是不断移动的,并且可以直接获得其坐标,所以从最后一截身体开始往前进行拷贝赋值;

由于我们的赋值特点,数组(蛇身)从后往前进行覆盖式拷贝赋值,即完成了蛇身体的移动

没有吃到食物时的细节:

没有吃到食物时,蛇的身体长度是不变的,我们的身体坐标进行改变之后,在二维数组中留下了一个隐患;

2.5判断是否撞墙和打印得分

打印得分:得分即身体的长度即计数器的数值

判断是否撞墙:判断蛇头的下一个位置在二维数组中是不是1即是不是墙壁即可

3.完整代码

#ifndef _SNAKE_H_#define _SNAKE_H_#include <stdio.h>#include <windows.h>#include <time.h>#include <stdlib.h>#include <conio.h>#define MAX 500 //蛇身个数#define ROW 20 #define LINE 20typedef struct Body{int x;int y;}body;void MapPrint(char arr[][LINE], int count);//地图打印void Move(int *row, int *line, char *move);//蛇头移动函数,通过读取输入的键盘方向键来改变蛇头方向void GetCoordinate(int *row, int *line, char *move);//蛇头自动移动,通过获取的方向信息,决定蛇头往哪个方向自动移void food(char arr[][LINE], int *x, int *y);//随机生成一个食物void JudgeFood(int food_x, int food_y, int row, int line, int *count);//判断是否吃到食物void GetBody(char arr[][LINE], body body[], int count, int temp_x, int temp_y);//蛇体坐标更新int Judge(char arr[][LINE], int row, int line);//判断是否撞墙void Game();#endif

#include "snake.h"void gotoxy(int x, int y)//将光标移动到(x,y)位置{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);COORD pos;pos.X = x;pos.Y = y;SetConsoleCursorPosition(handle, pos);}void MapPrint(char arr[][LINE],int count){gotoxy(0, 0);for (int i = 0; i < ROW; i++){for (int j = 0; j < LINE; j++){//第一行,最后一行,第一列,最后一列都是墙壁if (arr[i][j]==1)printf("■");else if (arr[i][j] == 2)printf("⊙");//蛇头else if (arr[i][j] == 3)printf("¤");//打印食物¤else if (arr[i][j] == 4)printf("●");//打印身体●elseprintf(" ");//一个墙体占两个空格}printf("\n");}printf("\n");printf(" 当前得分:%d\n", count);printf("\n");}void Move(int *row, int *line,char *move)//蛇头移动函数,通过读取输入的键盘方向键来改变蛇头方向{if (GetAsyncKeyState(VK_UP))//上{*move = 'w';}else if (GetAsyncKeyState(VK_DOWN))//下{*move = 's';}else if (GetAsyncKeyState(VK_LEFT))//左{*move = 'a';}else if (GetAsyncKeyState(VK_RIGHT))//右{*move = 'd';}GetCoordinate(row, line, move);//将获得的方向键信息传输过去}void GetCoordinate(int *row, int *line, char *move)//蛇头自动移动,通过获取的方向信息,决定蛇头往哪个方向自动移{if (*move == 'w')(*row)--;else if (*move == 's')(*row)++;else if (*move == 'a')(*line)--;else if (*move == 'd')(*line)++;}void food(char arr[][LINE],int *x,int *y)//随机生成一个食物{int flag = 0;for (int i = 0; i < ROW; i++){for (int j = 0; j < ROW; j++){if (arr[i][j] == 3)//食物为3flag = 1;}}if (!flag)//没有食物就生成食物{//食物不能在边框上*x = rand() % (ROW-2)+1;*y = rand() % (LINE-2)+1;}}void JudgeFood(int food_x,int food_y,int row,int line,int *count)//判断是否吃到食物{if (food_x == row&&food_y == line)//吃到食物{(*count)++;//吃到食物身体个数+1}}void GetBody(char arr[][LINE], body body[], int count, int temp_x, int temp_y)//蛇体坐标更新{//保留前一个蛇体的坐标int befor_x = 0;int befor_y = 0;if (count > 0)//最少有一个蛇身{//记录下最后一个蛇身的位置befor_x = body[count - 1].x;befor_y = body[count - 1].y;}int keep = count;//保存一份蛇体个数while (count)//蛇体坐标覆盖,后面的覆盖前面的{if (count == 1)//只有一个蛇体时,为原来蛇头位置{body[count - 1].x = temp_x;body[count - 1].y = temp_y;}else{body[count - 1].x = body[count - 2].x;body[count - 1].y = body[count - 2].y;}count--;}while (keep)//将对应的蛇体坐标赋值{arr[body[keep-1].x][body[keep-1].y] = 4;keep--;}if (befor_x!=0)//最后一个蛇身的上一次所在位置清空{arr[befor_x][befor_y] = 0;}}int Judge(char arr[][LINE],int row,int line)//判断是否撞墙{if (arr[row][line] == 1){printf(" --------------\n");printf("| 撞到墙壁 |\n");printf("| 游戏结束 |\n");printf(" --------------\n");system("pause");return 0;}return 1;}void Game(){char arr[ROW][LINE]={{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ,1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },};//地图int row = 10, line = 10;//蛇头起始位置arr[row][10] = 2;char move = 'w';//蛇头开始往上移动int food_x = 0, food_y = 0;//食物的x,y坐标srand((unsigned)time(NULL));//随机数种子//保留一份蛇头移动前坐标int temp_x = row;int temp_y = line;int count = 0;//蛇身体个数body body[MAX] = {0 };//蛇身坐标记录结构体数组while (1){//生成食物food(arr, &food_x, &food_y);arr[food_x][food_y] = 3;MapPrint(arr,count);//打印图形if (count==0)arr[row][line] = 0;//没有身体的时候,蛇头原来位置变为空白//保留蛇头移动前的位置temp_x = row;temp_y = line;Move(&row, &line,&move);//蛇头移动if (Judge(arr, line, row) == 0)//判断是否撞墙{break;}JudgeFood(food_x,food_y,row, line, &count);//判断是否吃到食物GetBody(arr, body, count, temp_x, temp_y);//蛇身构造arr[row][line] = 2;//新位置变成蛇头Sleep(200);//通过控制休眠时间来控制蛇头移动速度}}

#include "snake.h"int main(){Game();printf("游戏结束\n");system("pause");return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。