贪吃蛇小游戏

时间:2021-07-15 23:52:15

   贪吃蛇实现基本的移动、吃掉食物、加速、暂停、显示游戏分数等基本功能。

代码如下:

  1 “Snake.c”   2 
  3 #include <stdio.h>
  4 #include <windows.h>
  5 #define FOOD "■" 
  6 #define MAPLINES 80   //地图长度 
  7 #define MAPCOLS 26    //地图高度 
  8 
  9 #define _INIT_X 30    //蛇的初始x坐标 
 10 #define _INIT_Y 10    //蛇的初始y坐标 
 11 typedef struct node{  //蛇的身体结点 
 12     int x;
 13     int y;
 14     struct node *next;
 15 }SnakeNode,*pSnakeNode;
 16 
 17 //控制方向 
 18 enum DIRECTION{    
 19     UP =1,
 20     DOWN,
 21     LEFT,
 22     RIGHT,
 23 };
 24 //蛇的状态 
 25 enum State {
 26     OK,
 27     KILL,        //正常死 
 28     KILL_BY_SELF,
 29     KILL_BY_WALL, 
 30 }; 
 31 
 32 //蛇身体 
 33 typedef struct snake{
 34     pSnakeNode _pSnake;   //蛇头指针 
 35     pSnakeNode _pFood;    //食物 
 36     enum DIRECTION _Dir;  //方向 
 37     enum State _State;    //蛇状态
 38     int _SleepTime;       //停留时间 
 39 }Snake,*pSnake;
 40 
 41 
 42 void SetPosition(int x,int y){   //获取光标位置 
 43     HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
 44     COORD pos = {0};
 45     pos.X = x;
 46     pos.Y = y;
 47     SetConsoleCursorPosition(handle, pos);  //设置控制台光标 
 48 }
 49 
 50 void DropMap(){    
 51     int i=0;
 52     for(; i < MAPLINES; i+=2){
 53         SetPosition(i ,0);
 54         printf(FOOD) ;
 55     }
 56     for(i=0; i<MAPCOLS ; ++i){
 57         SetPosition( 0, i);
 58         printf(FOOD);
 59         SetPosition( MAPLINES-2,i); 
 60         printf(FOOD);
 61     }
 62     for(i=0; i<MAPLINES ; i+=2){
 63         SetPosition( i, MAPCOLS);
 64         printf(FOOD);
 65     }
 66 }
 67 void InitSnake(pSnake ps){
 68     pSnakeNode cur =NULL;
 69     int i=0;
 70     
 71     cur = malloc(sizeof(SnakeNode));
 72     memset(cur, 0, sizeof(SnakeNode));
 73     cur->x = _INIT_X;
 74     cur->y = _INIT_Y;
 75     cur->next = NULL;
 76     //将蛇节点连接起来 
 77     for(i = 1; i<=2 ;++i){
 78         ps->_pSnake = malloc(sizeof(SnakeNode));
 79         ps->_pSnake->next = cur;
 80         ps->_pSnake->x = _INIT_X + i*2;    //初始坐标 
 81         ps->_pSnake->y = _INIT_Y ;
 82         cur = ps->_pSnake;
 83     }
 84     //画结点 
 85     while(cur != NULL){
 86         SetPosition(cur->x,cur->y);
 87         printf(FOOD);
 88         cur = cur->next;
 89     }
 90     
 91     ps->_SleepTime = 500; //控制蛇的初始移动速度 
 92     ps->_State= OK;
 93     ps->_Dir = RIGHT;    //蛇初始移动方向 
 94     ps->_pFood = malloc(sizeof(SnakeNode)); 
 95 }
 96 void CreateFood(pSnake ps){      //画食物 
 97     pSnakeNode cur = NULL;
 98     pSnakeNode food = NULL;
 99     
100     food = malloc(sizeof(SnakeNode));
101 oncemore:
102     memset(food ,0 ,sizeof(SnakeNode));
103     do{
104         food->x = rand() % MAPLINES-2 ;  
105        food->y = rand() % MAPCOLS-1 ;
106     }       
107     while(food->x %2 != 0 || food->x <2 || food->y <1);
108        
109     
110     cur = ps->_pSnake;
111     while(cur != NULL){
112         if(cur->x ==food->x && cur->y == food->y){
113             goto oncemore;
114         }
115         cur =cur->next; 
116     }
117     ps->_pFood->x = food->x;   // 
118     ps->_pFood->y = food->y;   //
119     SetPosition(food->x,food->y);
120     printf(FOOD);
121     
122 }
123 int NextHasFood(pSnake ps,pSnakeNode newNode){  //根据蛇头坐标判断移动过程中是否遇到食物 
124     if((ps->_pFood->x == newNode->x) 
125         && (ps->_pFood->y == newNode->y)) 
126     {
127         return 1;
128     }
129     return 0;
130 }
131 
132 void EatFood(pSnake ps,pSnakeNode newNode){   //吃掉食物 
133     //将新加入的蛇节点链到蛇头 
134     pSnakeNode cur = ps->_pSnake;
135     newNode->next = cur;
136     ps->_pSnake = newNode;
137     //cur重新指向蛇头
138     cur = ps->_pSnake;
139     while( cur != NULL){
140         SetPosition(cur->x, cur->y);
141         printf(FOOD);
142         cur =cur->next;
143     }
144     CreateFood(ps);
145 }
146 
147 void NoFood(pSnake ps,pSnakeNode newNode){   //不吃食物,正常移动一次 
148     
149     pSnakeNode cur = ps->_pSnake;
150     newNode->next = cur;
151     ps->_pSnake = newNode;
152      
153     cur = ps->_pSnake;
154     while(cur->next->next !=NULL){
155         SetPosition(cur->x, cur->y);
156         printf(FOOD);
157         cur =cur->next;
158     } 
159     SetPosition(cur->next->x,cur->next->y);
160     printf("  ");
161     free(cur->next);
162     cur->next= NULL;
163 }
164 void MoveSnake(pSnake ps){     //让蛇动起来 
165     //重新构造一个蛇头 
166     pSnakeNode newNode = malloc(sizeof(SnakeNode));
167     memset(newNode,0,sizeof(SnakeNode));
168     
169     newNode->x =ps->_pSnake->x; 
170     newNode->y =ps->_pSnake->y;
171     switch(ps->_Dir){    //  移动方向 坐标做出相应的变化 
172         case UP:
173             newNode->y--;
174             break;
175         case DOWN:
176             newNode->y++;
177             break;
178         case LEFT:
179             newNode->x-=2;
180             break;
181         case RIGHT:
182             newNode->x+=2; 
183             break;
184         default:
185             break;
186     } 
187     if(NextHasFood(ps,newNode)){
188         EatFood(ps,newNode);    
189     }
190     else{
191         NoFood(ps,newNode);
192     }
193 }
194 
195 int KillBySelf(pSnake ps){      //蛇撞自己死法 
196    pSnakeNode cur = ps->_pSnake->next;
197    
198    while(cur != NULL){
199        if((cur->x == ps->_pSnake->x) && (cur->y == ps->_pSnake->y)){
200            return 1;
201        }
202        cur = cur->next;
203    }
204    return 0;    
205 } 
206 int KillByWall(pSnake ps){       //蛇撞墙死 
207     if(ps->_pSnake->x == 0 || ps->_pSnake->x == MAPLINES - 2
208      || ps->_pSnake->y == 0 || ps->_pSnake->y == MAPCOLS )
209     return 1;
210    return 0;
211 }
212 int Kill(pSnake ps){
213     size_t count = 0;
214     pSnakeNode cur = ps->_pSnake;
215     while(cur != NULL){
216         count++;
217         cur = cur->next;
218     }
219     if(count == (MAPLINES -4)*(MAPCOLS -2)/4){
220         return 1;
221     }
222     return 0;
223 }
224 int SpeedUp(pSnake ps){      //给蛇加速 
225     if( GetAsyncKeyState(VK_UP)  || GetAsyncKeyState(VK_DOWN) || 
226         GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState(VK_RIGHT) ){
227       return 50;
228     }    
229     return 400;
230 }
231 
232 int StopGame( pSnake ps){   //暂停游戏 
233     if(GetAsyncKeyState(VK_ESCAPE)){
234         SetPosition(80,3);
235         printf("暂停(按空格继续...)");
236         while(1){
237             if(GetAsyncKeyState(VK_SPACE)){
238               goto ContinueGame; 
239             }
240         }
241     }
242 ContinueGame:
243     SetPosition(80,3);
244     printf("                   ");
245     return 1;
246 } 
247 
248 void ShowScore(pSnake ps){    //显示分数 
249     
250     size_t count = 0;
251     pSnakeNode cur = ps->_pSnake;
252     while(cur != NULL){
253         count++;
254         cur = cur->next;
255     }
256     SetPosition(80,6);
257     printf("当前分数:%d",(count-3 )*10); 
258 }
259 void ControlSnake(pSnake ps){    //控制蛇
260     do{
261         if(GetAsyncKeyState(VK_DOWN) && ps->_Dir!=UP){
262             ps->_Dir =DOWN; 
263         }
264         if(GetAsyncKeyState(VK_UP) && ps->_Dir!=DOWN){
265             ps->_Dir =UP; 
266         }
267         if(GetAsyncKeyState(VK_LEFT) && ps->_Dir!=RIGHT){
268             ps->_Dir =LEFT; 
269         }
270         if(GetAsyncKeyState(VK_RIGHT) && ps->_Dir!=LEFT){
271             ps->_Dir =RIGHT; 
272         }
273         if(StopGame(ps)){
274             ShowScore(ps);
275             MoveSnake(ps);        
276             Sleep(SpeedUp(ps));
277         }        
278         
279         if(KillBySelf(ps))
280            ps->_State = KILL_BY_SELF;
281         if(KillByWall(ps))
282            ps->_State = KILL_BY_WALL ; 
283         if(Kill(ps)) 
284            ps->_State == KILL;
285            
286     }while(ps->_State == OK);  
287     
288     if(ps->_State == KILL){
289         SetPosition(82,3); 
290         printf("厉害厉害!"); 
291     }
292     if(ps->_State == KILL_BY_WALL){
293         SetPosition(82,3); 
294         printf("撞墙死了!"); 
295         //exit(1);
296     }
297     if(ps->_State == KILL_BY_SELF){
298         SetPosition(82,3); 
299         printf("撞自己死!"); 
300         
301     }    
302 }
303 
304 
305 
306 void StartGame(){       //初始化游戏 
307     srand(time(NULL));
308     DropMap();
309     Snake s;
310     memset(&s, 0, sizeof(SnakeNode));
311     InitSnake(&s);
312     CreateFood(&s);
313     //MoveSnake(&s);
314     ControlSnake(&s);
315     
316 }
317 void Welcome(){
318     system("mode con cols=100 lines=30"); 319     printf("        *************** Snake of Eat   **************\n");
320     printf("        *******   ↑ ↓ ← →   Control Direction****\n");
321     printf("        *********************************************\n");
322     getchar();
323     system("cls");
324 }
 1 .C文件
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <windows.h>
 5 int main(int argc, char *argv[]) {
 6     system("color f4");
 7     Welcome();
 8     StartGame(); 
 9        return 0;
10 }