C程序设计 贪吃蛇分析(4)

今天早上早起起来写代码

主要是完善了 暂停和重新开始游戏,以及退出功能。

对界面进行了完善。

然后是使用了PCC32库文件。

调用了函数setTextColor(),实现了彩色功能。

界面也更人性化了点,

还有待改进。

下午继续,!

  1 //Lee. 控制台 贪吃蛇
  2 //测试版本1.0
  3 //几点疑问,1.为什么Map[79][24]  地图的横坐标都要用X * 2的形式,,
  4 //                                   而纵坐标         的1却表示两个字节。
  5 /*3.3.1 画地图    (即横坐标1表示一个宽度,但是纵坐标的1表示两个宽度)
  6 因为是字符游戏,地图并不是那么重要,只要有个标记能让玩家看清边界就行了. 但是
  7 根据我的经验,控制台中的一行的高度大约为一列的宽度的两倍. 换句话说,在控制台中,一
  8 个1×1的格子,其实是个长方形,它的高度为宽度的两倍. 因此,为了美观起见,我的横坐标
  9 (列值)一律使用双倍值,这样看上去就是一个匀称的方格子. ASCII 字符全都是一个字符宽
 10 度的,因此,我在本文接下来的部分中,统一使用中文宽字符来进行布局. 典型的中文布局符
 11 号有以下这些:
 12 ◆◇□■●●★☆▲△¤◎+┏┛┗┓━┃┫┣┳┻╋
 13 这些符号通常可以在中文输入法的"特殊符号"和"制表符号"两种软键盘中找到. 为了
 14 便于输入,可以事先写在程序的注释中,然后复制到需要的地方去.
 15 */
 16 //                            
 17 //            2. 光标隐藏函数有什么用,好像不需要这个函数也没有影响。
 18 //            3. Key()函数和注释掉了的那个Key()函数有什么区别,没煮熟掉的那个我看不懂。
 19 //            后来我发现了,用我注释掉的那个,,,在左右运动的时候有BUG,但是我不理解在使用的那个Key();
 20 //            现在理解了
 21 
 22 #include<iostream>
 23 #include<windows.h>
 24 #include<conio.h>
 25 #include<time.h>
 26 #include<stdlib.h>
 27 #include"pcc32.h"
 28 #pragma comment(lib, "pcc32_vc6.lib")
 29 
 30 using namespace std;
 31 
 32 #define UP 72        //定义上下左右常量
 33 #define DOWN 80
 34 #define LEFT 75
 35 #define RIGHT 77
 36 #define ESC 27
 37 #define SPACE 32
 38 
 39 int X, Y;//食物坐标
 40 
 41 int Map[79][24]={{0}};    //    地图尺寸,其实有食物记为1
 42 int over = 0;             //用来标记游戏结束
 43 int score = 0;            //记录分数            
 44 int ColoArray[15]={15,1,2,3,4,5,6,7,8,9,10,11,12,13,14};    //自己定义的用来控制颜色的数组
 45 struct Snake
 46 {
 47     int x, y;            //坐标
 48     int direction;        //方向
 49 }Snake[100];            //蛇最多100个节点
 50 
 51 int length = 3;            //初始化蛇的长度为3
 52 
 53 void GamePrint();        //游戏开始画面函数
 54 void Gameinit();        //游戏初始化函数
 55 void Sweep_Screem();    //清屏函数
 56 void Gotoxy(int , int); //光标移动函数
 57 void Hid_Cursor();        //光标隐藏函数
 58 void Snake_Move();        //蛇运动函数
 59 void Create_Food();        //食物产生函数
 60 void Pwall();            //画墙函数
 61 void Key();                //键盘操作和处理函数
 62 void Hit_Wall();        //判断是否撞墙
 63 void Eat_Itself();        //判断是否咬到自己
 64 void Whether_Eat();        //判断蛇是否吃到食物
 65 void GameRun();            //游戏运行函数
 66 void SurFace();
 67 void GameOver();
 68 void Pause();          //游戏暂停函数
 69 void MyCount1();            //提示边栏,用来做一些提示
 70 void MyCount2();            //统计边栏,用来做一些统计
 71 
 72 int main()                //主函数
 73 {
 74 START:
 75 //    fixConsoleSize(18,15);
 76     Hid_Cursor();
 77 //    SurFace();
 78     fixConsoleSize(105,25);
 79     GamePrint();
 80     Gameinit();        
 81     GameRun();
 82     while(over)                //如果游戏结束了,是否重新开始。按R键为重新开始
 83         {
 84             int t=getch();
 85             if(t == 'r'||t == 'R')
 86             {
 87                 system("cls");
 88                 goto START;
 89             }
 90         }
 91     
 92     return 0;
 93 }
 94 
 95 
 96 
 97 
 98 void GamePrint()        //游戏开始画面函数(先是欢迎界面,然后是游戏规则,然后是画墙)
 99 {
100     Gotoxy(36,8);
101     printf("┏┅┅┅┅┅┅┅┅┅┅┅┅┅┓");
102     Gotoxy(36,9);
103     printf("┠   Welcome to RedSnake.   ┨");
104     Gotoxy(36,10);
105     printf("┠         by_Lee.          ┨");
106     Gotoxy(36,11);
107     printf("┗┅┅┅┅┅┅┅┅┅┅┅┅┅┛");
108     Sleep(2000);
109     Sweep_Screem();
110     Gotoxy(41, 7);
111     printf("┏┯┯┯┯┯┯┯┓");
112     Gotoxy(41, 8);
113     printf("┠   Game Tips  ┨");
114     Gotoxy(41, 9);
115     printf("┠   ↑    Up   ┨");
116     Gotoxy(41, 10);
117     printf("┠   ↓   Down  ┨");
118     Gotoxy(41, 11);
119     printf("┠   ←   Left  ┨");
120     Gotoxy(41, 12);
121     printf("┠   →   Right ┨");
122     Gotoxy(41, 13);
123     printf("┠  ESC   Exit  ┨");
124     Gotoxy(41, 14);
125     printf("┠ SPACE  Pause ┨");
126     Gotoxy(41, 15);
127     printf("┗┷┷┷┷┷┷┷┛");
128 
129     Sleep(2200);   
130     Sweep_Screem();
131     Pwall();            //画墙函数
132     MyCount1();            //画边栏
133     Sleep(1100);
134 }
135 
136 
137 void Gameinit()                                //游戏初始化
138 {
139     Snake[0].x = 10;                        //  ■■□ 实际上是固定了初始蛇的位置
140     Snake[0].y = 12;
141     Snake[1].x = 8;
142     Snake[1].y = 12;
143     Snake[2].x = 6;
144     Snake[2].y = 12;
145     Snake[0].direction = RIGHT;                //默认蛇的初始状态为向右运动
146     Gotoxy(10, 12);                            //根据蛇的位置跳转,并打印蛇头和蛇身
147     printf("");    
148     Gotoxy(8, 12);
149     printf("");
150     Gotoxy(6, 12);
151     printf("");
152 }
153 
154 
155 void Sweep_Screem()//清屏函数
156 {
157     int i;
158     Gotoxy(0, 0);
159     for(i = 0;i < 25; i++)
160     {
161         printf("                                                                                ");
162     }
163 }
164 
165 void Gotoxy(int x, int y)//移动光标
166 {
167     COORD coord; 
168     coord.X=x;
169     coord.Y=y;
170     SetConsoleCursorPosition( GetStdHandle( STD_OUTPUT_HANDLE ), coord );
171 }
172 
173 void Hid_Cursor()        //光标隐藏函数
174 {
175     HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
176     CONSOLE_CURSOR_INFO cci;
177     GetConsoleCursorInfo(hOut,&cci);
178     cci.bVisible=0;//赋1为显示,赋0为隐藏
179     SetConsoleCursorInfo(hOut,&cci);
180 }
181 
182 
183 void Snake_Move()        //蛇运动函数
184 {
185     int i, c, pause = 0, temp = 0;
186     srand(time(NULL));
187     Gotoxy(Snake[0].x, Snake[0].y);
188     setTextColor(ColoArray[rand()%14]);
189     printf("");
190     Gotoxy(Snake[1].x, Snake[1].y);
191     setTextColor(ColoArray[rand()%14]);
192     printf("");    
193     Whether_Eat();    //检查是否吃到食物,如果吃到食物,蛇头坐标Map[Snake[0].x][Snake[0].y] = 0;
194     setTextColor(ColoArray[rand()%14]);
195     Create_Food();            //重新随机出一个食物,并且蛇的长度增加1,且新的蛇头产生
196     Gotoxy(Snake[length].x, Snake[length].y);
197     printf(" ");                        //消除原来的蛇尾。
198         //判断蛇是否吃到食物,如果吃到,则再Create一个食物
199 //    Gotoxy(0, 0);        //有BUG ,不知道怎么回事
200 //    printf("■");        //有BUG ,不知道怎么回事
201 
202     Eat_Itself();                            //判断蛇是否咬到自己
203     for(i = length; i > 0; i--)                //移动蛇的坐标
204         Snake[i] = Snake[i-1];
205 
206     Key();                                    //判断用户的键盘输入并进行处理
207 }
208 
209 /*void Snake_Move()
210 {    
211 char c,pause;
212 static char temp = 0;//静态局部变量
213 pause = 0;
214 if(!temp){//一开始的时候让蛇先自动移动
215 temp = RIGHT;
216 Snake_Auto_Move(temp);
217 }
218 while(1){
219 c = getch();
220 if(c == ESC){//退出
221 system("cls");
222 puts("游戏退出成功!");
223 system("pause");
224 exit(0);
225 }
226 if(pause == SPACE){
227 if(c == SPACE){//再按下空格键继续游戏
228 pause = 0;
229 Gotoxy(6,20);
230 printf("           ");//消除~~Pause~~:
231 Snake_Auto_Move(temp);
232 }
233 continue;
234 }
235 if(c == SPACE){//按空格键暂停游戏
236 pause = SPACE;
237 Gotoxy(6,20);
238 printf("~~Pause~~:");
239 continue;
240 }*/
241 
242 void Create_Food()    //食物产生函数
243 {
244     int i;
245     if(Map[X][Y] == 0)
246     {
247         srand((unsigned int)time(0) + X);//等同于srand(time(0))或者srand(time(NULL))或者srand((int)time(0)),因为最终都要被强制转换为unsigned int;
248         X = (rand() % 38 + 1) * 2;
249         //X = rand() % 76 ;错误为什么?
250         
251         srand((unsigned int)time(0) + Y + rand());
252         Y = rand() % 23 + 1;
253         for(i = 0; i < length; i++)
254             if(Snake[i].x == X && Snake[i].y == Y)
255             {
256                 i = -1;
257                 break;
258             }
259             if(i != -1)
260             {
261                 Map[X][Y] = 1;
262                 Gotoxy(X, Y);
263                 srand(time(NULL));
264                 setTextColor(ColoArray[rand()%14]);
265                 printf("");
266             }
267     }
268 }
269 
270 void Whether_Eat()                        //判断蛇是否吃到食物
271 {
272     if(Map[Snake[0].x][Snake[0].y] == 1)
273     {    
274         length++;
275         score += 10;
276         Map[Snake[0].x][Snake[0].y] = 0;
277     }
278 }
279 
280 void Eat_Itself()                        //判断蛇是否咬到自己
281 {
282     int i;
283     for(i = 3; i < length; i++)
284     {
285         if(Snake[0].x == Snake[i].x && Snake[0].y == Snake[i].y)
286         {
287             over=1;
288             break;
289         }
290     }
291 }
292 
293 void Hit_Wall()                    //判断是否撞墙    
294 {
295     if(Snake[0].x == 0)            Snake[0].x = 76;
296     if(Snake[0].x == 78)        Snake[0].x = 2;
297     if(Snake[0].y == 0)            Snake[0].y = 23;
298     if(Snake[0].y == 24)        Snake[0].y = 1;
299 }
300 
301 
302 void Key()                        
303 {
304     if(_kbhit())//判断是否按键
305     {              
306         int ch = _getch();
307         if(ch == 224)//判断按的是不是方向键
308         {
309             ch = _getch();
310             if(ch+Snake[0].direction != 152)//判断按键是否是反方向
311                 Snake[0].direction = ch;//如果不是就改变蛇头方向
312         }
313         else if(ch == 27)//判断用户是否退出
314         {
315 
316             Gotoxy(30,12);
317             setTextColor(WHITE);
318             printf(" Successful Exit!\n                           ");
319             exit(0);
320         }
321         else if(ch == 32)
322         {
323             Pause();
324         }
325     }
326     switch(Snake[0].direction)
327     {
328     case 72: Snake[0].y-=1; break;
329     case 80: Snake[0].y+=1; break;
330     case 75: Snake[0].x-=2; break;
331     case 77: Snake[0].x+=2; break;
332     }    
333 }
334 
335 /*
336 if(c == ESC){//退出
337     system("cls");
338     puts("游戏退出成功!");
339     system("pause");
340     exit(0);
341 }
342 if(pause == SPACE){
343     if(c == SPACE){//再按下空格键继续游戏
344         pause = 0;
345         Gotoxy(6,20);
346         printf("           ");//消除~~Pause~~:
347         Snake_Auto_Move(temp);
348 }
349 continue;
350 }
351 if(c == SPACE){//按空格键暂停游戏
352     pause = SPACE;
353     Gotoxy(6,20);
354     printf("~~Pause~~:");
355     continue;*/
356 
357 
358 
359 
360 
361 
362 /*void Key()
363 {
364 if(kbhit() != 0)
365 {
366     while(kbhit() != 0)
367     {
368         Snake[0].direction = getch();
369     }
370     }
371     switch(Snake[0].direction)
372     {
373     case 72: Snake[0].y-=1; break;
374     case 80: Snake[0].y+=1; break;
375     case 75: Snake[0].x-=2; break;
376     case 77: Snake[0].x+=2; break;
377     }    
378 }
379 */
380 
381 
382 void Pwall()                    //画墙函数
383 {
384     srand(time(NULL));
385     int i, j;
386     for(i = 39,j = 0; j < 39; i--, j++)
387     {
388         setTextColor(ColoArray[rand()%14]);
389         Gotoxy(j*2, 0);
390         printf("");
391         if(j < 24)
392         {
393             setTextColor(ColoArray[rand()%14]);
394             Gotoxy(78, j);
395             printf("");
396         }
397         Gotoxy(i*2, 24);
398         printf("");
399         if(i > 15)
400         {
401             setTextColor(ColoArray[rand()%14]);
402             Gotoxy(0, i-15);
403             printf("");
404         }
405         Sleep(40);
406     }
407     Gotoxy(52,24);
408     setTextColor(WHITE);
409     printf("RedSnake v1.0 by_Lee");
410 }
411 
412 void GameRun()                    //游戏运行函数
413 {
414     while(!over)
415     {
416         Snake_Move();            //控制蛇的运动
417         Hit_Wall();                //判断是否撞墙
418         GameOver();
419         Sleep(70);
420     }
421 }
422 
423 /*void Pcount()
424 {
425 int i, j;
426 for(i = 49,j = 0; j < 39; i--, j++)
427 {
428 Gotoxy(j*2, 0);
429 printf("■");
430 if(j < 24)
431 {
432 Gotoxy(78, j);
433 printf("■");
434 }
435 Gotoxy(i*2, 24);
436 printf("■");
437 if(i > 15)
438 {
439 Gotoxy(0, i-15);
440 printf("■");
441 }
442 Sleep(50);
443 }
444 }
445 */
446 
447 void SurFace()//18,15
448 {
449     Gotoxy(5,0);
450     printf("RedSnake!");
451     Gotoxy(2,2);
452     printf("┌─————┐");
453     Gotoxy(2,3);
454     printf("├ 开始游戏 ┤ ");
455     Gotoxy(2,4);
456     printf("└—————┘");
457     Gotoxy(2,5);
458     printf("┌─————┐");
459     Gotoxy(2,6);
460     printf("├   帮助   ┤ ");
461     Gotoxy(2,7);
462     printf("└—————┘");
463     Gotoxy(2,8);
464     printf("┌─————┐");
465     Gotoxy(2,9);
466     printf("├   关于   ┤ ");
467     Gotoxy(2,10);
468     printf("└—————┘");
469     Gotoxy(2,11);
470     printf("┌─————┐");
471     Gotoxy(2,12);
472     printf("├ 退出游戏 ┤ ");
473     Gotoxy(2,13);
474     printf("└—————┘");
475     //system("pause");
476     POINT p;
477     /*    while(1)
478     {
479     if(GetCursorPos(&p))
480     
481       }
482     */
483 }
484 
485 /*void Snake_Auto_Move(char temp)
486 {
487 int i;
488 Gotoxy(Snake[0].x, Snake[0].y);
489 printf("□");
490 Gotoxy(Snake[1].x, Snake[1].y);
491 printf("■");
492 Gotoxy(Snake[length].x, Snake[length].y);
493 printf(" ");
494 do
495 {
496 Whether_Eat();                            //判断蛇是否吃到食物
497 Eat_Itself();                            //判断蛇是否咬到自己
498 for(i = length; i > 0; i--)                //移动蛇的坐标
499 Snake[i] = Snake[i-1];
500 Create_Food();
501 switch(temp)
502 {
503 case 72: Snake[0].y-=1; break;
504 case 80: Snake[0].y+=1; break;
505 case 75: Snake[0].x-=2; break;
506 case 77: Snake[0].x+=2; break;
507 }
508 }while((!kbhit() )&& (!over));
509 }
510 */
511 
512 void GameOver()
513 {
514     if(length == 99)
515     {
516         Sweep_Screem();
517         Gotoxy(28, 12);
518         printf("You Win.");
519         Sleep(2000);
520     }
521     if(over)
522     {
523         system("cls");
524         setTextColor(WHITE);
525         Gotoxy(38, 8);
526         printf("┏┯┯┯┯┯┯┯┯┯┯┯┓");
527         Gotoxy(38, 9);
528         printf("┠      Game Over.      ┨");
529         Gotoxy(38, 10);
530         printf("┠  Your score is %4d  ┨", score);
531         Gotoxy(38, 11);
532         printf("┠   Please try again   ┨");
533         Gotoxy(38, 12);
534         printf("┗┷┷┷┷┷┷┷┷┷┷┷┛");
535     }
536 }
537 
538 void Pause()                //用于暂停的函数
539 {   
540     setTextColor(WHITE);
541     Gotoxy(35,12);
542     printf("  Pause.  ");
543     while(1)
544     {
545         
546         int c = getch();
547         if(c == 32)
548         {
549         Gotoxy(35,12);
550         printf("           ");
551         break;
552         }
553     }
554 }
555 
556 void MyCount1()
557 {
558     setTextColor(WHITE);
559     Gotoxy(80,1);
560     printf("┏┅┅┅┅┅┅┅┅┅┅┓");
561     Gotoxy(80,2);
562     printf("┠                    ┨");
563     Sleep(25);
564     Gotoxy(80,3);
565     printf("┠    ↑     Up       ┨");    
566     Sleep(25);
567     Gotoxy(80,4);
568     printf("┠    ↓     Down     ┨");
569     Sleep(25);
570     Gotoxy(80,5);
571     printf("┠    ←     Left     ┨");
572     Sleep(25);
573     Gotoxy(80,6);
574     printf("┠    →     Right    ┨");
575     Sleep(25);
576     Gotoxy(80,7);
577     printf("┠    ESC    Exit     ┨");
578     Sleep(25);
579     Gotoxy(80,8);
580     printf("┠    SPACE  Pause    ┨");
581     Sleep(25);
582     Gotoxy(80,9);
583     printf("┠    R      Restart  ┨");
584     Sleep(25);
585     Gotoxy(80,10);
586     printf("┠                    ┨");
587     Gotoxy(80,11);
588     printf("┗┅┅┅┅┅┅┅┅┅┅┛");
589 
590 
591 }
592 
593 void MyCount2()
594 {
595 
596 }
597     

效果如下

 

posted @ 2013-06-19 13:12  Geekers  阅读(399)  评论(0编辑  收藏  举报