C程序设计,贪吃蛇程序

您所在的位置:网站首页 贪吃蛇程序代码C语言分析内容 C程序设计,贪吃蛇程序

C程序设计,贪吃蛇程序

2023-09-24 13:26| 来源: 网络整理| 查看: 265

C语言,贪吃蛇程序设计 一.代码分析(1)头文件(2)宏定义(3)全局变量(4)函数部分1)绘制地图函数DreawMap(),2)食物位置函数FoodRand()3)键盘控制移动函数ControlMove()函数4)移动函数Move()函数5)蛇身开始函数Isnake()函数6)判断食物是否被吃到函数Jfood()函数7)判断是否碰到墙Jwell()函数8)判断是否碰到蛇身Jsnake()函数9)计算分数和难度Showf()函数10)清空存储空间函数 二.代码附录

一.代码分析 (1)头文件 1.include 2.Include 3.Include (2)宏定义 #define WIDTH 40定义宽度为40 #define HEIGHT 20定义高度为20 #define PRINTF printf(“◼”);定义PRINTF表示输出边框符号 #define LINE printf(“\n”);定义LINE表示输出换行符 #define EMPTY printf(“ ”);定义EMPTY表示输出空格,empty在计算机科学中表示空。 (3)全局变量 Int sum = 0;定义整型变量sum用来计算得分 Int JudgeSum = 0;定义整型变量JudgeSum用来判断速度 Int Hard = 0;定义整型变量Hard用来计算难度 Int Pause = 200000000;定义整型变量并初始化为两亿用来控制移动速度 Int JudgeDirection = 4;定义整型变量用来判断方向 Int *PJ = &JudgeDirection;定义指向整型数据的指针,并赋给JudegDirection的地址使用指针传值判断方向。 (4)函数部分 1)绘制地图函数DreawMap(),

思路:一行一行的输出,输出完一行就换行继续输出,直到输出完边框部分。 第一步:先输出第一行,输完第一行进行换行。(这里@代表◼)

for (int i = 0; i //最后一行是单独输出的,所以 for (int j = 0; j //到了两边的边框,就输出边框 printf("@"); //符号。 if (j == WIDTH) //如果j等于40则就换行,输出 { //下一行。否则就输出空格*/ printf("\n"); } } else { printf(" "); } } }

运用一个双重循环,外循环控制行数的切换,内循环控制个数,从第二行开始输出,一直输出到倒数第二行结束。刚才说了,左右边框是在0和39的地方,使用判断语句进行判断是否位于边框地方,如果是就输出边框符号,如果不是就输出空格。位于最后一格输出换行符。 第三步:就是输出最后一行的边框;

for (int i = 0; i for (int j = 0; j PRINTF if (j == WIDTH - 1)LINE } else EMPTY } } for (int i = 0; i x * 2,y };//定义了一个结构体类型变量pos HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);//获得 标准输出的句柄 SetConsoleCursorPosition(output, pos); //设置控制台光标位置 }

第二步,随机产生坐标位置

srand((int)time(0));//srand(time(NULL))表示设置一种随机种子,每次运行都 int x = rand() % 27 + 2; 可以保证随机种子不同。*/ int y = rand() % 17 + 2;

第三步,先对整个坐标进行判断是否与蛇身重合,如果是则重新产生随机位置,如果不是就继续执行,并且将食物坐标存放在一个链表中,以备后续的使用。

for (int i = 0; i x = rand() % 27 + 2;//如果是则重新产生位置坐标 y = rand() % 17 + 2; } else//如果不是则让后一个结点的next域指向前一个结点 { Phead_1 = Phead_1->next; } if (Phead_1->next == NULL)//直到后一个结点的指针域为空,就表示循环到最后一个结点了,就结束循环 { break; } } Food = (Snakexy*)malloc(sizeof(Snakexy));//开辟新的结点 Food->x = x;//将食物的坐标存放到食物链表中去 Food->y = y; 3)键盘控制移动函数ControlMove()函数

思路:用键盘的上下左右键来控制蛇的移动。这里使用Get Async Key State的方法。 先介绍Get Async Key State的用法。这个函数就是用来得到某个键的状态,让后判断返回值是否为1,如果是表示这个键处于按下状态。 另一种就是逻辑键与物理键了,键盘输出就属于一种物理键的输入,而鼠标点击就是一种逻辑键了。类似的向GetKeyState,GetKeyboardState等函数就得到的是逻辑键操作。

if (GetAsyncKeyState(VK_UP) && 0x8000)//judege direction { 判断方向。 if (JudgeDirection == 2) { } else { JudgeDirection = 1; } } if (GetAsyncKeyState(VK_DOWN) && 0x8000) { if (JudgeDirection == 1) { } else { JudgeDirection = 2; } } if (GetAsyncKeyState(VK_RIGHT) && 0x8000) { if (JudgeDirection == 3) { } else { JudgeDirection = 4; } } if (GetAsyncKeyState(VK_LEFT) && 0x8000) { if (JudgeDirection == 4) { } else { JudgeDirection = 3; } } if (GetAsyncKeyState(VK_RETURN) && 0x0D) { while (1) { if (GetAsyncKeyState(VK_RETURN) && 0x0D) { break; } }} 4)移动函数Move()函数

思路:使用链表,消除尾结点,增加头结点,这样就可以实现蛇的移动。运用了一个while循环来不断执行消除尾结点和增加头结点,实现不断移动。 第一步:消除尾结点。

Phead_1 = Phead;/*结构体指针Phead和Phead_1同指向这个链表的头也就是头指针head,因为结构体指针Phead用来存放整个蛇身不进行改变,所以使用Phead_1来代替改变*/ while (Phead_1->next->next != NULL)/*Phead_1的next域后的next域 { 如果不是空,则指向后一个指针域 Phead_1 = Phead_1->next; */ } Phead_1->next = NULL;//这是最后一个指针域为空就是到最后的结点 for (int i = 0; i //输入向上的指令,表示此时蛇向上移动。 Phead_2->x = Phead->x; //则蛇身的x坐标不变, Phead_2->y = Phead->y - 1; //y坐标向上移动一位 } if (*PJ == 2)//向下移动 { Phead_2->x = Phead->x; Phead_2->y = Phead->y + 1; } if (*PJ == 3)//向左移动 { Phead_2->x = Phead->x - 1; Phead_2->y = Phead->y; } if (*PJ == 4)//向右移动 { Phead_2->x = Phead->x + 1; Phead_2->y = Phead->y; } Phead_2->next = Phead;//将前一个的结点赋值给新链表后一个结点 Phead = Phead_2;//同时指向同一个链表 MoveCursor(Phead_2->x, Phead_2->y);//移动到头结点xy处 Printf(“◼”)//输出蛇身符号,表示头 5)蛇身开始函数Isnake()函数

思路:存放整个蛇身,初始化开始蛇身长度为5,打印出蛇身,并存放在蛇身链表中

for (int i = 0; i end->next = Pbady;//否则就是尾结点就指向蛇身链表 } Pbady->next = NULL;是最后的结点为空 end = Pbady; } Phead_1 = Phead; while (Phead_1->next != NULL) { MoveCursor(Phead_1->x, Phead_1->y);//移动到蛇身位置 Printf(“◼”)//输出蛇身符号 Phead_1 = Phead_1->next; } 6)判断食物是否被吃到函数Jfood()函数

思路:如果吃到食物就在蛇身链表的尾结点处增加新的结点,依次类推,如果吃到一个分数就加一,如果迟到2个速度也就是难度加一。

Phead_1 = Phead;/*结构体指针Phead和Phead_1同指向这个链表的头也就是头指针head,因为结构体指针Phead用来存放整个蛇身不进行改变,所以使用Phead_1来代替改变*/ if (Phead_1->x == Food->x&&Phead_1->y == Food->y) {//如果蛇身头结点指向食物链表,也就是蛇头碰到食物 FoodRand();//则产生食物位置 JudgeSum += 1;//产生后则难度加一 if (JudgeSum == 2)如果难度超过二就说明速度要增加 { JudgeSum = 0; Hard += 1;//难度加一 Pause -= 20000000;//移动速度减少两千万,原来为两亿。可以增加10个难度 } while (Phead_1->next != NULL)//循环后的最后一个结点为空 { Phead_1 = Phead_1->next;//则是尾结点重新赋值 } Snakebody *S = (Snakebody*)malloc(sizeof(Snakebody));//开辟新结点 S->x = Food->x; S->y = Food->y; S->next = NULL; Phead_1->next = S; ControlMove(); MoveCursor(Phead_1->x, Phead_1->y); Printf(“◼”); } 7)判断是否碰到墙Jwell()函数 if (Phead->x == 0 || Phead->x == 29 || Phead->y == 0 || Phead->y == 19) { MoveCursor(10, 20); printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); 8)判断是否碰到蛇身Jsnake()函数 Phead_1 = Phead->next; while (Phead_1->next != NULL) { if ((Phead->x == Phead_1->x) && (Phead->y == Phead_1->y)) { MoveCursor(10, 20); printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); } Phead_1 = Phead_1->next; } 9)计算分数和难度Showf()函数 MoveCursor(33, 5); printf("得分:%d", sum); MoveCursor(33, 6); printf("难度:%d", Hard)

;

10)清空存储空间函数 while (Phead->next != NULL) { Phead=Phead->next; free(Phead); } free(Phead); 二.代码附录 #include #include #include #define HEIGHT 20 //设置地图高度 #define WIDTH 40 //设置地图宽度 #define PRINTF printf("■"); #define LINE printf("\n"); #define EMPTY printf(" "); typedef struct Snakebody//类型定义结构体,蛇的身体 { int x, y;//身体的坐标 struct Snakebody *next;//结构指针 }Snakebody;//先来创建保持身体的链表,贪吃蛇的核心代码就是该如何保存蛇的身体 typedef struct Snakexy { int x; int y; }Snakexy; //记录食物坐标 int sum = 0; //计算得分 int JudgeSum = 0; //判断是否加快 int Hard = 0; //计算难度 int Pause = 200000000; //暂停速度(移动速度) int JudgeDirection = 4; //判断方向 int * PJ = &JudgeDirection; //用指针传值判断移动方向 Snakebody *Phead = NULL; //存储着整个蛇身 不可更改 Snakebody *Phead_1 = NULL; //指向蛇身 Snakebody *Pbady = NULL; //创建节点 Snakebody *end = NULL; //尾节点 Snakexy * Food = NULL; //保存食物位置 void Front(); //游戏开始页面1 void Jfood(); //检测是否吃到食物1 void Jwall(); //检测蛇头是否撞墙1 void Jsnake(); //检测蛇头是否撞到蛇身1 void ISnake(); //初始化蛇身1 void DeawMap(); //绘制地图1 void FoodRand(); //生成食物1 void ControlMove(); //控制移动和暂停1 void MoveCursor(int x, int y); //移动光标1 void Move(); //游戏运行1 void Showf(); //显分数以及难度1 void Free(); //释放内存 int main() { Front(); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN);//绿 DeawMap(); Showf(); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);// 暗白 MoveCursor(44, 10); printf("↑"); MoveCursor(41, 11); printf("使用←↓→来控制"); MoveCursor(41, 12); printf("蛇的移动,撞墙游"); MoveCursor(41, 13); printf("戏结束,每2分增 "); MoveCursor(41, 14); printf("一个难度(速度)"); ISnake(); FoodRand(); MoveCursor(40, 20); Move(); return 0; } void Front() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 MoveCursor(18, 10); printf(" 贪 吃 蛇 "); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_GREEN);//设置绿色 MoveCursor(18, 12); printf("分析:乾中权"); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_BLUE);//设置蓝色 MoveCursor(18, 14); printf("QQ:2238265682"); MoveCursor(18, 16); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);//设置红色和蓝色相加 MoveCursor(18, 18); printf("请等待......"); for (int i = 0; i for (int i = 0; i if (j == 0 || j == WIDTH - 1) { PRINTF if (j == WIDTH - 1)LINE } else EMPTY } } for (int i = 0; i x * 2,y }; HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);//获得 标准输出的句柄 SetConsoleCursorPosition(output, pos); //设置控制台光标位置 } void FoodRand() { srand((int)time(0)); int x = rand() % 37 + 2; int y = rand() % 17 + 2; Phead_1 = Phead; for (int i = 0; i x = rand() % 37 + 2; y = rand() % 17 + 2; } else { Phead_1 = Phead_1->next; } if (Phead_1->next == NULL) { break; } } MoveCursor(x, y); PRINTF Food = (Snakexy*)malloc(sizeof(Snakexy)); Food->x = x; Food->y = y; MoveCursor(43, 5); printf(" "); Showf(); sum++; SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY);// 蓝 } void ControlMove() { if (GetAsyncKeyState(VK_UP) && 0x8000) { if (JudgeDirection == 2) { } else { JudgeDirection = 1; } } if (GetAsyncKeyState(VK_DOWN) && 0x8000) { if (JudgeDirection == 1) { } else { JudgeDirection = 2; } } if (GetAsyncKeyState(VK_RIGHT) && 0x8000) { if (JudgeDirection == 3) { } else { JudgeDirection = 4; } } if (GetAsyncKeyState(VK_LEFT) && 0x8000) { if (JudgeDirection == 4) { } else { JudgeDirection = 3; } } if (GetAsyncKeyState(VK_RETURN) && 0x0D) { while (1) { if (GetAsyncKeyState(VK_RETURN) && 0x0D) { break; } } } } void ISnake() { for (int i = 0; i Phead = Pbady; } else { end->next = Pbady; } Pbady->next = NULL; end = Pbady; } Phead_1 = Phead; while (Phead_1->next != NULL) { MoveCursor(Phead_1->x, Phead_1->y); PRINTF Phead_1 = Phead_1->next; } } void Move() { while (1) { Phead_1 = Phead; while (Phead_1->next->next != NULL) { Phead_1 = Phead_1->next; } Phead_1->next = NULL; for (int i = 0; i Phead_2->x = Phead->x; Phead_2->y = Phead->y - 1; } if (*PJ == 2) { Phead_2->x = Phead->x; Phead_2->y = Phead->y + 1; } if (*PJ == 3) { Phead_2->x = Phead->x - 1; Phead_2->y = Phead->y; } if (*PJ == 4) { Phead_2->x = Phead->x + 1; Phead_2->y = Phead->y; } Phead_2->next = Phead; Phead = Phead_2; MoveCursor(Phead_2->x, Phead_2->y); PRINTF Jfood(); Jwall(); Jsnake(); MoveCursor(40, 20); } } void Jfood() { Phead_1 = Phead; if (Phead_1->x == Food->x&&Phead_1->y == Food->y) { FoodRand(); JudgeSum += 1; if (JudgeSum == 2) { JudgeSum = 0; Hard += 1; Pause -= 20000000; } while (Phead_1->next != NULL) { Phead_1 = Phead_1->next; } Snakebody *S = (Snakebody*)malloc(sizeof(Snakebody)); S->x = Food->x; S->y = Food->y; S->next = NULL; Phead_1->next = S; ControlMove(); MoveCursor(Phead_1->x, Phead_1->y); PRINTF } //获取食物的坐标和蛇头做对比 } void Jwall() { if (Phead->x == 0 || Phead->x == 39 || Phead->y == 0 || Phead->y == 19) { MoveCursor(10, 20); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); } } void Jsnake() { Phead_1 = Phead->next; while (Phead_1->next != NULL) { if ((Phead->x == Phead_1->x) && (Phead->y == Phead_1->y)) { MoveCursor(10, 20); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED);//设置红色 printf("抱歉,你撞到了自己,游戏结束! "); system("pause>nul"); exit(0); } Phead_1 = Phead_1->next; } } void Showf() { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE);// 蓝 MoveCursor(43, 5); printf("得分:%d", sum); MoveCursor(43, 6); printf("难度:%d", Hard); } void Free() { while (Phead->next != NULL) { Phead=Phead->next; free(Phead); } free(Phead); }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3