編程老是對着一個黑窗口,能夠說是很是乏味了,因而喵喵就翻出來了之前用easyx圖形庫作圖形界面的貪吃蛇遊戲。node
不過你們只是當作提升編程的樂趣來學習吧,想進一步作的話能夠學習QT,還有其餘的框架。ios
這是一個easyx圖形庫的學習教程,建議你們學完再看本文:c++
https://www.easyx.cn/skills/List.aspx?id=7編程
首先看一下效果圖:框架
實現的功能:學習
基本的吃食物長大,撞牆死亡,特殊食物,遊戲暫停,重開遊戲,記分數的功能。字體
遊戲最高分的記錄。spa
遊戲關卡的選擇。3d
加了遊戲的音效,具體的音效,能夠在下面下載:code
連接:https://pan.baidu.com/s/1NFn19J7gcXmG45jAuYe4Ig 密碼:x5kz
一些說明:
這個程序用的基本是C,當時對C++類的理解實在太差,如今也懶的改了。
這個程序是萬惡的VC寫的,當時還沒發現codeblocks啥的。
關於程序的功能實現,並不太難,有詳細的註釋,能夠隨意複製粘貼。
下面看貪吃蛇的代碼:
#include "node.h" class Food { public: Food(); virtual ~Food(); int food;//0爲無食物,1爲有食物 node foodxy; int c;//累計出現食物個數 }; Food::Food() { c=0; } Food::~Food() { } class node { public: int x,y; node(); virtual ~node(); }; #include "node.h" class snake { public: snake(); virtual ~snake(); node jie[200];//蛇每一個節點座標 int n;//蛇當前節點數 char dry;//蛇當前前進方向 }; class wall { public: node dry[30];//障礙物的座標 int n;//障礙物的個數 wall(); virtual ~wall(); };
1 #include<graphics.h> 2 #include<conio.h> 3 #include<time.h> 4 #include "snake.h" 5 #include "Food.h" 6 #include<stdio.h> 7 #include<fstream.h> 8 #include "mmsystem.h"//導入聲音頭文件 9 #pragma comment(lib,"winmm.lib")//導入聲音頭文件庫 10 #include "wall.h" 11 int wallnum,speed; 12 13 void zero(); 14 void first();//操做頁面初始化 15 int second( Food &, snake&);//數據初始化 16 void foodstyle(Food&,wall);//食物狀態 17 void gameover(snake,int);//遊戲結束 18 void judge( Food&,snake&,int,wall);//判斷遊戲是否結束 19 void judge2(Food &,snake&);//判斷蛇是否吃到食物 20 void snakemove(Food&,snake&,wall); 21 void snakeshow(Food &,snake &,wall); 22 void change(Food &,snake &,int);//改變方向 23 void score(snake );//記錄分數 24 void wallstyle(wall&);//障礙物的狀態 25 26 27 int main() 28 { 29 initgraph(640,560); 30 int o; 31 Food F; 32 snake Snake; 33 wall Wall; 34 first(); 35 zero(); 36 o= second(F,Snake); 37 wallstyle(Wall); 38 PlaySound("kaichang.wav",NULL,SND_FILENAME|SND_ASYNC);//載入聲音特效 39 while(1) 40 { 41 while(!kbhit())//沒有鍵盤輸入時 42 { 43 44 if(!F.food ) 45 { 46 foodstyle(F,Wall); 47 } 48 judge(F,Snake,o,Wall); 49 judge2(F,Snake); 50 snakemove(F,Snake,Wall); 51 Sleep(speed);//控制速度 52 score(Snake); 53 } 54 change(F,Snake,o); 55 56 } 57 return 0; 58 } 59 60 void zero() 61 { 62 char p[1]; 63 outtextxy(490,30,_T("關卡:")); 64 for(int i=0;i<3;i++) 65 { 66 RECT r= {520+40*i,35,560+40*i,45};//使數字顯示在矩形區域中央 67 sprintf(p, "%d", i+1); 68 drawtext(p, &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE); 69 } 70 settextstyle(40, 15, _T("黑體")); 71 outtextxy(50,200,_T("請輸入 1 or 2 or 3 肯定關卡")); 72 char c=getch();//控制選擇關卡 73 switch (c) 74 { 75 case '1': 76 wallnum=10; 77 speed=300; 78 i=1; 79 break; 80 case '2': 81 wallnum=15; 82 speed=200; 83 i=2; 84 break; 85 case '3': 86 wallnum=15; 87 speed=100; 88 i=3; 89 break; 90 default: 91 settextcolor(BLACK);//擦除 92 outtextxy(50,200,_T("請輸入 1 or 2 or 3 肯定關卡")); 93 settextcolor(RED); 94 outtextxy(200,200,_T("請正確輸入")); 95 Sleep(1000);//確保顯示時間 96 main(); 97 } 98 setfillcolor(GREEN); 99 RECT v= {530+40*(i-1),20,550+40*(i-1),60}; 100 sprintf(p, "%d", i); 101 drawtext(p, &v, DT_CENTER | DT_VCENTER | DT_SINGLELINE); 102 settextcolor(BLACK); 103 outtextxy(50,200,_T("請輸入 1 or 2 or 3 肯定關卡")); 104 settextcolor(RED);//確保之後的字體顏色 105 } 106 void first() 107 { 108 srand((unsigned)time(NULL));//播種子 109 setlinestyle(PS_DASH);//實線 110 settextcolor(RED); 111 setlinecolor(BLUE); 112 line(480,0,480,480);//分界線 113 line(0,480,640,480); 114 outtextxy(490,90,_T("分數:"));//操做說明 115 outtextxy(490,150,_T("最高分:")); 116 outtextxy(490,210,_T("操做方式:")); 117 outtextxy(490,260,_T(" W/w:上移 S/s:下移")); 118 outtextxy(490,310,_T(" A/a:左移 D/d:右移")); 119 outtextxy(490,360,_T(" 空格:暫停/開始")); 120 outtextxy(490,410,_T(" Esc:退出")); 121 outtextxy(490,450,_T(" 做者:丁喵喵")); 122 setlinecolor(BLUE);//示例圖形 123 setfillcolor(GREEN); 124 fillcircle(310,495,10); 125 fillcircle(30,535,5); 126 setfillcolor(RED); 127 fillrectangle(20,505,40,525); 128 fillrectangle(300,510,320,530); 129 setfillcolor(BLACK); 130 fillcircle(310,520,10); 131 outtextxy(20,490,_T("舒適提示:")); 132 outtextxy(50,510,_T("一.障礙物,撞擊死亡")); 133 outtextxy(320,510,_T("四.被破壞障礙物,非無敵狀態撞擊仍會死亡")); 134 outtextxy(50,530,_T("二.特殊食物,吃掉衝撞障礙物不死亡")); 135 outtextxy(320,490,_T("三.蛇吃完特殊食物後的無敵狀態")); 136 outtextxy(320,530,_T("五.只有蛇頭時衝撞障礙物不死亡")); 137 } 138 139 int second(Food & F,snake & Snake) 140 { 141 F.food=0;//食物有無、蛇結束、位置、前進方向初始化 142 Snake.n=1; 143 Snake.jie[0].x=40; 144 Snake.jie[0].y=40; 145 setfillcolor(RED); 146 fillcircle( Snake.jie[0].x,Snake.jie[0].y,10); 147 Snake.dry='d'; 148 ifstream inFile("scoremax.txt",ios::in);//讀入文件 149 int o; 150 inFile>>o; 151 char p[1]; 152 sprintf(p, "%d", o); 153 settextstyle(10, 10, _T("黑體")); 154 outtextxy(550,150,p);//最高分 155 sprintf(p, "%d", (Snake.n-1)*10); 156 outtextxy(550,90,p);//分數 157 return o; 158 } 159 160 void foodstyle(Food & F,wall Wall) 161 { 162 if(!F.food) 163 { 164 F.foodxy.x=(rand()%22)*20+20;//食物出現地點 165 F.foodxy.y=(rand()%22)*20+20; 166 //確保食物不出如今障礙物及蛇初始位置 167 while((F.foodxy.x==40&&F.foodxy.y==40)||(F.foodxy.x==60&&F.foodxy.y==40)) 168 { 169 F.foodxy.x=(rand()%22)*20+20; 170 F.foodxy.y=(rand()%22)*20+20; 171 } 172 for(int i=0;i<Wall.n;i++) 173 { 174 if(F.foodxy.x==Wall.dry[i].x&&F.foodxy.y==Wall.dry[i].y) 175 { 176 foodstyle(F,Wall); 177 } 178 } 179 setlinestyle(PS_SOLID); 180 if((F.c+1)%5==0&&(F.c+1)!=0)//判斷是否爲特殊食物 181 { 182 setfillcolor(GREEN); 183 } 184 else 185 { 186 setfillcolor(YELLOW); 187 } 188 fillcircle(F.foodxy.x,F.foodxy.y,5); 189 F.food=1;//食物狀態爲有 190 F.c++;//累計出現食物個數 191 } 192 } 193 void judge(Food & F,snake & Snake,int o,wall Wall) 194 { 195 if(Snake.jie[0].x<=0||Snake.jie[0].x>=480||Snake.jie[0].y<=0||Snake.jie[0].y>=480) 196 {//判斷是否撞牆 197 PlaySound("zhuangqiang.wav",NULL,SND_FILENAME|SND_ASYNC); 198 Sleep(3000); 199 gameover(Snake,o); 200 } 201 for(int i=1;i<=Snake.n;i++) 202 {//判斷是否咬到本身 203 if(Snake.jie[0].x==Snake.jie[i].x&&Snake.jie[0].y==Snake.jie[i].y) 204 { 205 PlaySound("yao.wav",NULL,SND_FILENAME|SND_ASYNC); 206 Sleep(3000); 207 gameover(Snake,o); 208 } 209 } 210 for(i=0;i<Wall.n;i++) 211 {//判斷是否撞到障礙物 212 if(Snake.jie[0].x<Wall.dry[i].x+20&&Snake.jie[0].y<Wall.dry[i].y+20&& 213 Snake.jie[0].x>Wall.dry[i].x-20&&Snake.jie[0].y>Wall.dry[i].y-20) 214 { 215 if((F.c-1)%5!=0&&F.c!=1)//非無敵狀態 216 { 217 PlaySound("zhuangqiang.wav",NULL,SND_FILENAME|SND_ASYNC); 218 Sleep(3000); 219 gameover(Snake,o); 220 } 221 } 222 } 223 224 } 225 226 void judge2(Food & F,snake & Snake) 227 { 228 if(Snake.jie[0].x==F.foodxy.x&&Snake.jie[0].y==F.foodxy.y)//判斷是否吃到食物 229 { 230 PlaySound("shiwu.wav",NULL,SND_FILENAME|SND_ASYNC); 231 setfillcolor(BLACK);//擦除 232 fillcircle(F.foodxy.x,F.foodxy.y,5); 233 Snake.n++;//蛇結數增長 234 setfillcolor(BLUE); 235 fillcircle( F.foodxy.x,F.foodxy.y,10); 236 F.food=0;//食物被吃掉 237 } 238 } 239 void gameover(snake Snake,int o) 240 { 241 if(o<=(Snake.n-1)*10)//判斷是否須要更改最高分 242 { 243 PlaySound("zhangsheng.wav",NULL,SND_FILENAME|SND_ASYNC); 244 ofstream outFile("scoremax.txt",ios::out);//寫入文件 245 outFile<<(Snake.n-1)*10; 246 outFile.close(); 247 } 248 else 249 { 250 PlaySound("Game_over.wav",NULL,SND_FILENAME|SND_ASYNC); 251 } 252 settextcolor(RED); 253 settextstyle(180, 40, _T("黑體")); 254 outtextxy(100,100,_T("GAME OVER")); 255 settextstyle(40, 15, _T("黑體")); 256 outtextxy(200,300,_T("是否從新開始")); 257 outtextxy(150,350,_T("YES(Y/y)")); 258 outtextxy(350,350,_T("NO(N/n)")); 259 char c=getch();//判斷是否從新開始 260 if(c=='n'||c=='N') 261 { 262 closegraph();//關閉畫布 263 } 264 else if(c=='y'||c=='Y') 265 { 266 main(); 267 } 268 else//避免輸入移動指令破壞畫面 269 { 270 gameover(Snake,o); 271 } 272 273 } 274 275 void snakemove(Food & F,snake & Snake,wall Wall) 276 { 277 int i; 278 for (i=Snake.n ; i>0; i--)//蛇身每一節移到前一節位置 279 { 280 Snake.jie[i].x = Snake.jie[i-1].x; 281 Snake.jie[i].y = Snake.jie[i-1].y; 282 } 283 switch (Snake.dry)//判斷以前的移動方向 蛇頭並按該方向移到 284 { 285 case 'W': 286 case 'w': 287 Snake.jie[0].y-=20; 288 break; 289 case 's': 290 case 'S': 291 Snake.jie[0].y +=20; 292 break; 293 case 'A': 294 case 'a': 295 Snake.jie[0].x -=20; 296 break; 297 case 'D': 298 case 'd': 299 Snake.jie[0].x +=20; 300 break; 301 }; 302 snakeshow(F,Snake,Wall);//將結果顯示 303 } 304 305 void change(Food & F,snake & Snake,int o) 306 { 307 char key,p[1]; 308 IMAGE tmp; 309 int i; 310 key = getch(); 311 switch (key) 312 { 313 case 'w': 314 case 'W': 315 if (Snake.dry !='s'&&Snake.dry !='S')//確保不反向移動 316 { 317 Snake.dry ='w'; 318 } 319 break; 320 case 's': 321 case 'S': 322 if (Snake.dry !='w'&&Snake.dry !='W') 323 { 324 Snake.dry = 's'; 325 } 326 break; 327 case 'a': 328 case 'A': 329 if (Snake.dry !='D'&&Snake.dry !='d') 330 { 331 Snake.dry = 'a'; 332 } 333 break; 334 case 'd': 335 case 'D': 336 if (Snake.dry !='a'&&Snake.dry !='A') 337 { 338 Snake.dry = 'd'; 339 } 340 break; 341 case' '://暫停 342 343 getimage(&tmp,150,200,150,40);//將該區域圖像保存 344 settextstyle(40, 15, _T("黑體")); 345 outtextxy(150, 200, _T("任意鍵繼續")); 346 PlaySound("stop.wav",NULL,SND_FILENAME|SND_ASYNC); 347 getch(); 348 putimage(150,200,&tmp);//將保存圖像返回,確保不破壞背景 349 for(i=3;i>=1;i--)//倒計時 350 { 351 settextstyle(40, 15, _T("黑體")); 352 sprintf(p, "%d", i); 353 outtextxy(200, 200, p); 354 Sleep(1000); 355 putimage(150,200,&tmp); 356 } 357 PlaySound("start.wav",NULL,SND_FILENAME|SND_ASYNC); 358 break; 359 case 27: 360 gameover(Snake,o);//退出 361 break; 362 } 363 } 364 365 void snakeshow(Food & F,snake & Snake,wall Wall) 366 { 367 int i; 368 for (i=Snake.n-1; i>0; i--)//蛇身 369 { 370 setfillcolor(BLUE); 371 fillcircle( Snake.jie[i].x,Snake.jie[i].y,10); 372 } 373 if((F.c-1)%5==0&&F.c!=1)//特殊食物 374 { 375 setfillcolor(GREEN); 376 } 377 else 378 { 379 setfillcolor(RED); 380 } 381 fillcircle( Snake.jie[0].x,Snake.jie[0].y,10); 382 setlinecolor(BLACK); 383 setfillcolor(BLACK);//擦除以前最後一節蛇身 384 fillcircle( Snake.jie[Snake.n].x,Snake.jie[Snake.n].y,10); 385 if(Snake.n>1) 386 { 387 setfillcolor(BLUE); 388 } 389 else 390 { 391 setfillcolor(RED); 392 } 393 fillcircle( Snake.jie[Snake.n-1].x,Snake.jie[Snake.n-1].y,10); 394 } 395 396 397 void score(snake Snake) 398 { 399 char p[1]; 400 sprintf(p, "%d", (Snake.n-2)*10); 401 settextcolor(BLACK); 402 outtextxy(550,90,p); 403 sprintf(p, "%d", (Snake.n-1)*10); 404 settextcolor(RED); 405 settextstyle(10, 10, _T("黑體")); 406 outtextxy(550,90,p); 407 408 } 409 410 void wallstyle(wall & Wall) 411 { 412 Wall.n =wallnum; 413 for(int i=0;i<Wall.n;i++) 414 { 415 Wall.dry[i].x=(rand()%22)*20+20;//障礙物出現地點 416 Wall.dry[i].y=(rand()%22)*20+20; 417 while((Wall.dry[i].x==40&&Wall.dry[i].y==40)||(Wall.dry[i].x==60&&Wall.dry[i].y==40) 418 ||(Wall.dry[i].x==80&&Wall.dry[i].y==40)) 419 { 420 Wall.dry[i].x=(rand()%22)*20+20;//障礙物出現地點 421 Wall.dry[i].y=(rand()%22)*20+20; 422 } 423 setfillcolor(RED); 424 fillrectangle(Wall.dry[i].x-10,Wall.dry[i].y-10,Wall.dry[i].x+10,Wall.dry[i].y+10); 425 for(int j=0;j<i;j++)//確保障礙物不重疊 426 { 427 if(Wall.dry[i].x==Wall.dry[j].x&&Wall.dry[i].y==Wall.dry[j].y) 428 { 429 i--; 430 } 431 } 432 } 433 }