进化的贪吃蛇(一)
程序员文章站
2022-03-21 20:33:50
有很多学习C语言或者C++的朋友可能写过贪吃蛇的作业,我也是其中之一。在最开始写的时候自己水平很差,写出的效果还不如许多同学从网上抄的。 这一系列博客都是使用C语言写贪吃蛇,逐步提升难度,当然自己也好久不动手了,也算是自己复习一次C语言。 第一个贪吃蛇,因为许多刚学完C的同学并不了解太多东西,所以我 ......
有很多学习C语言或者C++的朋友可能写过贪吃蛇的作业,我也是其中之一。在最开始写的时候自己水平很差,写出的效果还不如许多同学从网上抄的。
这一系列博客都是使用C语言写贪吃蛇,逐步提升难度,当然自己也好久不动手了,也算是自己复习一次C语言。
第一个贪吃蛇,因为许多刚学完C的同学并不了解太多东西,所以我们只使用最基本的方法,完成最基本的功能。当然,我们得到的效果可能也就不是很好。
1 #include <stdio.h> 2 3 //随机数生成 4 #include <stdlib.h> 5 #include <time.h> 6 7 //Windows API 8 #include <Windows.h> 9 10 //游戏常量设置 11 #define MAP_H 10 12 #define MAP_W 20 13 #define INIT_LEN 2 14 #define GAME_SPEED 200 15 16 #define CH_SNAKE 'O' 17 #define CH_FOOD '*' 18 #define CH_WALL 'H' 19 #define CH_SPACE ' ' 20 21 char map[MAP_H][MAP_W]; 22 struct _point{ 23 int y; 24 int x; 25 }snake[MAP_H*MAP_W]; 26 int snakeLength; 27 enum _direction{ 28 UP,LEFT,RIGHT,DOWN 29 }direction; 30 31 void initialize();//初始化 32 int update();//更新画面 33 void generateFood();//生成食物 34 void changeDirection();//方向控制 35 void showMap();//显示画面 36 37 /************* 38 * 基本的游戏逻辑:显示、控制、更新 39 */ 40 int main(){ 41 42 initialize(); 43 do{ 44 showMap(); 45 changeDirection(); 46 }while(update()); 47 48 return 0; 49 } 50 51 /******************* 52 * 初始化画面数组、蛇身体的坐标数组、蛇的长度、最后在地图上生成一个食物 53 */ 54 void initialize(){ 55 int i,j; 56 snakeLength=INIT_LEN; 57 direction=RIGHT; 58 59 for(i=0;i<MAP_H;i++){ 60 for(j=0;j<MAP_W;j++){ 61 map[i][j]=CH_SPACE; 62 } 63 } 64 65 for(i=0;i<INIT_LEN;i++){ 66 snake[i].x=INIT_LEN-i-1; 67 snake[i].y=0; 68 } 69 70 for(i=0;i<snakeLength;i++){ 71 map[snake[i].y][snake[i].x]=CH_SNAKE; 72 } 73 74 generateFood(); 75 } 76 77 /******************* 78 * Sleep控制游戏速度,system函数调用console指令cls清屏,最后循环输出画面 79 */ 80 void showMap(){ 81 system("cls"); 82 int i,j; 83 84 for(i=0;i<MAP_W+2;i++){ 85 putchar(CH_WALL); 86 } 87 putchar('\n'); 88 89 for(i=0;i<MAP_H;i++){ 90 putchar(CH_WALL); 91 for(j=0;j<MAP_W;j++){ 92 putchar(map[i][j]); 93 } 94 putchar(CH_WALL); 95 putchar('\n'); 96 } 97 98 for(i=0;i<MAP_W+2;i++){ 99 putchar(CH_WALL); 100 } 101 } 102 103 /******************* 104 * 使用随机数产生食物的坐标 105 */ 106 void generateFood(){ 107 int x,y; 108 srand(time(0)); 109 while(1){ 110 x=rand()%MAP_W; 111 y=rand()%MAP_H; 112 if(map[y][x]==CH_SPACE) 113 break; 114 } 115 map[y][x]=CH_FOOD; 116 } 117 118 /******************* 119 * 更新画面(游戏逻辑处理的部分) 120 * 通过direction计算下一个画面蛇头到达的位置,检查该位置的物体,分别处理不同情形 121 */ 122 int update(){ 123 Sleep(GAME_SPEED); 124 int i,head_y,head_x; 125 126 switch(direction){ 127 case UP: 128 head_y=snake[0].y-1; 129 head_x=snake[0].x; 130 break; 131 case LEFT: 132 head_y=snake[0].y; 133 head_x=snake[0].x-1; 134 break; 135 case RIGHT: 136 head_y=snake[0].y; 137 head_x=snake[0].x+1; 138 break; 139 case DOWN: 140 head_y=snake[0].y+1; 141 head_x=snake[0].x; 142 break; 143 } 144 if(head_x<0||head_x>MAP_W||head_y<0||head_y>MAP_H){ 145 return 0;//撞墙 146 } 147 148 if(map[head_y][head_x]==CH_SNAKE){ 149 return 0;//撞自己 150 } 151 if(map[head_y][head_x]==CH_FOOD){ 152 for(i=snakeLength;i>0;i--){ 153 snake[i]=snake[i-1]; 154 } 155 snake[0].x=head_x; 156 snake[0].y=head_y; 157 map[head_y][head_x]=CH_SNAKE; 158 snakeLength+=1; 159 generateFood(); 160 return 1;//吃食物 161 } 162 if(map[head_y][head_x]==CH_SPACE){ 163 map[snake[snakeLength-1].y][snake[snakeLength-1].x]=CH_SPACE; 164 for(i=snakeLength-1;i>0;i--){ 165 snake[i]=snake[i-1]; 166 } 167 snake[0].x=head_x; 168 snake[0].y=head_y; 169 map[head_y][head_x]=CH_SNAKE; 170 return 1;//继续前进 171 } 172 173 return 1; 174 } 175 176 /******************* 177 * 使用GetKeyState获取键盘输入,改变direction变量来控制行进方向 178 */ 179 void changeDirection(){ 180 if(GetKeyState(VK_UP)<0&&direction!=DOWN) 181 direction=UP; 182 else if(GetKeyState(VK_LEFT)<0&&direction!=RIGHT) 183 direction=LEFT; 184 else if(GetKeyState(VK_DOWN)<0&&direction!=UP) 185 direction=DOWN; 186 else if(GetKeyState(VK_RIGHT)<0&&direction!=LEFT) 187 direction=RIGHT; 188 }
这差不多就是我第一次写的,相当的简陋,使用体验很差。但是除了Sleep,system,GetKeyState之外并没有什么C语言课本上没教过的。
Sleep函数使控制台挂起(停下来),控制游戏速度。
system函数是用于输入控制台命令的,cls是控制台用于清屏的命令
GetKeyState函数用于读取键盘上某个特定按键的状态,这里用于读取用户输入(控制方向)
当然,现在上面的代码除了基本的游戏逻辑什么都没有。而且还会闪屏,最坑的是因为Sleep函数,按键有时候并不能被读取,这是因为Sleep挂起了整个程序,而读取输入正是程序的一部分。
上一篇: vue 组件
下一篇: Python开发【三】数据类型