本文为大大维原创,最早于博客园发表,转载请注明出处!!!
虽然本人一直是个免费的游戏测试员(/手动滑稽),但一直有着一个游戏架构师的梦想。正如马爸爸所说,梦想还是要有的,万一实现了呢?
这些天放寒假,有些空闲时间,就想着做一个简单的游戏机。能达到小时候十几块钱买的那种小霸王的功能就差不多了(有贪吃蛇,赛车小游戏,俄罗斯方块,雷霆战机,坦克大战,2048,拼图等),好吧,原谅我有些浮夸风(/手动斜眼)。。。
这不,下面是我这两天抠出来的一个最简单的贪吃蛇小游戏,姑且叫它“大大维的贪吃蛇v1”吧!!!
游戏功能比较简单,后续还需要完善。先将代码在这保存一份,日后看看,也是一件挺有意思的事情吧!!!
1 /**--------------------------------------------------**/ 2 /**名称:大大维的贪吃蛇v1 日期:2017/1/22**/ 3 /**描述:实现了贪吃蛇的基本功能,可以调节游戏难度,**/ 4 /**做了一个简单的用户界面 **/ 5 /**存在的问题:由于使用了全局数组存贮,因此对Space **/ 6 /**类的封装有些欠缺;由于使用了全局刷新,游戏运行中**/ 7 /**会出现闪屏现象,游戏难度越高,闪动越严重;不能够**/ 8 /**存储玩家的游戏记录,由于不是图形化界面,用户界面**/ 9 /**较丑;不能改变游戏的地图大小 **/ 10 /**笔者会在后续版本逐步完善这些问题!!! **/ 11 /**--------------------------------------------------**/ 12 13 #include<iostream> 14 #include<ctime> 15 #include<cstdlib> 16 #include<cstdio> 17 #include<conio.h> 18 #include<windows.h> 19 using namespace std; 20 const int SpaceLENG=20; 21 const int SpaceHIGH=40; 22 const int HARDSPEED=100; 23 const int NOMALSPEED=400; 24 const int EASYSPEED=700; 25 int speed=NOMALSPEED; 26 bool FLAG=true; 27 enum dir {UP,DOWN,LEFT,RIGHT};///使用小写会引发歧义 28 enum level {HARD,ESAY,NOMAL}; 29 ///---------------------------------------------------- 30 ///游戏空间定义 31 class Space 32 { 33 public: 34 void InitSpace(); 35 void DisplaySpace(); 36 public: 37 char SpaceData[SpaceLENG+2][SpaceHIGH+2]; 38 }; 39 void Space::InitSpace() 40 { 41 for(int i=-1; i<SpaceLENG+1; i++) 42 for(int j=-1; j<SpaceHIGH+1; j++) 43 { 44 if(i<0||i==SpaceLENG||j<0||j==SpaceHIGH) 45 SpaceData[i][j]='#'; 46 else 47 SpaceData[i][j]=' '; 48 } 49 } 50 void Space::DisplaySpace() 51 { 52 for(int i=-1; i<SpaceLENG+1; i++) 53 { 54 for(int j=-1; j<SpaceHIGH+1; j++) 55 { 56 cout<<SpaceData[i][j]; 57 } 58 cout<<endl; 59 } 60 cout<<endl<<endl; 61 } 62 Space *spa=new Space(); 63 ///---------------------------------------------------- 64 ///蛇节点定义 65 class SnakeNode 66 { 67 public: 68 void setXY(int m,int n) 69 { 70 x=m; 71 y=n; 72 } 73 void setNext(SnakeNode *temp) 74 { 75 next=temp; 76 } 77 void setPrior(SnakeNode *temp) 78 { 79 prior=temp; 80 } 81 int getX() 82 { 83 return x; 84 } 85 int getY() 86 { 87 return y; 88 } 89 SnakeNode* getNext() 90 { 91 return next; 92 } 93 SnakeNode* getPrior() 94 { 95 return prior; 96 } 97 private: 98 int x,y; 99 SnakeNode *prior,*next; 100 }; 101 ///---------------------------------------------------- 102 ///食物定义 103 class Food 104 { 105 public: 106 void foodCreate() 107 { 108 bool flag=true; 109 while(flag) 110 { 111 srand((unsigned int)time(NULL)); 112 fx=rand()%SpaceLENG; 113 fy=rand()%SpaceHIGH; 114 if(spa->SpaceData[fx][fy]!='*') 115 flag=false; 116 } 117 118 spa->SpaceData[fx][fy]='$'; 119 } 120 int getFx() 121 { 122 return fx; 123 } 124 int getFy() 125 { 126 return fy; 127 } 128 private: 129 int fx; 130 int fy; 131 }; 132 ///---------------------------------------------------- 133 ///蛇定义 134 class Snake:public SnakeNode,public Food 135 { 136 public: 137 Snake() 138 { 139 addHead(SpaceLENG/2,SpaceHIGH/2); 140 addHead(SpaceLENG/2,SpaceHIGH/2-1); 141 addHead(SpaceLENG/2,SpaceHIGH/2-2); 142 } 143 void addHead(int x,int y); 144 void delTail(); 145 void moving(); 146 void changePoint(char keydown); 147 SnakeNode* getHead() 148 { 149 return head; 150 } 151 SnakeNode* getTail() 152 { 153 return tail; 154 } 155 int getLEN() 156 { 157 return LEN; 158 } 159 private: 160 SnakeNode *head=NULL,*tail=NULL; 161 int LEN=0; 162 dir point=LEFT; 163 }; 164 void Snake::addHead(int x,int y) 165 { 166 SnakeNode *temp=new SnakeNode(); 167 temp->setXY(x,y); 168 temp->setNext(head); 169 temp->setPrior(NULL); 170 if(head) 171 { 172 head->setPrior(temp);///如果头不为空 173 spa->SpaceData[head->getX()][head->getY()]='*';///旧头 174 } 175 head=temp; 176 if(!tail)tail=head;///如果尾为空 177 spa->SpaceData[head->getX()][head->getY()]='@';///新头 178 LEN++; 179 } 180 void Snake::delTail() 181 { 182 SnakeNode *temp=tail; 183 spa->SpaceData[tail->getX()][tail->getY()]=' '; 184 if(tail==head) 185 tail=head=NULL; 186 else 187 { 188 tail=tail->getPrior(); 189 tail->setNext(NULL); 190 LEN--; 191 } 192 delete temp; 193 194 } 195 void Snake::moving() 196 { 197 int a,b; 198 SnakeNode* temp=getHead(); 199 a=temp->getX(); 200 b=temp->getY(); 201 switch(point) 202 { 203 case UP: 204 --a; 205 break; 206 case DOWN: 207 ++a; 208 break; 209 case LEFT: 210 --b; 211 break; 212 case RIGHT: 213 ++b; 214 break; 215 } 216 ///撞墙 217 if(a==SpaceLENG||b==SpaceHIGH||a==-1||b==-1) 218 { 219 FLAG=false; 220 } 221 ///撞自己身体 222 if(spa->SpaceData[a][b]=='*') 223 { 224 spa->SpaceData[a][b]=='@';///用头结点覆盖相撞节点 225 FLAG=false; 226 } 227 ///吃食物 228 if(a==getFx()&&b==getFy()) 229 { 230 addHead(a,b); 231 foodCreate(); 232 } 233 ///普通移动 234 else 235 { 236 addHead(a,b); 237 delTail(); 238 } 239 } 240 void Snake::changePoint(char keydown)///方向控制 241 { 242 switch(keydown) 243 { 244 case 'w': 245 { 246 if(point!=DOWN) 247 { 248 point=UP; 249 break; 250 } 251 else break; 252 } 253 case 'W': 254 { 255 if(point!=DOWN) 256 { 257 point=UP; 258 break; 259 } 260 else break; 261 } 262 case 's': 263 { 264 if(point!=UP) 265 { 266 point=DOWN; 267 break; 268 } 269 else break; 270 } 271 case 'S': 272 { 273 if(point!=UP) 274 { 275 point=DOWN; 276 break; 277 } 278 else break; 279 } 280 case 'a': 281 { 282 if(point!=RIGHT) 283 { 284 point=LEFT; 285 break; 286 } 287 else break; 288 } 289 case 'A': 290 { 291 if(point!=RIGHT) 292 { 293 point=LEFT; 294 break; 295 } 296 else break; 297 } 298 case 'd': 299 { 300 if(point!=LEFT) 301 { 302 point=RIGHT; 303 break; 304 } 305 else break; 306 } 307 case 'D': 308 { 309 if(point!=LEFT) 310 { 311 point=RIGHT; 312 break; 313 } 314 else break; 315 } 316 } 317 } 318 ///---------------------------------------------------- 319 ///用户交互界面创建 320 class UserView 321 { 322 public: 323 int menuCreate(); 324 int gameSetting(); 325 }; 326 int UserView::menuCreate() 327 { 328 bool flag=true; 329 while(flag) 330 { 331 cout<<" MENU"<<endl<<endl; 332 cout<<"Instruction:"<<endl<<endl; 333 cout<<"The Snake's original length is 3."<<endl<<endl; 334 cout<<"Using 'w,s,a,d' or 'W,S,A,D' to control the direction."<<endl<<endl<<endl<<endl; 335 cout<<"Please Input 'Y'or'y' to start game;"<<endl; 336 cout<<"Please Input 'N'or'n' to end game;"<<endl; 337 cout<<"Please Input 'S'or's' to game setting;"<<endl; 338 cout<<"Please Input else to stay!"<<endl; 339 char startKey=getch(); 340 if(startKey=='N'||startKey=='n') 341 { 342 system("cls"); 343 cout<<"Good Bye!!!"<<endl; 344 exit(0); 345 } 346 else if(startKey=='Y'||startKey=='y') 347 { 348 system("cls"); 349 cout<<" Game Start!!!"<<endl<<endl<<endl<<endl<<endl; 350 cout<<" GOOD LUCK!!!"<<endl; 351 getch(); 352 flag=false; 353 } 354 else if(startKey=='S'||startKey=='s') 355 { 356 gameSetting(); 357 } 358 system("cls"); 359 } 360 system("cls"); 361 return 0; 362 } 363 int UserView::gameSetting() 364 { 365 system("cls"); 366 cout<<" Setting:"<<endl<<endl<<endl<<endl; 367 cout<<"Please Chose Game Difficulty"<<endl; 368 cout<<"Input 'H'or'h'---Hard Level"<<endl; 369 cout<<"Input 'N'or'n'---Nomal Level"<<endl; 370 cout<<"Input 'E'or'e'---Easy Level"<<endl; 371 cout<<"Input else return the MENU"<<endl; 372 char hardKey=getch(); 373 if(hardKey=='H'||hardKey=='h') 374 { 375 cout<<"The Game's Difficulty now is Hard Level!!!"<<endl; 376 speed=HARDSPEED; 377 return 0; 378 } 379 else if(hardKey=='N'||hardKey=='n') 380 { 381 cout<<"The Game's Difficulty now is Nomal Level!!!"<<endl; 382 speed=NOMALSPEED; 383 return 0; 384 } 385 else if(hardKey=='E'||hardKey=='e') 386 { 387 cout<<"The Game's Difficulty now is Easy Level!!!"<<endl; 388 speed=EASYSPEED; 389 return 0; 390 } 391 system("cls"); 392 return 0; 393 } 394 ///---------------------------------------------------- 395 ///程序入口 396 int main() 397 { 398 while(true) 399 { 400 FLAG=true; 401 UserView view; 402 view.menuCreate(); 403 spa->InitSpace(); 404 Snake sna; 405 sna.foodCreate(); 406 spa->DisplaySpace(); 407 while(FLAG) 408 { 409 char downKey=getch(); 410 sna.changePoint(downKey); 411 ///kbhit(),检查是否有键盘输入,若有,则返回一个非0值,否则返回0,在头文件<conio.h>中定义 412 ///此处FLAG如果不加,会产生蛇吃墙现象 413 while(FLAG&&!kbhit()) 414 { 415 system("cls"); 416 sna.moving(); 417 spa->DisplaySpace(); 418 Sleep(speed); 419 } 420 } 421 cout<<"Game Over!!!"<<endl; 422 cout<<"The Snake's Length is :"<<sna.getLEN()<<endl<<endl<<endl<<endl; 423 cout<<"The Game Will Return Back MENU!"<<endl; 424 getch(); 425 system("cls"); 426 } 427 return 0; 428 }
最后上几张游戏的运行的截图: