进击的贪吃蛇(一)

2018-06-18 03:55:09来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

有很多学习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挂起了整个程序,而读取输入正是程序的一部分。

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:说说 typedef 的那些事

下一篇:error: stray &#39;\357&#39; in program编程出错的总结