游戏截图:
以下是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<<"
打开文件失败!
";
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<<" "<<_mark;
202 }else
203 std::cout<<" --- ---";
204
205 cd.Y += 2;
206 SetConsoleCursorPosition( handle, cd );
207 inopen.close();
208 inopen.clear();//重置流状态
209 }
210 std::cout<<" 返 回 菜 单";
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<<"游戏等级 当前分数";
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<<"小牛 :初级 "<<_mark;
277 break;
278 case middle:
279 cd.Y +=2;
280 SetConsoleCursorPosition( handle, cd );
281 std::cout<<"中牛 :中级 "<<_mark;
282 break;
283 case high:
284 cd.Y +=2;
285 SetConsoleCursorPosition( handle, cd );
286 std::cout<<"大牛 :高级 "<<_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<<" 等 级 分 数";
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<<" 上榜分数:"<<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<<" ";
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<<" 制作人: _ 翼";
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 }