C语言 —— 贪吃蛇
发布时间:2020-12-14 04:22:28 所属栏目:大数据 来源:网络整理
导读:参考视频:https://www.bilibili.com/video/av29580072/?p=1 ? GreedySnake.h 1 #ifndef GREEDYSNAKE_H_INCLUDED 2 #define GREEDYSNAKE_H_INCLUDED 3 4 5 #define SNAKE_LENGTH 20 // 蛇的长度最大为20 6 #define true 1 7 #define false 0 8 enum {UP = -
参考视频:https://www.bilibili.com/video/av29580072/?p=1 ? GreedySnake.h 1 #ifndef GREEDYSNAKE_H_INCLUDED 2 #define GREEDYSNAKE_H_INCLUDED 3 4 5 #define SNAKE_LENGTH 20 //蛇的长度最大为20 6 #define true 1 7 #define false 0 8 enum {UP = -1,DOWN = 1,LEFT = -2,RIGHT = 2}; 9 10 typedef int bool; 11 12 void FirstPage(); //设置起始游戏界面 13 void TestSpace(); //按空格开始游戏 14 void ShowBackground(); //展示游戏背景 15 void SetSnakeRandPos(); //为蛇产生一个随机的位置 16 void DrawSnake(); //画蛇 17 void SnakeMove(); //蛇动 18 void DestroySnake(); //销毁蛇 19 void ChangeDir(); //蛇随着方向键动起来 20 bool IsSnakeDie(); //判断蛇是否死亡 21 void ProduceFood(); //随机位置产生食物 22 void SnakeGrowUp(); //蛇变长 23 void PrintScore(); //打印分数 24 25 26 #endif // GREEDYSNAKE_H_INCLUDED ? GreedySnake.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <conio.h> 5 #include <windows.h> 6 #include <time.h> 7 #include "GreedySnake.h" 8 9 //把所有元素置为0 10 //snake[0][0]表示蛇头的行,snake[0][1]表示蛇头的列,snake[0][2]表示蛇头移动的方向 11 int snake[SNAKE_LENGTH][3] = { 0 }; 12 13 int SnakeLength = 2; //初始长度为3,但数组下标从0开始,故此处为2 14 15 char background[20][50] = 16 { 17 "████████████████████████n",//一个█占两个字节,占两个字符的位置 18 "█ █n", 19 "█ █n", 20 "█ █n", 21 "█ █n", 22 "█ █n", 23 "█ █n", 24 "█ █n", 25 "█ █n", 26 "█ █n", 27 "█ █n", 28 "█ █n", 29 "█ █n", 30 "█ █n", 31 "█ █n", 32 "█ █n", 33 "█ █n", 34 "█ █n", 35 "█ █n", 36 "████████████████████████n" 37 }; 38 39 int SnakeDir = LEFT; //蛇的方向,默认向左 40 bool bIsProFood = true; //蛇产生食物的标记 41 int row; //食物的行坐标 42 int col; //食物的列坐标 43 44 int score = 0; //分数 45 46 47 48 void FirstPage() //设置起始游戏界面 49 { 50 for (int i = 0; i < 20; ++i) 51 printf(" "); 52 for (int i = 0; i < 60; ++i) 53 printf("*"); 54 printf("n"); 55 56 for (int j = 0; j < 5; ++j) 57 { 58 for (int i = 0; i < 20; ++i) 59 printf(" "); 60 printf("*"); 61 for (int i = 0; i < 58; ++i) 62 printf(" "); 63 printf("*n"); 64 } 65 66 for (int i = 0; i < 20; ++i) 67 printf(" "); 68 printf("*"); 69 for (int i = 0; i < 15; ++i) 70 printf(" "); 71 printf("《 欢迎来到贪吃蛇的世界!》"); 72 for (int i = 0; i < 16; ++i) 73 printf(" "); 74 printf("*n"); 75 76 for (int i = 0; i < 20; ++i) 77 printf(" "); 78 printf("*"); 79 for (int i = 0; i < 15; ++i) 80 printf(" "); 81 printf("《 请按空格键开始游戏 》"); 82 for (int i = 0; i < 16; ++i) 83 printf(" "); 84 printf("*n"); 85 86 for (int j = 0; j < 10; ++j) 87 { 88 for (int i = 0; i < 20; ++i) 89 printf(" "); 90 printf("*"); 91 for (int i = 0; i < 58; ++i) 92 printf(" "); 93 printf("*n"); 94 } 95 96 for (int i = 0; i < 20; ++i) 97 printf(" "); 98 for (int i = 0; i < 60; ++i) 99 printf("*"); 100 for (int i = 0; i < 8; ++i) 101 printf("n"); 102 } 103 104 void TestSpace() //按空格开始游戏 105 { 106 char c; 107 while ((c = getch()) != ‘ ‘) //getch()在头文件<conio>内 108 { 109 110 } 111 system("cls"); //清屏 112 } 113 114 void ShowBackground() //展示游戏背景 115 { 116 for (int i = 0; i < 20; ++i) 117 printf(background[i]); 118 } 119 120 void SetSnakeRandPos() //设置蛇的初始位置,默认蛇的身子为三节,向左移动 121 { 122 int x,y; 123 srand((unsigned)time(NULL)); 124 x = rand()% 20 + 1; //因为蛇的身子起始为三节,所以x的范围为1-20(蛇不能起始就撞墙) 125 y = rand()% 18 + 1; 126 127 snake[0][0] = y; //行 注意:x,y和初始背景中的行列刚好是反的 128 snake[0][1] = x * 2; //列 注意:一个█占两个字节,所以算其坐标时要乘以2 129 snake[0][2] = LEFT; //方向 130 131 snake[1][0] = y; 132 snake[1][1] = x * 2 + 2; 133 snake[1][2] = LEFT; 134 135 snake[2][0] = y; 136 snake[2][1] = x * 2 + 4; 137 snake[2][2] = LEFT; 138 139 DrawSnake(); 140 } 141 142 void DrawSnake() //展示蛇 143 { 144 //因为一个█占两个字节,所以不能直接用strcpy(&background[snake[i][0]][snake[i][1]],"█");否则会把 拷贝进来,导致出错 145 //由于前面把snake的所有元素都置为了0,所以当snake[i][0]为0时,代表那个坐标处没有蛇的身子 146 for (int i = 0; snake[i][0] != 0; ++i) 147 strncpy(&background[snake[i][0]][snake[i][1]],"█",2); //注意取地址符&不能漏掉! 148 } 149 150 151 void DestroySnake() //销毁蛇 152 { 153 for (int i = 0; snake[i][0] != 0; ++i) 154 strncpy(&background[snake[i][0]][snake[i][1]]," ",2); //注意取地址符&不能漏掉! 155 156 } 157 158 void SnakeMove() //蛇动 159 { 160 DestroySnake(); 161 for(int i = SNAKE_LENGTH - 1; i >= 1; --i) 162 { 163 if(snake[i][0] != 0) 164 { 165 //把前一个节点的值,赋给当前节点 166 snake[i][0] = snake[i-1][0]; 167 snake[i][1] = snake[i-1][1]; 168 snake[i][2] = snake[i-1][2]; 169 } 170 } 171 172 snake[0][2] = SnakeDir; //设置蛇头方向 173 174 //处理第一个节点(蛇头) 175 if(snake[0][2] == LEFT || snake[0][2] == RIGHT) //左右移动,列加减2 176 { 177 snake[0][1] += snake[0][2]; 178 } 179 else 180 { 181 snake[0][0] += snake[0][2]; //上下移动,行加减1 182 } 183 184 DrawSnake(); 185 186 } 187 188 void ChangeDir() //改变方向 189 { 190 //不能用getchar(), 会回显,并且要按回车之后才会开始读取 191 //不能用getch(),同步检测 192 193 //异步检测 194 if(GetAsyncKeyState(‘W‘)) 195 { 196 if (snake[0][2] != DOWN) //蛇不能回头 197 SnakeDir = UP; 198 } 199 200 if(GetAsyncKeyState(‘S‘)) 201 { 202 if (snake[0][2] != UP) 203 SnakeDir = DOWN; 204 } 205 206 if(GetAsyncKeyState(‘A‘)) 207 { 208 if (snake[0][2] != RIGHT) 209 SnakeDir = LEFT; 210 } 211 212 if(GetAsyncKeyState(‘D‘)) 213 { 214 if (snake[0][2] != LEFT) 215 SnakeDir = RIGHT; 216 } 217 } 218 219 bool IsSnakeDie() //蛇死亡判断(包括撞墙和吃自己,两种情况) 220 { 221 if(snake[0][2] == LEFT || snake[0][2] == RIGHT) //如果蛇左右移动,则判断蛇头的左右是否是"█",如果是,则判定为蛇死亡 222 { 223 if(!strncmp(&background[snake[0][0]][snake[0][1]+snake[0][2]],2)) //注意取地址符&不能漏掉! 224 return true; 225 } 226 else //如果蛇上下移动,则判断蛇头的上下是否是"█" 227 { 228 if(!strncmp(&background[snake[0][0]+snake[0][2]][snake[0][1]],2)) 229 return true; 230 } 231 return false; 232 } 233 234 void ProduceFood() //随机位置产生食物 235 { 236 //判断是否产生新的食物 237 if(bIsProFood == false) 238 return; 239 240 bool flag = true; 241 srand((unsigned)time(NULL)); 242 243 while(1) //产生合法的食物,即食物不与蛇的身子重合 244 { 245 row = rand()% 18 + 1; //行 246 col = rand()% 22 + 1; 247 248 for (int i = 0; snake[i][0] != 0; i++) //遍历蛇 249 if (row == snake[i][0] && col == snake[i][1]) //如果在食物产生在蛇身上 250 { 251 flag = false; 252 break; 253 } 254 255 if(flag == true) 256 break; 257 } 258 259 strncpy(&background[row][col*2],"★",2); 260 bIsProFood = false; 261 } 262 263 void SnakeGrowUp() //蛇变长 264 { 265 if(row == snake[0][0] && col*2 == snake[0][1]) //注意:列要乘以2 266 { 267 if (UP == snake[SnakeLength][2]) 268 { 269 snake[SnakeLength+1][0] = snake[SnakeLength][0]+1; 270 snake[SnakeLength+1][1] = snake[SnakeLength][0]; 271 snake[SnakeLength+1][2] = snake[SnakeLength][2]; 272 } 273 else if (DOWN == snake[SnakeLength][2]) 274 { 275 snake[SnakeLength+1][0] = snake[SnakeLength][0]-1; 276 snake[SnakeLength+1][1] = snake[SnakeLength][0]; 277 snake[SnakeLength+1][2] = snake[SnakeLength][2]; 278 } 279 else if (LEFT == snake[SnakeLength][2]) 280 { 281 snake[SnakeLength+1][0] = snake[SnakeLength][0]; 282 snake[SnakeLength+1][1] = snake[SnakeLength][0]+2; 283 snake[SnakeLength+1][2] = snake[SnakeLength][2]; 284 } 285 else if (RIGHT == snake[SnakeLength][2]) 286 { 287 snake[SnakeLength+1][0] = snake[SnakeLength][0]; 288 snake[SnakeLength+1][1] = snake[SnakeLength][0]-2; 289 snake[SnakeLength+1][2] = snake[SnakeLength][2]; 290 } 291 SnakeLength++; 292 bIsProFood = true; 293 score++; 294 } 295 296 } 297 298 void PrintScore() //打印分数 299 { 300 COORD rd; 301 //设置光标位置 302 rd.X = 59; 303 rd.Y = 10; 304 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),rd); 305 printf("分数"); 306 307 rd.X = 60; 308 rd.Y = 11; 309 //设置光标位置 310 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),rd); 311 //打印 312 printf ("%d",score); 313 } ? main.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <conio.h> 4 #include <windows.h> 5 #include <time.h> 6 #include "GreedySnake.h" 7 8 9 int main() 10 { 11 FirstPage(); 12 TestSpace(); 13 system("cls"); 14 SetSnakeRandPos(); 15 ShowBackground(); 16 17 while (1) 18 { 19 system("cls"); 20 ProduceFood(); 21 SnakeGrowUp(); 22 ChangeDir(); 23 24 if(IsSnakeDie()) 25 { 26 printf("snake die!n"); 27 break; 28 } 29 30 SnakeMove(); 31 ShowBackground(); 32 PrintScore(); 33 34 Sleep(500); 35 } 36 system("pause"); 37 return 0; 38 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |