柔城

SOSOFT articles

C++控制台贪吃蛇代码

游戏截图:

以下是3个代码文件:

Snake_Class.h文件:

 1 #ifndef SNAKE
 2 #define SNAKE
 3 
 4 #include<windows.h>
 5 #include<vector>
 6 #include<string>
 7 
 8 //标记界面和菜单项的ID
 9 enum ID_ { ID_1=1, ID_2, ID_3, ID_4, ID_5, ID_6, ID_7 };
10 
11 //标记初级,中级,高级三种游戏等级
12 enum Rank_ { first=150, middle=100, high=50 };
13 
14 
15 //贪吃蛇结构   http://www.cnblogs.com/sosoft/
16 struct Snake_data{
17     bool state ;                    //标记蛇状态
18     UINT Snake_size;                //标记蛇长度
19     std::vector<COORD> Snake_coord; //蛇的当前坐标
20     COORD food_coord;               //食物坐标
21     UINT rank;                     //标记等级
22     UINT mark;                      //分数
23     UINT key;                       //记录按键方向
24     ID_ ID_interface;               //标记当前停留界面ID
25     short ID_option ;               //标记被选中菜单的ID
26     bool Flag;                      //标记刷新
27 };
28 
29 //贪吃蛇类
30 class Snake_class{
31 public:
32     Snake_class(){}
33     Snake_class(Snake_data *data): pSnake(data){}
34     void ShowMenu();            //显示菜单
35     void StartGame() ;          //开始游戏
36     void ShowPause();           //显示暂停界面
37     void SaveRecord();          //保存记录
38     void ShowRank();            //显示等级
39     void ShowRecord();          //显示存档记录列表
40     bool Read( size_t );        //读取记录
41     void ShowArmory();          //显示英雄榜
42     void Die();                 //死亡界面
43     size_t Create_file();       //存储文件
44 private:
45     void JudgeDie();            //判断死亡
46     bool Jesus();               //上榜判断
47     void ShowSnake( COORD& );   //显示蛇
48     void ShowPointer( COORD,std::string ); //显示指针
49     void Show_not();            //显示无数据
50     Snake_data *pSnake;
51 };
52 
53 
54 
55 #endif;

Snake_class.cpp:

  1 #include"Snake_Class.h"
  2 #include<iostream>
  3 #include<fstream>
  4 #include<ctime>
  5 #include<cstdlib>
  6 
  7 //获取缓冲区句柄
  8 static const HANDLE handle = GetStdHandle( STD_OUTPUT_HANDLE );
  9 static CONSOLE_SCREEN_BUFFER_INFO info ;
 10 //保存蛇的记录数据文件
 11 static const char *Snake_Record[] = { "d://SnakeRecord//Snake1.txt",
 12                                       "d://SnakeRecord//Snake2.txt",
 13                                       "d://SnakeRecord//Snake3.txt",
 14                                       "d://SnakeRecord//Snake4.txt",
 15                                       "d://SnakeRecord//Snake5.txt" };
 16 
 17 static const char *S_Armory[] = { "d://SnakeRecord//Armory1.txt",
 18                                   "d://SnakeRecord//Armory2.txt",
 19                                   "d://SnakeRecord//Armory3.txt" };
 20 //显示主菜单(完成已测试)
 21 void Snake_class::ShowMenu(){
 22     //获取缓冲区相关信息
 23     GetConsoleScreenBufferInfo( handle, &info );
 24     char *str[] = {"开 始 游 戏",
 25                    "难 度 等 级",
 26                    "读 取 存 档",
 27                    "英 雄 榜",
 28                    "退 出 游 戏"};
 29     //输出菜单选项
 30     short y = 3;
 31     COORD cd = { info.srWindow.Right/2 - 5, y };
 32     for( size_t n=0;n<sizeof(str)/sizeof(*str);++n ){
 33         SetConsoleCursorPosition( handle, cd );
 34         std::cout<<*(str+n);
 35         cd.Y += 2;
 36     }
 37 //判断指针指向哪个菜单选项
 38     cd.X -= 2;
 39     cd.Y  = y;
 40     switch( pSnake->ID_option ){
 41         case ID_1:
 42             break;
 43         case ID_2:
 44             cd.Y = y+2; break;
 45         case ID_3:
 46             cd.Y = y+4; break;
 47         case ID_4:
 48             cd.Y = y+6; break;
 49         case ID_5:
 50             cd.Y = y+8; break;
 51     }
 52     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
 53 }
 54 
 55 //开始游戏(完成待测试)
 56 void Snake_class::StartGame(){
 57     COORD cd;
 58     //判断是否已有食物
 59     if( !pSnake->food_coord.X ){
 60         srand((unsigned int)time(NULL));
 61         while(1){
 62             //限制食物出现的坐标不与围墙相同
 63               ++( cd.X = rand()%78 ); 
 64               ++( cd.Y = rand()%18 );
 65             //判断食物坐标是否与蛇身吻合
 66             std::vector<COORD>::iterator ite;
 67             for( ite=pSnake->Snake_coord.begin(); ite!=pSnake->Snake_coord.end(); ++ite ){
 68                     if( ite->X == cd.X && ite->Y == cd.Y )
 69                         break;
 70             }
 71             if( ite == pSnake->Snake_coord.end() ){
 72                 pSnake->food_coord.X = cd.X ;
 73                 pSnake->food_coord.Y = cd.Y ;
 74                 break;
 75             }
 76         }
 77     }
 78     SetConsoleCursorPosition( handle, pSnake->food_coord );
 79     std::cout<<"*";
 80     //判定按键方向
 81     cd.X  = pSnake->Snake_coord.begin()->X;
 82     cd.Y = pSnake->Snake_coord.begin()->Y ;
 83     switch( pSnake->key ){
 84         case VK_UP:
 85             --cd.Y; break;
 86         case VK_DOWN:
 87             ++cd.Y; break;
 88         case VK_LEFT:
 89             --cd.X; break;
 90         case VK_RIGHT:
 91             ++cd.X; break;
 92     }
 93     ShowSnake( cd );
 94     JudgeDie();
 95 }
 96 
 97 //显示暂停界面(完成已测试)
 98 void Snake_class::ShowPause(){
 99     COORD cd = { info.srWindow.Right/2-10, info.srWindow.Bottom/5 };
100     SetConsoleCursorPosition( handle, cd );
101     std::cout<<"游 戏 暂 停 中 ......";
102     char *str[] = { "继 续 游 戏",
103                     "保 存 游 戏",
104                     "退 出 游 戏" };
105 //输出菜单选项
106     short X = info.srWindow.Right/3;
107     cd.X = X/2-5 ;
108     cd.Y = info.srWindow.Bottom/3*2-4;
109     for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
110         SetConsoleCursorPosition( handle, cd );
111         std::cout<<*(str+i);
112         cd.X += X;
113     }
114 
115 //判断指针应指向的菜单选项
116     switch( pSnake->ID_option ){
117         case ID_1:
118             cd.X = X/2-7; break;
119         case ID_2:
120             cd.X = X/2+X-7; break;
121         case ID_3:
122             cd.X = X/2+2*X-7; break;
123     }
124     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
125 }
126 
127 //保存记录(完成未测试)
128 void Snake_class::SaveRecord(){
129     std::ofstream outopen;
130     outopen.open( *( Snake_Record + Create_file() ) );
131     if( !outopen ){
132         std::cerr<<"\n打开文件失败!\n";
133         exit(0);
134     }
135     //保存记录到文件中,前面加"0"是为了后面检测是否文件为空使用
136     outopen<<"0 "<<pSnake->Snake_size<<" ";
137     for(std::vector<COORD>::iterator ite=pSnake->Snake_coord.begin();
138         ite!=pSnake->Snake_coord.end();++ite )
139             outopen<<ite->X<<" "<<ite->Y<<" ";
140     outopen<<pSnake->rank<<" "<<pSnake->mark<<" "<<pSnake->key;
141     outopen.close();
142 //输出保存成功
143     COORD cd = { info.srWindow.Right/2-4, info.srWindow.Bottom/3*2-1 };
144     SetConsoleCursorPosition( handle, cd );
145     std::cout<<"保存成功!\a";
146 }
147 
148 //显示等级(已测试)
149 void Snake_class::ShowRank(){
150     COORD cd = { info.srWindow.Right/2-6, info.srWindow.Bottom/3+2 };
151     char *str[] = { "初       级",
152                     "中       级",
153                     "高       级" };
154     for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
155         SetConsoleCursorPosition( handle, cd );
156         std::cout<<*(str+i);
157         cd.Y += 2;
158     }
159     //判断指针所停留的选项
160     cd.X -= 2;
161     cd.Y  = info.srWindow.Bottom/3+2;
162     switch( pSnake->ID_option ){
163         case ID_1:
164             break;
165         case ID_2:
166             cd.Y += 2; break;
167         case ID_3:
168             cd.Y += 4; break;
169     }
170     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
171 }
172 
173 //显示存档记录(已测试)
174 void Snake_class::ShowRecord(){
175     COORD cd = { info.srWindow.Right/2-12, 8 };
176     //输出记录
177     std::ifstream inopen;
178     SetConsoleCursorPosition( handle, cd );
179     for( size_t i=0;i<sizeof(Snake_Record)/sizeof(*Snake_Record);++i ){
180         inopen.open( *(Snake_Record+i) );
181         if( !inopen || (inopen.get() == EOF && i==0) ){
182             Show_not();
183             pSnake->ID_option = ID_7;//第7个选项标记,在按回车时检测下
184             return;
185         }
186         if( inopen.get() != EOF ){
187             UINT _rank, _mark;
188             inopen>>_mark;
189             ++(_mark *= 2);
190             while( _mark-- )
191                 inopen>>_rank;
192             inopen>>_mark;
193             switch( _rank ){
194                 case first:
195                     std::cout<<"初级"; break;
196                 case middle:
197                     std::cout<<"中级"; break;
198                 case high:
199                     std::cout<<"高级"; break;
200             }
201             std::cout<<"\t\t\t  "<<_mark;            
202         }else
203             std::cout<<" ---\t\t\t  ---"; 
204 
205         cd.Y += 2;
206         SetConsoleCursorPosition( handle, cd );
207         inopen.close();
208         inopen.clear();//重置流状态
209     }
210     std::cout<<"\t   返 回 菜 单";
211     cd.X = info.srWindow.Right/2-4; 
212     cd.Y = 4;
213     SetConsoleCursorPosition( handle, cd );
214     std::cout<<"存 档 记 录";
215     cd.X -=10;
216     cd.Y +=2;
217     SetConsoleCursorPosition( handle, cd );
218     std::cout<<"游戏等级\t\t当前分数";
219     //输出指针
220     cd.X = info.srWindow.Right/2-14;
221     cd.Y = 8;
222     switch( pSnake->ID_option ){
223         case ID_1:
224             break;
225         case ID_2:
226             cd.Y +=2; break;
227         case ID_3:
228             cd.Y +=4; break;
229         case ID_4:
230             cd.Y +=6; break;
231         case ID_5:
232             cd.Y +=8; break;
233         case ID_6:
234             cd.Y +=10;break;
235     }
236     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
237 }
238 
239 //读取记录
240 bool Snake_class::Read( size_t i ){
241     std::ifstream inopen( *(Snake_Record+i) );
242     if( inopen.get() == EOF ){
243         std::cout<<"\a";
244         inopen.close();
245         return false;
246     }
247     inopen>>pSnake->Snake_size;
248     COORD cd;
249     pSnake->Snake_coord.clear();
250     for( int n=1;n<=pSnake->Snake_size;++n ){
251         inopen>>cd.X>>cd.Y ;
252         pSnake->Snake_coord.push_back( cd );
253     }
254     inopen>>pSnake->rank>>pSnake->mark>>pSnake->key;
255     inopen.close();
256     inopen.clear();
257     return true;
258 }
259 
260 //显示英雄榜(未测试)
261 void Snake_class::ShowArmory(){
262     short nt=0;
263     COORD cd = { info.srWindow.Right/3, info.srWindow.Bottom/3 };
264     std::ifstream inopen;
265     for( size_t i=0;i<sizeof(S_Armory)/sizeof(*S_Armory);++i ){
266         UINT _rank=0, _mark=0;
267         inopen.open( *(S_Armory+i) );
268         if( !inopen ){
269             ++nt;
270             continue;
271         }
272         inopen>>_rank>>_mark;
273         switch( _rank ){
274             case first:
275                 SetConsoleCursorPosition( handle, cd );
276                 std::cout<<"小牛 :初级\t\t  "<<_mark;
277                 break;
278             case middle:
279                 cd.Y +=2;
280                 SetConsoleCursorPosition( handle, cd );
281                 std::cout<<"中牛 :中级\t\t  "<<_mark;
282                 break;
283             case high:
284                 cd.Y +=2;
285                 SetConsoleCursorPosition( handle, cd );
286                 std::cout<<"大牛 :高级\t\t  "<<_mark;
287                 break;
288         }
289         inopen.close();
290         inopen.clear();
291     }
292     if( nt == 3 ){
293         Show_not();
294         return;
295     }
296     cd.X = info.srWindow.Right/2-3;
297     cd.Y = 4;
298     SetConsoleCursorPosition( handle, cd );
299     std::cout<<"英 雄 榜";
300     cd.X -=10;
301     cd.Y +=2;
302     SetConsoleCursorPosition( handle,cd );
303     std::cout<<"\t等 级\t\t分 数"; 
304     cd.Y = info.srWindow.Bottom-7;
305     SetConsoleCursorPosition( handle, cd );
306     std::cout<<"按回车返回主菜单........";
307 }
308 
309 //死亡界面(未测试)
310 void Snake_class::Die(){
311     COORD cd = { info.srWindow.Right/2-10, info.srWindow.Bottom/5 };
312     SetConsoleCursorPosition( handle, cd );
313     std::cout<<"    您 已 x_x 了 !";
314     char *str[] = { "返 回 菜 单",
315                     "退 出 游 戏" };
316 //输出菜单选项
317     short X = info.srWindow.Right/2;
318     cd.X = X/2-5 ;
319     cd.Y = info.srWindow.Bottom/3*2-4;
320     for( size_t i=0;i<sizeof(str)/sizeof(*str);++i ){
321         SetConsoleCursorPosition( handle, cd );
322         std::cout<<*(str+i);
323         cd.X += X;
324     }
325 
326 //判断指针应指向的菜单选项
327     switch( pSnake->ID_option ){
328         case ID_1:
329             cd.X = X/2-7; break;
330         case ID_2:
331             cd.X = X/2+X-7; break;
332     }
333     ShowPointer( cd,pSnake->Flag?std::string("  "):std::string("><") );
334     if( Jesus() ){
335         cd.X = X/2;
336         cd.Y = info.srWindow.Bottom/3;
337         SetConsoleCursorPosition( handle, cd );
338         std::cout<<"哟...这分? ╮(╯▽╰)╭ 也能上榜。。。!";
339         cd.Y +=2;
340         SetConsoleCursorPosition( handle, cd );
341         std::cout<<"上榜等级:";
342         switch( pSnake->rank ){
343             case first:
344                 std::cout<<"初级"; break;
345             case middle:
346                 std::cout<<"中级"; break;
347             case high:
348                 std::cout<<"高级"; break;
349         }
350         std::cout<<"\t上榜分数:"<<pSnake->mark;
351     }
352 }
353 
354 //存储记录文件(完成未测试)
355 size_t Snake_class::Create_file(){
356     std::ifstream inopen;
357     size_t fn=0, fc=0, iend = sizeof(Snake_Record)/sizeof(*Snake_Record);
358     //判断文件是否存在或文件已被存满
359     for( size_t i=0;i<iend;++i ){
360         inopen.open( *(Snake_Record+i) );
361         if( !inopen ) ++fn;
362         else if( inopen.get() == EOF ){  
363             inopen.close(); 
364             return i; 
365         }
366         else { ++fc; inopen.close(); }
367     }
368     if( fn == iend || fc == iend ){
369             std::ofstream outopen;
370                    //创建文本
371             for( size_t i=0;i<iend;++i ){
372                 outopen.open( *(Snake_Record+i) );
373                 outopen.close(); 
374             }
375     } 
376     //返回打开成功的文件索引
377     return 0 ;
378 }
379 
380 //判断死亡(未测试)
381 void Snake_class::JudgeDie(){
382     std::vector<COORD>::iterator hbeg = pSnake->Snake_coord.begin(),
383         beg = hbeg+1;
384     while( beg != pSnake->Snake_coord.end() ){
385         if( beg->X == hbeg->X && beg->Y == hbeg->Y ){
386             pSnake->state = FALSE;
387             return;
388         }
389         ++beg;
390     }
391     COORD cd;
392     if(hbeg->X <= 0 || hbeg->Y <= 0 ||
393         hbeg->X >=info.srWindow.Right || hbeg->Y >= info.srWindow.Bottom-5 ){
394             if( pSnake->Snake_size < 40 ){
395                 pSnake->state = FALSE;
396                 return;
397             }
398             //如果达到了40级可以穿墙
399             switch( pSnake->key ){
400                 case VK_UP:
401                     cd.X = pSnake->Snake_coord.begin()->X ;
402                     cd.Y = info.srWindow.Bottom-6;
403                     break;
404                 case VK_DOWN:
405                     cd.X = pSnake->Snake_coord.begin()->X ;
406                     cd.Y = 1;
407                     break;
408                 case VK_LEFT:
409                     cd.X = info.srWindow.Right-1;
410                     cd.Y = pSnake->Snake_coord.begin()->Y ;
411                     break;
412                 case VK_RIGHT:
413                     cd.X = 1;
414                     cd.Y = pSnake->Snake_coord.begin()->Y ;
415                     break;
416             }
417             ShowSnake( cd );
418     }
419 }
420 
421 //上榜判断(未测试)
422 bool Snake_class::Jesus(){
423     std::ifstream inopen;
424     size_t i;
425     //判断相应等级打开相应文件
426     switch( pSnake->rank ){
427         case first:
428             i=0; break;
429         case middle:
430             i=1; break;
431         case high:
432             i=2; break;
433     }
434     inopen.open( *(S_Armory+i) );
435     if( inopen ){
436         UINT _mark;
437         inopen>>_mark>>_mark;
438         if( _mark >= pSnake->mark ){
439             inopen.close();
440             return FALSE;
441         }
442     }
443     std::ofstream outopen( *(S_Armory+i) );//创建文件并输入
444     if( !outopen ){
445         std::cerr<<"打开英雄榜文件出错"<<std::endl;
446         exit(0);
447     }
448     outopen<<pSnake->rank<<" "<<pSnake->mark;
449     outopen.close();
450     return TRUE;
451 }
452 //显示蛇(未测试)
453 void Snake_class::ShowSnake( COORD& cd){
454     if( cd.X == pSnake->food_coord.X && cd.Y == pSnake->food_coord.Y ){
455             //在最后添加一个坐标
456         pSnake->Snake_coord.push_back( *(pSnake->Snake_coord.rbegin()) );
457         pSnake->food_coord.X = pSnake->food_coord.Y = 0;//标志食物已被吃掉
458         ++pSnake->mark;
459         ++pSnake->Snake_size;
460     }
461     COORD cod;
462     cod.X = (pSnake->Snake_coord.rbegin())->X ;
463     cod.Y = (pSnake->Snake_coord.rbegin())->Y ;
464     std::vector<COORD>::reverse_iterator rbeg = pSnake->Snake_coord.rbegin();
465     while( rbeg != pSnake->Snake_coord.rend()-1 ){
466         rbeg->X = (rbeg+1)->X ;
467         rbeg->Y = (rbeg+1)->Y ;
468         ++rbeg;
469     }
470     //显示蛇
471     pSnake->Snake_coord.begin()->X = cd.X ;
472     pSnake->Snake_coord.begin()->Y = cd.Y ;
473     for( std::vector<COORD>::iterator beg = pSnake->Snake_coord.begin();
474         beg != pSnake->Snake_coord.end();++beg ){
475             SetConsoleCursorPosition( handle, *beg );
476             std::cout<<"*";
477     }
478     SetConsoleCursorPosition( handle,cod );
479     std::cout<<" ";
480 }
481 
482 //显示指针(完成)
483 inline void Snake_class::ShowPointer( COORD cd,std::string str ){
484     SetConsoleCursorPosition( handle, cd );
485     std::cout<<str[0];
486     pSnake->ID_interface != ID_6?cd.X += 14:cd.X = info.srWindow.Right/3*2+3;
487     SetConsoleCursorPosition( handle, cd );
488     std::cout<<str[1];
489 }
490 
491 //显示无数据(完成)
492 inline void Snake_class::Show_not(){
493     COORD cd = { info.srWindow.Right/2-4 ,info.srWindow.Bottom/2 };
494     SetConsoleCursorPosition( handle, cd );
495     std::cout<<"无 数 据 !";
496     cd.X -= 6;
497     cd.Y += 2;
498     SetConsoleCursorPosition( handle, cd );
499     std::cout<<"请按回车返回主菜单......";
500 }

main.cpp :

  1 #include<iostream>
  2 #include<direct.h>
  3 #include"Snake_Class.h"
  4 
  5 #define _max(ID) --snake.ID_option < ID_1?ID : snake.ID_option
  6 #define _min(ID) ++snake.ID_option > ID?ID_1 : snake.ID_option
  7 
  8 //钩子过程
  9 LRESULT CALLBACK _HookProc(int,WPARAM,LPARAM);
 10 
 11 void Wall();       //画墙函数
 12 void Frame();      //画框函数
 13 void initialize_();//初始化蛇结构数据
 14 
 15 Snake_data snake;
 16 Snake_class csnake(&snake);
 17 static HANDLE handle;  //控制台句柄
 18 //控制台信息结构
 19 static CONSOLE_SCREEN_BUFFER_INFO info ;
 20 
 21 int main(){
 22     using namespace std;
 23         //获取输出缓冲区句柄
 24     handle = GetStdHandle(STD_OUTPUT_HANDLE); 
 25     //获取相关信息(主要是缓冲区大小)
 26     GetConsoleScreenBufferInfo( handle, &info );
 27     initialize_();
 28     _mkdir( "d://SnakeRecord" ); //创建目录
 29 
 30     CONSOLE_CURSOR_INFO cursor;           //光标结构 
 31     cursor.dwSize = 10;
 32     cursor.bVisible = 0;                  //0为隐藏光标
 33     SetConsoleCursorInfo(handle, &cursor);//设置隐藏光标函数 
 34 
 35     //csnake.ShowMenu();
 36     HHOOK hook;
 37     MSG msg;
 38     //相应的钩子有相应的过程函数MSDN中可看,安装键盘钩子 
 39     hook = SetWindowsHookEx(WH_KEYBOARD_LL,_HookProc,GetModuleHandle(NULL),0);
 40     while(1){
 41         //判断蛇是否还活着
 42         Wall();
 43         if( !snake.state && snake.ID_interface == ID_2 ){
 44                //csnake.Die();
 45                snake.ID_interface = ID_4;
 46                Frame();
 47         }
 48         if( snake.ID_interface == ID_2 ){
 49              csnake.StartGame();
 50              Sleep( snake.rank );
 51         }
 52         if( PeekMessage(&msg,NULL,0,0,PM_REMOVE) ){//循环接收消息
 53                TranslateMessage(&msg);
 54                DispatchMessage(&msg);
 55         }
 56     }
 57 
 58     UnhookWindowsHookEx( hook );    //卸载钩子 
 59     return 0;
 60 }
 61 
 62 //定义钩子过程(未完成)
 63 LRESULT CALLBACK _HookProc(int message, WPARAM wParam, LPARAM lParam){
 64     //判断是否弹起按键消息
 65     if( wParam == WM_KEYUP){
 66         bool state = true;
 67             switch(((LPKBDLLHOOKSTRUCT) lParam)->vkCode){//lParam:指向一个结构 
 68                 //按下上键
 69                 case VK_UP:              
 70                     switch( snake.ID_interface ){
 71                         case ID_1:
 72                             snake.Flag = true;
 73                             csnake.ShowMenu();
 74                             snake.Flag = false;
 75                             snake.ID_option = _max( ID_5 );
 76                             csnake.ShowMenu();
 77                             break;
 78                         case ID_2:
 79                             if( snake.key != VK_DOWN && snake.key != VK_UP ){
 80                                 snake.key = VK_UP;
 81                             }
 82                             break;
 83                         case ID_5:
 84                             snake.Flag = true;
 85                             csnake.ShowRank();
 86                             snake.ID_option = _max( ID_3 );
 87                             snake.Flag = false;
 88                             csnake.ShowRank();
 89                             break;
 90                         case ID_6:
 91                             snake.Flag = true;
 92                             csnake.ShowRecord();
 93                             snake.ID_option = _max( ID_6 );
 94                             snake.Flag = false;
 95                             csnake.ShowRecord();
 96                             break;
 97                     }
 98                     break;
 99                     //按下下键
100                 case VK_DOWN:
101                     switch( snake.ID_interface ){
102                         case ID_1:
103                             snake.Flag = true;
104                             csnake.ShowMenu();
105                             snake.Flag = false;
106                             snake.ID_option = _min( ID_5 );
107                             csnake.ShowMenu();
108                             break;
109                         case ID_2:
110                             if( snake.key != VK_UP && snake.key != VK_DOWN ){
111                                 snake.key = VK_DOWN;
112                             }
113                             break;
114                         case ID_5:
115                             snake.Flag = true;
116                             csnake.ShowRank();
117                             snake.ID_option = _min( ID_3 );
118                             snake.Flag = false;
119                             csnake.ShowRank();
120                             break;
121                         case ID_6:
122                             snake.Flag = true;
123                             csnake.ShowRecord();
124                             snake.ID_option = _min( ID_6 );
125                             snake.Flag = false;
126                             csnake.ShowRecord();
127                             break;
128                     }
129                     break;
130                     //按下左键
131                 case VK_LEFT:
132                     switch( snake.ID_interface ){
133                         case ID_2:
134                             if( snake.key != VK_RIGHT && snake.key != VK_LEFT ){
135                                 snake.key = VK_LEFT;
136                             }
137                             break;
138                         case ID_3:
139                             snake.Flag = true;
140                             csnake.ShowPause();
141                             snake.ID_option = _max( ID_3 );
142                             snake.Flag = false;
143                             csnake.ShowPause();
144                             break;
145                         case ID_4:
146                             snake.Flag = true;
147                             csnake.Die();
148                             snake.ID_option = _max( ID_2 );
149                             snake.Flag = false;
150                             csnake.Die();
151                             break;
152                     }
153                     break;
154                     //按下右键
155                  case VK_RIGHT:
156                      switch( snake.ID_interface ){
157                         case ID_2:
158                             if( snake.key != VK_LEFT && snake.key != VK_RIGHT ){
159                                 snake.key = VK_RIGHT;
160                             }
161                             break;
162                         case ID_3:
163                             snake.Flag = true;
164                             csnake.ShowPause();
165                             snake.ID_option = _min( ID_3 );
166                             snake.Flag = false;
167                             csnake.ShowPause();
168                             break;
169                         case ID_4:
170                             snake.Flag = true;
171                             csnake.Die();
172                             snake.ID_option = _min( ID_2 );
173                             snake.Flag = false;
174                             csnake.Die();
175                             break;
176                      }
177                      break;
178                      //按下空格和回车键
179                  case VK_SPACE:
180                  case VK_RETURN:
181                      system( "cls" );
182                      switch( snake.ID_interface ){
183                         case ID_1://主菜单界面
184                             switch( snake.ID_option ){
185                                  case ID_1:
186                                      snake.ID_interface = ID_2;//开始游戏界面ID
187                                      csnake.StartGame();
188                                      break;
189                                  case ID_2:
190                                      snake.ID_interface = ID_5;//等级界面
191                                      snake.ID_option = ID_1;
192                                      Frame();
193                                      //csnake.ShowRank();
194                                      break;
195                                  case ID_3:
196                                      snake.ID_interface = ID_6;//读取记录界面
197                                      snake.ID_option = ID_1;
198                                      csnake.ShowRecord();
199                                      break;
200                                  case ID_4:
201                                      snake.ID_interface = ID_7;//英雄榜界面
202                                      csnake.ShowArmory();
203                                      break;
204                                  case ID_5:
205                                      state = false;
206                                      break;
207                             }
208                             break;
209 
210                         case ID_2://游戏界面
211                             snake.ID_interface = ID_3;
212                             snake.ID_option = ID_1;
213                             Frame();
214                             //csnake.ShowPause();
215                             break;
216 
217                         case ID_3://暂停界面
218                             switch( snake.ID_option ){
219                                  case ID_1:
220                                      snake.ID_interface = ID_2;
221                                      csnake.StartGame();
222                                      break;
223                                  case ID_2:
224                                      csnake.SaveRecord();
225                                      break;
226                                  case ID_3:
227                                      state = false;
228                                      break;
229                             }
230                             break;
231 
232                         case ID_4://死亡界面
233                             switch( snake.ID_option ){
234                                  case ID_1:
235                                      snake.ID_interface = ID_1;
236                                      snake.ID_option = ID_1;
237                                      initialize_();
238                                      csnake.ShowMenu();
239                                      break;
240                                  case ID_2:
241                                      state = false;
242                                      break;
243                             }
244                             break;
245 
246                         case ID_5://等级界面
247                             switch( snake.ID_option ){
248                                  case ID_1:
249                                      snake.rank = first;
250                                      break;
251                                  case ID_2:
252                                      snake.rank = middle;
253                                      break;
254                                  case ID_3:
255                                      snake.rank = high;
256                                      break;
257                             }
258                             snake.ID_interface = ID_1;
259                             snake.ID_option = ID_1;
260                             csnake.ShowMenu();
261                             break;
262 
263                         case ID_6://读取界面
264                             size_t id;
265                             switch( snake.ID_option ){
266                                  case ID_1:
267                                      id = 0; break;
268                                  case ID_2:
269                                      id = 1; break;
270                                  case ID_3:
271                                      id = 2; break;
272                                  case ID_4:
273                                      id = 3; break;
274                                  case ID_5:
275                                      id = 4; break;
276                             }
277                             //进行读取文件
278                             if( snake.ID_option != ID_6&&snake.ID_option != ID_7 ){
279                                      initialize_();
280                                      if( csnake.Read( id ) ){
281                                          snake.ID_interface = ID_2;
282                                          csnake.StartGame();
283                                      }
284                                      else snake.ID_interface = ID_6;
285                             }
286                             else {
287                                      snake.ID_interface = ID_1;
288                                      snake.ID_option = ID_1;
289                                      csnake.ShowMenu();
290                             }
291                             break;
292 
293                         case ID_7://英雄榜界面
294                             snake.ID_interface = ID_1;
295                             snake.ID_option = ID_1;
296                             csnake.ShowMenu();
297                             break;
298                      }
299                      if( !state ){
300                          COORD cd = { info.srWindow.Right/4, info.srWindow.Bottom/5*4 };
301                          SetConsoleCursorPosition( handle,cd );
302                          exit(0);
303                      }
304                      snake.ID_option = ID_1;
305                     break;
306             }
307     }
308           //消息传给下个钩子
309           return CallNextHookEx ( NULL, message, wParam, lParam );
310 }
311 
312 //画墙函数和调用相应界面(已测试完成)
313 void Wall(){
314     short i;
315     COORD coord = { 0,0 };  //坐标结构
316 //绘墙
317     SetConsoleCursorPosition( handle, coord );
318     for( i=0;i<=info.srWindow.Right;++i )
319             std::cout<<"#";
320 
321     coord.X = info.srWindow.Right;
322     coord.Y = 1;
323     for( i=1;i<info.srWindow.Bottom;++i ){
324         SetConsoleCursorPosition( handle, coord );
325         std::cout<<"#";
326         ++coord.Y ;
327     }
328 
329     coord.X = 0;
330     coord.Y = info.srWindow.Bottom;
331     for( i=1;i<=info.srWindow.Right;++i ){
332         SetConsoleCursorPosition( handle, coord );
333         std::cout<<"#";
334         ++coord.X ;
335     }
336 
337     coord.X = 0;
338     coord.Y = 1;
339     for( i=1;i<info.srWindow.Bottom;++i ){
340         SetConsoleCursorPosition( handle, coord );
341         std::cout<<"#";
342         ++coord.Y ;
343     }
344 //判断所在界面显示相关界面的菜单选项及其它
345     int j = info.srWindow.Right/4;
346     switch( snake.ID_interface ){
347         case ID_1:
348             csnake.ShowMenu(); 
349             coord.X = j;
350             coord.Y = info.srWindow.Bottom-6;
351             SetConsoleCursorPosition( handle, coord );
352             std::cout<<"o(-\"-)o  贪  #^_^#  吃  →_→  蛇  \\(^o^)/";
353             break;//显示菜单选项
354 
355         case ID_2:
356         case ID_3:
357         case ID_4:
358             //绘输出信息框
359             coord.X = 1;
360             coord.Y = info.srWindow.Bottom - 5;
361             SetConsoleCursorPosition( handle, coord );
362             for( i=1;i<info.srWindow.Right; std::cout<<"#", ++i );
363             for( coord.X=j;coord.X<=info.srWindow.Right-j;coord.X+=j ){
364                 coord.Y = info.srWindow.Bottom - 5;
365                 for( i=coord.Y;i<info.srWindow.Bottom;++i ){
366                         SetConsoleCursorPosition( handle, coord );
367                         std::cout<<"#";
368                         ++coord.Y ;
369                 }
370             }
371             //输出每个框的信息
372             coord.X = 2;
373             coord.Y-= 4;
374             SetConsoleCursorPosition( handle, coord );
375             std::cout<<"游戏难度:";
376             coord.Y +=2;
377             SetConsoleCursorPosition( handle, coord );
378             std::cout<<"\t   ";
379             switch( snake.rank ){
380                   case first:
381                       std::cout<<"初 级"; break;
382                   case middle:
383                       std::cout<<"中 级"; break;
384                   case high:
385                       std::cout<<"高 级"; break;
386             }
387       //当前分数
388             coord.X += j;
389             coord.Y -= 2;
390             SetConsoleCursorPosition( handle, coord );
391             std::cout<<"  当 前 分 数";
392             coord.X +=j/2-3;
393             coord.Y +=2;
394             SetConsoleCursorPosition( handle, coord );
395             std::cout<<snake.mark ;
396       //操作说明
397             coord.X = j*2+1;
398             coord.Y = info.srWindow.Bottom -4;
399             SetConsoleCursorPosition( handle, coord );
400             std::cout<<" 操作说明: ";
401             coord.Y +=2;
402             SetConsoleCursorPosition( handle, coord );
403             std::cout<<"  ↑ ↓ ←  →";
404             ++coord.Y; 
405             SetConsoleCursorPosition( handle, coord );
406             std::cout<<" 空格: 暂停游戏";
407       //制作人
408             coord.X += j;
409             SetConsoleCursorPosition( handle, coord );
410             std::cout<<"\t制作人: _ 翼";
411             break;
412 
413         case ID_5:
414             csnake.ShowRank(); break;//显示游戏等级
415 
416         case ID_6:
417             csnake.ShowRecord(); break;//显示存档记录
418 
419         case ID_7:
420             csnake.ShowArmory(); break;//显示英雄榜
421     }
422 
423 }
424 
425 //画框函数(完成)
426 void Frame(){
427     COORD coord = { 0, info.srWindow.Bottom/3 };
428     SetConsoleCursorPosition( handle, coord );
429     for( short i=0;i<=info.srWindow.Right; std::cout<<"-", ++i );
430         
431     coord.Y = info.srWindow.Bottom/3*2;
432     SetConsoleCursorPosition( handle, coord );
433     for( short i=0;i<=info.srWindow.Right; std::cout<<"-", ++i );
434         
435     switch( snake.ID_interface ){
436         case ID_3:
437             csnake.ShowPause(); break;//显示暂停菜单
438         case ID_4:
439             csnake.Die(); break;//显示死亡界面菜单
440         case ID_5:
441             csnake.ShowRank(); break;//显示等级选项
442     }
443 }
444 
445 //初始化蛇数据(完成)
446 void initialize_(){
447     snake.state = true; //蛇状态
448     snake.Snake_size = 5; //蛇初始化长度
449     //初始化蛇位置
450     COORD cd;
451     cd.Y = 3;
452     snake.Snake_coord.clear();
453     for( size_t i=10;i>5;--i ){
454         cd.X = i;
455         snake.Snake_coord.push_back( cd );
456     }
457     snake.food_coord.X = 0;
458     snake.food_coord.Y = 0;
459     snake.rank = first;   //默认等级
460     snake.mark = 0; //分数
461     snake.key = VK_RIGHT; 
462     snake.ID_interface = ID_1;//界面标记
463     snake.ID_option = ID_1;   //选项标记
464     snake.Flag = false;
465 }

 

posted on 2014-01-06 23:56  柔城  阅读(62822)  评论(9编辑  收藏  举报

导航