【C 语⾔】贪吃蛇⼩游戏代码详解
贪吃蛇的规则⼤家应该都知道,简单来说就是吃到⾷物则蛇⾝增长,蛇可以在游戏区域内随意移动。游戏结束条件就是蛇撞到边界或者撞到
⾃⼰⾊蛇⾝。
⾸先,实现⼀个函数,这个函数的作⽤是将移动到我们所期望的位置
构建结构体对象
设计这个游戏,最重要的两个对象就是蛇和⾷物,因此⽤两个结构体来代表这两个对象。⾷物只关注其坐标位置,蛇的话,成员包括坐标数组,长度和分数。
初始化游戏边界和⼩蛇/* *  控制光标所在的位置 */void  gotoxy (int  x , int  y ){ COORD coord ; coord .X = x ; coord .Y = y ; SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE ), coord );}
1
2
3
4
5
6
7
8
9
10// 定义游戏区域的边界宽度#define    WIDTH        100#define    HIGH        20// 定义蛇的最⼤长度#define    MAX_LENGHT  100// 定义游戏初始速度#define    SPEED        500// 定义游戏中的两个对象:⾷物和蛇struct { int  x ; int  y ;}food ;struct { int  len ; int  x_buf [MAX_LENGHT ]; int  y_buf [MAX_LENGHT ]; int  score ;}snake ;// 要⽤到的全局变量int  food_flag = 0;int  key = 72;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
这个没什么难度,就是循环打印,直接放代码。
注意最后⼀⾏使⽤gotoxy函数移动函数很重要,不然光标会在游戏区域内持续闪烁,在退出游戏时,甚⾄会出现显⽰问题。(为了避免遗漏,我基本在每个涉及到光标移动的函数最后都加了这句话)/*  *  绘制游戏区域边界 */void  DrawMap (void ){ int  x , y ; for  (x = 0; x < WIDTH + 4; x += 2) {  y = 0;  gotoxy (x , y );  printf ("■");  y = HIGH + 2;  gotoxy (x , y );  printf ("■"); } for  (y = 1; y < HIGH + 2; y ++)
{  x = 0;  gotoxy (x , y );  printf ("■");  x = WIDTH + 2;  gotoxy (x , y );  printf ("■"); } // 将光标移出游戏区域 gotoxy (0, HIGH + 5);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
贪吃蛇的编程代码
22
23
24
25
26
27
28
29
⽣成⾷物
我使⽤⼀个标志位food_flag来代表区域内是否存在⾷物(初始时刻,以及蛇吃到⾷物时,food_flag为0)。当food_flag为0时就执⾏⽣成⾷物的操作。由于要保证游戏的随机性,⽤随机数来⽣成⾷物坐标。/* *  初始化⼩蛇 */void  CreateSnake (void ){ int  orgin_x , orgin_y ; orgin_x = WIDTH / 2 + 2; orgi
n_y = HIGH / 2 + 1; snake .len = 3; snake .x_buf [0] = orgin_x ; snake .y_buf [0] = orgin_y ; snake .x_buf [1] = orgin_x ; snake .y_buf [1] = ++orgin_y ; snake .x_buf [2] = orgin_x ; snake .y_buf [2] = ++orgin_y ; snake .score = -1; int  i ; for  (i = 0; i < snake .len ; i ++) {  gotoxy (snake .x_buf [i ], snake .y_buf [i ]);  printf ("■"); } gotoxy (0, HIGH + 5);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
实现的⽅法都⼤同⼩异,但是我强调的点是随机⽣成坐标的实现。由于字符"■"是占两位,所以横坐标必须为2的倍数。其他的帖⼦⾥⼀般是⽤以下⽅法
然后通过while循环来判断x是否适合要求,不符合就重新⽣成。但这种做法会出现⼀种问题,游戏进⾏过程中会出现卡顿的效果。主要原因就是奇偶数出现概率各占50%,因此有⼤概率出现多次的循环
操作。
我的⽅法如下,这样的好处是可以保证⽣成的横坐标⼀定是偶数。避免了⼤量的循环操作。
移动⼩蛇
⾸先要对snake对象中坐标缓存区内的坐标进⾏后移,以便装⼊新的坐标。在此要分两种情况,⼀是⼩蛇没吃到⾷物,则抹去最后⼀节,在头部加⼊新坐标;⼆是⼩蛇吃到⾷物,则不删去最后⼀节。/* *  当游戏区域内不存在⾷物时,随机创造⼀个⾷物 */void  CreateFood (void ){ if  (food_flag == 0) {  int  flag = 0,i ;  do  {  srand ((unsigned  int )time (NULL ));  food .x = (rand () % (WIDTH /2))*2 + 2;  food .y = rand () % HIGH + 1;  // 判断⽣成的⾷物是否和蛇⾝重合  for  (i = 0; i < snake .len ; i ++)  {    if  (snake .x_buf [i ] == food .x && snake .y_buf [i ] == food .y )    {    flag = 1;    break ;    }  }  } while  (flag );  gotoxy (food .x , food .y );  printf ("★");  // 吃到⾷物,则分数加1  snake .score ++;  food_flag = 1; } gotoxy (0, HIGH + 5);}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36food .x = rand () % WIDTH + 2;food .y = rand () % HIGH + 1;
1
2food .x = (rand () % (WIDTH /2))*2 + 2;food .y = rand () % HIGH + 1;
1
2
随后根据⽤户按键,改变⼩蛇前进⽅向。这块部分代码也是我移植过来的,有详细的注释,就不在这赘述了。void  SnakeMove (int  x , int  y ){ // 判断是否吃到⾷物,吃到长度加1 if  (!food_flag )  snake .len ++; // 没吃到则抹去最后⼀节 else  {  gotoxy (snake .x_buf [snake .len - 1], snake .y_buf [snake .len - 1]);  printf ("  "); } int  i ; for  (i = snake .len - 1; i > 0; i --) {  snake .x_buf [i ] = snake .x_buf [i - 1];  snake .y_buf [i ] = snake .y_buf [i - 1]; } snake .x_buf [0] = x ; snake .y_buf [0] = y ; gotoxy (snake .x_buf [0], snake .y_buf [0]); printf ("■"); gotoxy (0, HIGH + 5);}
1234567891011121314151617181920212223

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。