還記得大一上學期就想做貪吃蛇了,甚至寫了三分之二,最后沒有辦法實現蛇的移動,就作廢了,不知道是不是這個學期變聰明了,哈哈,一口氣就寫出來了,當然了,主要還是問了同學。
貪吃蛇主要有幾個地方難實現,首先是如何形成動畫,這個是通過暫停程序sleep(time)來與刷新屏幕(system("cls")來實現的,后來發現刷新屏幕會一閃一閃,可以用goto()局部刷新或者是二級緩存。第二,是如何與玩家進行交互,說白了就是怎么獲取鍵盤事件,當然有很多種,例如scanf,getch()等,但是我們不可能按下一個鍵還要按一下回車鍵才把行吧,所以就用了getch().第三就是怎么讓蛇再沒有獲取到鍵盤命令的時候也會前進,這個是用判斷是否有鍵盤輸入kbnit()實現的(ε=ε=ε=(~ ̄▽ ̄)~,不要問我怎么知道的,神知道我怎么知道的)。差不多就這樣了。接下來放代碼,(其實就寫了蛇的部分,也不是我一個人寫的了,雖然大大大部分是我一個人寫的,因為調用其他人寫的難度比自己寫出來還大,用戶登錄啥的是直接套用了我上個學期實訓項目的https://www.cnblogs.com/miaos/p/miaoz-1-3.html,雖然不想這樣,不過。。。真香(:,關於寫蛇的部分我變個顏色)。
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<conio.h> #include<time.h> #include<iostream> #include<windows.h> using namespace std; typedef struct cmy { char cmyID[20]; int money; int kuchun; char name[40]; char conment[100][100]; char commentcount; }cm; typedef struct shopcar { int shuliang; cm cmyi; }car; typedef struct gmjl { int grad; struct tm lt; }jl; typedef struct users { char username[20]; char password[20]; int usermony; car shopcar[20]; int shopcount; char youxiang[30]; jl gmjlu[100]; int jilucount; }uer; typedef struct wjpass{ char wjname[20]; char beizhu[200]; char youxiang[30]; }wjp; typedef struct wenti { wjp wangji[100]; int wjcount; }wt; typedef struct passw2 { char a[20]; }passw2; uer kehu[1000];//初始化信息 wt weti = { "0",0 }; char gb[20] = "繆傳鵬最帥"; char adm[20] = "admin"; char admpassword[20] = "admin"; int count = 0;//用戶量 int countsp1 , countsp2 = 5; void yonhu(int usi);//用戶界面 通過用戶下標來標識 void zhuc();//注冊界面 void den();//登陸界面 void csjm();//初始界面 void exeit();//播放退出動畫然后退出 int nametoid(char name2[20]);//通過名字查找下標 void huangying();//歡迎界面 void exeit(); void youxijilu(); passw2 passw();//密碼不回顯 void zhanghuwenti(int usi);//反饋賬戶問題 void xiugaipassw(int usi);//修改密碼 void kehuwent();//初始界面的反饋賬戶問題 void gly_zhaohu();//管理員找回用戶密碼 void shezhi();//設置界面 void beijingcolor();//背景顏色 未調用 void ziticolor();//字體顏色 未調用 struct tm gwtiame();//返回當前時間 void chonzhi(int usi);//充值 struct tm gwtiame() { time_t t; struct tm*lt; t=time(NULL); lt = localtime(&t); struct tm a = *lt; return a; } /*******************************************************************變色失敗,用分割線******************************************************************/ using namespace std; typedef struct zuo { int x; int y; }zuo; zuo z[100];//蛇坐標,蛇頭為snak[0]; int shu=1; int pause=0; zuo food;//食物坐標 int ditu_x=40;// int ditu_y=20;//地圖 int speed=100;//速度; char f='S';//方向 w a s d; // void p2game(int usi);//同下 void pgame(int usi);//這個排行榜,沒寫完,就沒有調用了,不用管 void zhujiemian();//主界面 void stargame(int usi,int lk);//開始游戲 void printgame();//打印每一幀 * void refood();//重置食物坐標 void fangxiang();//獲取鍵盤,判斷方向* void snakyundon();//蛇的運動 * int eat();//判斷是否吃到食物; void snakdead(int usi);//判斷蛇是否死亡; void shezhi();//設置 void GoTo(int x,int y);//這個是局部刷新的,貌似也沒有用這個 void gotoxy(int x, int y)//沒錯,沒有用上面那個贗品,用的是這個 { COORD coord = {x, y}; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord); } void youxijilu(int usi) { while (1) { system("cls"); printf("========================================================游戲記錄=======================================================\n"); for (int i = 0; i < kehu[usi].jilucount; i++) { printf("編號:%d\t", i + 1); printf("時間:"); printf("%d年%d月%d日%d點%d分%d秒\t", kehu[usi].gmjlu[i].lt.tm_year + 1900, kehu[usi].gmjlu[i].lt.tm_mon, kehu[usi].gmjlu[i].lt.tm_mday, kehu[usi].gmjlu[i].lt.tm_hour, kehu[usi].gmjlu[i].lt.tm_min, kehu[usi].gmjlu[i].lt.tm_sec); printf("成績:%d",kehu[usi].gmjlu[i].grad); //printf("商品名稱:%s\n", kehu[usi].gmjlu[i].jlsp.cmyi.name); //printf("數量:%d\n", kehu[usi].gmjlu[i].jlsp.shuliang); //printf("交易額:%d\n", kehu[usi].gmjlu[i].jlsp.shuliang*kehu[usi].gmjlu[i].jlsp.cmyi.money); printf("——————————————————————————————\n"); } printf("1——————退出\n"); char fla4 = getch(); if (fla4 == '1') { yonhu(usi); } } } void fangxiang() { if(kbhit()) { char f1=getch(); if(f1=='D'||f1=='1'||f1=='S'||f1=='A'||f1=='W'||f1=='d'||f1=='s'||f1=='a'||f1=='w') {if(f=='W'&&f1=='S'||f=='A'&&f1=='D'||f=='S'&&f1=='W'||f=='D'&&f1=='A'||f=='w'&&f1=='s'||f=='a'&&f1=='d'||f=='s'&&f1=='w'||f=='d'&&f1=='a'); else if(f1=='1') { pause=1; } else f=f1; } } } void stargame(int usi,int lk) { char ff1='1'; if(lk==0) { for(;;){ cout<<"1---一般模式"<<endl; cout<<"2---無敵模式(需要消耗10個金幣)"<<endl; ff1=getch(); if(ff1=='1'||ff1=='2')break; system("cls"); } } system("cls"); if(ff1=='2')kehu[usi].usermony-=10; z[0].x=1; z[0].y=2; food.x=5; food.y=5; f='d'; printgame(); for(;;) { Sleep(speed); // getchar(); // system("cls"); fangxiang(); if(ff1=='1')snakdead(usi); if(eat()) { refood(); shu++; } p2game(usi); snakyundon(); pgame(usi); } } void snakyundon() { for(int i=shu-1;i>0;i--) { z[i]=z[i-1]; } if(f=='W'||f=='w')z[0].y-=1; if(f=='S'||f=='s')z[0].y+=1; if(f=='A'||f=='a')z[0].x-=1; if(f=='D'||f=='d')z[0].x+=1; } void printgame() { for(int i=1;i<=ditu_x*ditu_y;i++) { int flag=0; if((i%ditu_x-1)==food.x&&i/ditu_x==food.y) flag=1; for(int j=0;j<shu;j++) { if((i%ditu_x-1)==z[j].x&&i/ditu_x==z[j].y) flag=1; } if(i<=ditu_x||i%ditu_x==0||(i-1)%ditu_x==0||i>=ditu_x*(ditu_y-1))printf("*"); else printf(" "); if(i%ditu_x==0)printf("\n"); //if(flag)cout<<flag; } //cout<<z[0].x<<" "<<z[0].y; } void refood(){ if(eat()) { srand(time(0)); food.x=rand()%(ditu_x-2)+1; food.y=rand()%(ditu_y-2)+1; } } int eat(){ if(z[0].x==food.x&&z[0].y==food.y){ return 1; }else return 0; } void snakdead(int usi) { int flag=0; for(int i=1;i<shu;i++) { if(z[0].x==z[i].x&&z[0].y==z[i].y)flag=1; } if(z[0].y==0||z[0].y==ditu_y||z[0].x==0||z[0].x==ditu_x) flag=1; if(flag) { for(;;) {system("cls"); cout<<"\n\n\n\n\n---------------you are dead------------"<<endl; cout<<"\n\n---------do you want 復活(消耗2個金幣)-------------"<<endl; cout<<"\n\n-----1---是 2---否-------------"<<endl; char ffg=getch(); if(ffg=='1') { kehu[usi].usermony-=2; stargame(usi,1); } if(ffg=='2') break; } kehu[usi].gmjlu[kehu[usi].jilucount].grad=shu; kehu[usi].gmjlu[kehu[usi].jilucount++].lt=gwtiame(); shu=1; z[0].x=10; z[0].y=10; food.x=5; food.y=5; //Sleep(3000); yonhu(usi); } } void chonzhi(int usi) { while (1) { system("cls"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t您的余額是:%d\n\n\n\t\t\t\t\t\t1.充值余額\n\n\n\n\t\t\t\t\t\t2.返回上一層\n", kehu[usi].usermony); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char flag22 = getch(); if (flag22 == '1') { char flag23[20]; printf("請輸入第二組最帥以進行充值\n"); gets(flag23); if (!strcmp(flag23, gb)) { printf("充值中......"); kehu[usi].usermony += 100; _sleep(1000); printf("充值成功......"); _sleep(500); } else { printf("充值中........\n"); _sleep(2000); printf("充值失敗請重試......"); _sleep(500); } } else if (flag22 == '2') { yonhu(usi); } } } void shezhi() { while (1) { system("cls"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.設置顏色\n\n\n\t\t\t\t\t\t2.設置難度\n\n\n\t\t\t\t\t\t3.設置地圖\n\n\n\t\t\t\t\t\t4.返回上一層"); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char fla1 = getch(); if (fla1 == '1') { while (1) { system("cls"); printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("n\n\n\n\t\t\t\t\t\t1.黑底白字\n\n\t\t\t\t\t\t2.白底綠字\n\n\t\t\t\t\t\t3.黑底黃字\n\n\t\t\t\t\t\t4.黑底白字\n\n\t\t\t\t\t\t5.紫底白字\n\n\t\t\t\t\t\t6.返回\n"); printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char fla2 = getch(); switch (fla2) { case '1':system("color 07"); break; case '2':system("color 72"); break; case '3':system("color 06"); break; case '4':system("color 70"); break; case '5':system("color 57"); break; case '6':shezhi(); break; } } } if (fla1 == '4') { csjm(); } if(fla1=='2') { for(;;) { system("cls"); printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\t\t\t\t\t\t1.簡單\n\n\t\t\t\t\t\t2.一般\n\n\t\t\t\t\t\t3.困難\n\n\t\t\t\t\t\t4.地獄\n\n\t\t\t\t\t\t5.返回\n"); printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char ffff=getch(); if(ffff=='1')speed=250; if(ffff=='2')speed=100; if(ffff=='3')speed=60; if(ffff=='4')speed=10; if(ffff=='5')break; } } if(fla1=='3') { for(;;) { system("cls"); printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\t\t\t\t\t\t1.小\n\n\t\t\t\t\t\t2.中\n\n\t\t\t\t\t\t3.大\n\n\t\t\t\t\t\t4.返回\n"); printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char ffff=getch(); if(ffff=='1'){ditu_x=20;ditu_y=10;break;} if(ffff=='2'){ditu_x=40;ditu_y=20;break;} if(ffff=='3'){ditu_x=80;ditu_y=40;break;} if(ffff=='4')break; } } } } void gly_zhaohu() { system("cls"); printf("————————客戶問題————————\n"); if (weti.wjcount == 0)printf("當前沒有客戶問題\n"); for (int i = 0; i < weti.wjcount; i++) { printf("編號:%d\n名字:%s\n郵箱地址:%s\n問題:%s\n\n", i + 1, weti.wangji[i].wjname, weti.wangji[i].youxiang, weti.wangji[i].beizhu); } printf("——————————為客戶找回密碼——————————\n"); int tempbh; printf("請輸入客戶姓名所對應的編號\n"); scanf("%d", &tempbh); if (tempbh<1 || tempbh>weti.wjcount) { while (1) { printf("請輸入正確的編號\n"); printf("1————重新輸入\n2————退出\n"); char fla4 = getch(); if (fla4 == '1') { gly_zhaohu(); } if (fla4 == '2') { kehuwent(); } } } else { int kehui = nametoid(weti.wangji[tempbh-1].wjname); printf("客戶:%s\n密碼:%s\n請通過他的郵箱%s告知。\n", kehu[kehui].username, kehu[kehui].password, kehu[kehui].youxiang); printf("按任意鍵返回上一級\n"); getch(); } } void kehuwent() { while (1) { system("cls"); printf("\n\n——————————————————————————客戶問題——————————————————————————————\n"); if (weti.wjcount == 0)printf("\n\n\t\t\t\t\t\t當前沒有客戶問題\n\n\n"); for (int i = 0; i < weti.wjcount; i++) { printf("編號:%d\n名字:%s\n郵箱地址:%s\n問題:%s\n\n", i + 1, weti.wangji[i].wjname, weti.wangji[i].youxiang, weti.wangji[i].beizhu); } printf("——————————————————————客戶是上帝 請解決這些問題—————————————————————————\n\n"); printf("\n\n\t\t\t\t\t\t1.為客戶找回密碼\n\n\t\t\t\t\t\t2.刪除問題\n\n\t\t\t\t\t\t3.解決其他問題\n\n\t\t\t\t\t\t4.退出\n"); char flag31 = getch(); if (flag31 == '1') { gly_zhaohu(); } if (flag31 == '3') { printf("請手動解決\n"); _sleep(1000); kehuwent(); } if (flag31 == '2') { // gly_shanchuwt(); } if (flag31 == '4') { //guangliyuan(); den(); } } } int nametoid(char name2[20]) { int flag4 = 0, t1; for (int i = 0; i < count; i++) { if (!strcmp(name2, kehu[i].username)) { flag4 = 1; t1 = i; } } if (flag4 == 0) { return -1; } else return t1; } void zhanghuwenti(int usi) { while (1) { system("cls"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.修改密碼\n\n\n\t\t\t\t\t\t2.返回上一層\n"); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char flag30 = getch(); if (flag30 == '1') { xiugaipassw(usi); } else if (flag30 == '3') { //待增加 } else if (flag30 == '2') { yonhu(usi); } } } passw2 passw() { passw2 x; char ch, s[20]; int i = 0; while ((ch = getch()) != '\r') { if (ch != 8) { x.a[i] = ch; putchar('*'); i++; } else if (i > 0) { putchar('\b'); putchar(' '); putchar('\b'); i--; } } x.a[i] = '\0'; return x; } void zhaohuipassw() { system("cls"); char nametemp[20],bztemp[200]; printf("請輸入賬戶名\n"); scanf("%s", nametemp); if (nametoid(nametemp) == -1) { while (1) { printf("帳戶名不存在\n"); printf("1————重新輸入\n2————返回上一層\n"); char fla1 = getch(); if (fla1 == '1')zhaohuipassw(); if (fla1 == '2')den(); } } printf("請輸入備注\n"); scanf("%s", bztemp); char yxtemp[30]; while (1) { printf("請輸入您的郵箱地址\n"); scanf("%s", yxtemp); if (!strcmp(yxtemp, kehu[nametoid(nametemp)].youxiang)) { strcpy(weti.wangji[weti.wjcount].beizhu, bztemp); strcpy(weti.wangji[weti.wjcount].wjname, nametemp); strcpy(weti.wangji[weti.wjcount].youxiang, yxtemp); weti.wjcount++; printf("等待管理員處理,處理成功新密碼將發送至您的郵箱\n"); _sleep(1000); break; } else { while (1) { system("cls"); printf("郵箱地址不正確\n"); printf("1————重新輸入\n2————返回上一層\n"); char fla1 = getch(); if (fla1 == '1') { system("cls"); break; } if (fla1 == '2')den(); } } } } void xiugaipassw(int usi) { if (usi == -1) { char zhaoname[20]; system("cls"); printf("請輸入賬戶名\n"); scanf("%s", zhaoname); if (zhaoname == "-1") { printf("正在返回...."); _sleep(800); den(); } if (nametoid(zhaoname) == -1) { printf("此帳戶名不存在\n"); printf("請重新輸入,輸入-1返回上一層\n"); xiugaipassw(-1); } else { while (1) { system("cls"); char zhaopass[20]; printf("請輸入修改前密碼"); scanf("%s", zhaopass); if (!strcmp(zhaopass, kehu[nametoid(zhaoname)].password)) { while (1) { char newpass1[20], newpass2[20]; printf("請輸入新密碼\n"); scanf("%s", newpass1); printf("請再次輸入新密碼\n"); scanf("%s", newpass2); if (!strcmp(newpass1, newpass2)) { printf("修改密碼成功...\n"); _sleep(800); strcpy(kehu[nametoid(zhaoname)].password, newpass1); printf("正在返回上一層....\n"); _sleep(600); den(); } else { printf("兩次密碼不相同請重新輸入\n"); _sleep(800); } } } else { printf("密碼錯誤\n1——————重新輸入\n2——————退出\n"); _sleep(800); while (1) { char flag28 = getch(); if (flag28 == '1')break; if (flag28 == '2')den(); } } } } } else { while (1) { system("cls"); char zhaopass[20]; printf("請輸入修改前密碼\n"); strcpy(zhaopass,passw().a); if (!strcmp(zhaopass, kehu[usi].password)) { while (1) { char newpass1[20], newpass2[20]; printf("\n請輸入新密碼\n"); strcpy(newpass1, passw().a); printf("\n請再次輸入新密碼\n"); strcpy(newpass2, passw().a); if (!strcmp(newpass1, newpass2)) { printf("\n修改密碼成功...\n"); _sleep(800); strcpy(kehu[usi].password, newpass1); printf("正在返回上一層....\n"); _sleep(600); yonhu(usi); } else { printf("\n兩次密碼不相同請重新輸入\n"); _sleep(800); break; } } } else { printf("密碼錯誤\n1——————重新輸入\n2——————退出\n"); _sleep(800); while (1) { char flag28 = getch(); if (flag28 == '1')break; if (flag28 == '2')yonhu(usi); } } } } } void huangying() { printf("\n——————————————————————————————————————————歡迎光臨—————————————————————————————————————————————————"); _sleep(1000); } void exeit() { system("cls"); printf("----------------------------------------歡迎下次再來---------------------------------------------------------------"); _sleep(1000); FILE*fp; fp = fopen("chaoshiahuju", "wb"); fwrite(&count, sizeof(int), 1, fp); fwrite(&countsp2, sizeof(int), 1, fp); for (int i = 0; i < count; i++) fwrite(&kehu[i], sizeof(users), 1, fp); fwrite(&weti, sizeof(wt), 1, fp); fclose(fp); _sleep(1000); exit(0); } void guangliyuan() { while (1) { system("cls"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.查看客戶問題\n\n\n\t\t\t\t\t\t2.返回登錄\n"); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char flag7 = getch(); if (flag7 == '2') { den(); } else if (flag7 == '1') { kehuwent(); } } } void yonhu(int usi) { while (1) { system("cls"); char flag10; printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.開始游戲\n\n\t\t\t\t\t\t2.查看游戲記錄\n\n\t\t\t\t\t\t3.查看余額|充值余額\n\n\t\t\t\t\t\t4.賬戶問題\n\n\t\t\t\t\t\t5.游戲設置\n\n\t\t\t\t\t\t6.退出登錄\n"); printf("\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); flag10=getch(); if (flag10 == '1') { stargame(usi,0); } else if (flag10 == '2') { youxijilu(usi); } else if (flag10 == '3') { chonzhi(usi); } else if (flag10 == '6') { den(); } else if (flag10 == '4') { zhanghuwenti(usi); } else if(flag10=='5') { shezhi(); } } } void zhuc() { char usname[20]; char password[20], passwordag[20]; system("cls"); printf("請輸入用戶名\n"); scanf("%s", usname); int flag3 = 0; for (int i = 0; i < count; i++) { if (!strcmp(usname, kehu[i].username))flag3 = 1; } if (flag3) { printf("用戶名已經存在請重新輸入"); _sleep(1000); zhuc(); } else { int flag6 = 0; while (1) { printf("請輸入密碼\n"); strcpy(password, passw().a); system("cls"); printf("請再次輸入密碼\n"); strcpy(passwordag, passw().a); if (strcmp(password, passwordag)) { printf("兩次密碼不相同,請重新輸入密碼\n"); _sleep(1000); } else { system("cls"); printf("請輸入您的郵箱地址\n"); scanf("%s", kehu[count].youxiang); system("cls"); printf("注冊成功"); _sleep(1000); strcpy(kehu[count].username, usname); strcpy(kehu[count].password, password); kehu[count].jilucount = 0; kehu[count].usermony = 100; kehu[count++].shopcount = 0; flag6 = 1; break; } } if (flag6)den(); } } void den() { char flag1; while (1) { system("cls"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.客戶登錄\n\n\n\t\t\t\t\t\t2.管理員登錄\n\n\n\t\t\t\t\t\t3.返回上一層"); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); flag1 = getch(); if (flag1 == '1') { while (1) { char name1[20]; char password2[20]; system("cls"); printf("請輸入賬戶名\n"); scanf("%s", name1); if (!strcmp(name1, "-1"))break; int flag4 = 0, t1; for (int i = 0; i < count; i++) { if (!strcmp(name1, kehu[i].username)) { flag4 = 1; t1 = i; } } if (flag4 == 0) { while (1) { printf("用戶名不存在\n"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.重新輸入\n\n\n\t\t\t\t\t\t2.返回上一層\n"); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char fla1 = getch(); if (fla1 == '1')break; if (fla1 == '2')den(); _sleep(1000); } } else { printf("請輸入密碼\n"); strcpy(password2, passw().a); if (!strcmp(password2, "-1"))den(); if (!strcmp(password2, kehu[t1].password)) { system("cls"); printf("登入成功"); _sleep(1000); yonhu(t1); } else { printf("密碼不正確"); _sleep(1000); } } } } if (flag1 == '2') { char name2[20]; char password3[20]; while (1) { system("cls"); printf("請輸入賬戶名\n"); scanf("%s", name2); if (!strcmp(name2, "-1"))break; if (strcmp(name2, adm)) { while (1) { printf("用戶名不存在\n"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.重新輸入\n\n\n\t\t\t\t\t\t2.返回上一層\n"); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char fla1 = getch(); if (fla1 == '1')break; if (fla1 == '2')den(); _sleep(1000); } } else { printf("請輸入密碼\n"); strcpy(password3, passw().a); if (strcmp(password3, admpassword)) { printf("密碼不正確\n"); } else { system("cls"); printf("登錄成功"); _sleep(1000); //后續程序 guangliyuan(); } } } exeit(); } if (flag1 == '3') { csjm(); } } } void csjm() { while (1) { system("cls"); char flag5 = 0; char flag2 = '0'; while (1) { system("cls"); printf("\n\n\n\n\n\n\n------------------------------------------------welcome come snake game-------------------------------------------------\n\n"); printf("\n\n\n\n\n\t\t1.登錄\t\t2.注冊\t\t3.賬戶問題\t\t4.設置\t\t5.退出\n"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); flag2 = getch(); if (flag2 == '1') { den(); break; } if (flag2 == '2') { zhuc(); break; } if (flag2 == '5') { system("cls"); printf("----------------------------------------歡迎下次再來---------------------------------------------------------------"); _sleep(1000); exeit(); } if (flag2 == '3') { while (1) { system("cls"); printf("\n\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); printf("\n\n\n\n\t\t\t\t\t\t1.修改密碼\n\n\n\t\t\t\t\t\t2.找回密碼\n\n\n\t\t\t\t\t\t3.返回上一級\n"); printf("\n\n\n\n\n------------------------------------------------------------------------------------------------------------------------\n"); char flag29 = getch(); if (flag29 == '1') { xiugaipassw(-1); } if (flag29 == '2') { zhaohuipassw(); } if (flag29 == '3')break; } } if (flag2 == '4') { shezhi(); } } } } void pgame(int usi) { for(int j=0;j<shu;j++) { if(z[shu-1].x>0&&z[shu-1].x<ditu_x&&z[shu-1].y<ditu_y-1&&z[shu-1].y>0) { gotoxy(z[j].x,z[j].y); cout<<'&'; } } gotoxy(food.x,food.y); cout<<'@'; //gotoxy(0,0); gotoxy(0,21); if(pause==1) { for(;;){ cout<<"1----繼續 "<<endl; cout<<"2----你選擇死亡"<<endl; char ff=getch(); if(ff=='1') { pause=0; break; } if(ff=='2') { pause=0; z[0].x=0; snakdead(usi); } } } gotoxy(0,21); cout<<"當前分數:"<<shu<<endl; cout<<"1----暫停 "<<endl; } void p2game(int usi) { if(z[shu-1].x>0&&z[shu-1].x<ditu_x&&z[shu-1].y-1<ditu_y-1&&z[shu-1].y>0) gotoxy(z[shu-1].x,z[shu-1].y); cout<<' '; gotoxy(food.x,food.y); cout<<' '; } int main() { system("mode con cols=120 lines=30"); FILE*fp; fp = fopen("chaoshiahuju", "rb+"); fread(&count, sizeof(int), 1, fp); fread(&countsp2, sizeof(int), 1, fp); for (int i = 0; i < count; i++) fread(&kehu[i], sizeof(users), 1, fp); fread(&weti, sizeof(wt), 1, fp); fclose(fp); system("color 70"); csjm(); return 0; }
關於命令行貪吃蛇就這樣了,接下來是qt寫的桌面版貪吃蛇,這次學到不少,也吃了不少虧(下面會講)。
如果你沒有接觸過qt,(qt大法好,mfc沒飯吃)我分享一下我看的大神寫的學習教程,http://www.qter.org/portal.php?mod=view&aid=26
你可能還需要環境配置的教程https://blog.csdn.net/liang19890820/article/details/53931813
其實只要會一點qt,做貪吃蛇是很簡單的,不過我經歷了一些苦難,唉。
首先和命令行一樣要思考的三個問題,第一,如何形成動畫,也就是如何把游戲畫面給輸出來,還記得我說的吃虧嗎,就是在這里,我首先想到的是用qlabel把圖片輸出,然后通過控制qlabel的坐標進行動畫,我一度甚至以為這個方法很絕妙,甚至直到我看到一條殺馬特一樣扭曲的蛇我還沒有放棄。。。直到我發現qtpainter,可以直接在相應坐標上輸出圖片。。。所以真正的方法是用qtpaiter來輸出圖片,通過控制圖片的坐標來形成動畫。第二就是怎么與玩家進行交互,由於沒有命令行,普通的scanf,gets是絕對行不通的,qt有自己的qt鍵盤事件獲取方式也就是keyevent,第三是怎么控制時間,幀率,讓蛇的運動函數循環運行,用的是qtime里面的timeupdate,來實現循環加sleep同樣的功能,主要是因為sleep在qt里面沒有用。解決了這些問題,到貼代碼部分了
首先是頭文件
snk.h在里面我定義了一些全局變量,具體看注釋。
#ifndef SNK_H #define SNK_H typedef struct zuo//坐標結構體 { //zuo() {} int x; int y; }zuo; extern char f,f2;//方向f,以及鍵盤按的鍵f1 extern zuo snkz[199];//蛇的頭與身體在其中z[0]是頭 extern zuo foodz;//食物的坐標 extern int shu,pause;//蛇的身體數與有關游戲暫停的全局變量 extern int ditu_x,ditu_y;//地圖大小 extern int xuanz;//蛇頭擺的方向,1為逆時針,0為順時針。后來沒有用到 extern int speed;//速度,也就是幀率,刷新率。 #endif // SNK_H
另外說一下extern,大概就是讓你重復定義變量而不會報錯,這樣做的原因https://blog.csdn.net/caoshangpa/article/details/51104022
dialog.h
#ifndef DIALOG_H #define DIALOG_H #include <QDialog> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); private: Ui::Dialog *ui; }; #endif // DIALOG_H
沒啥東西要講,你可以理解為我看不懂。
mainwindows.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include<QLabel> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots://聲明一些要用的函數 void on_label_2_linkActivated(const QString &link);//沒啥用 void timeUpDate(); void keyPressEvent(QKeyEvent *e); void paintEvent(QPaintEvent*w); void on_pushButton_clicked(); //void on_pushButton_windowTitleChanged(const QString &title); void on_pushButton_2_clicked(); private://聲明一些控件 Ui::MainWindow *ui; QList<QLabel*> p; }; #endif // MAINWINDOW_H
就是聲明了一些函數。
接着是cpp文件
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); setWindowTitle(QStringLiteral("by miaoz")); } Dialog::~Dialog() { delete ui; }
啥也沒有
main.cpp
#include "mainwindow.h" #include <QApplication> #include "dialog.h" #include <snk.h> //重新聲明一下頭文件里的變量,具體看前面關於頭文件定義全局變量的鏈接 int shu=2; zuo snkz[199]; zuo foodz; char f='w',f2='w'; int pause=0; int ditu_x=24,ditu_y=24; int xuanz=0; int speed=400; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; Dialog dl; w.setWindowIcon(QIcon(":/new/prefix1/D:/qt/qt/code/sorce/head (a).png"));//設置窗口圖標 dl.setWindowIcon(QIcon(":/new/prefix1/D:/qt/qt/code/sorce/head (a).png"));//同上 if(dl.exec()==Dialog::Accepted)//如果收到開始游戲按下的信號,就開始游戲。 { w.show(); return a.exec();//窗口一張運行,直到被關閉 } else return 0;// }
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include<QVBoxLayout> #include<QKeyEvent> #include<QVector> #include<QList> #include<QWidget> #include<time.h> #include<conio.h> #include<cstdlib> #include<QTime> #include<dialog.h> #include<cstdio> #include<QtCore> #include "snk.h" #include"QPainter" void chus()//初始化全局變量 { speed=400; shu=3; snkz[0].x=6; snkz[0].y=6; foodz.x=5; foodz.y=5; f='s'; } void refood()//重置食物 { for(;;) { int flag1=1; srand(time(0)); int x=rand()%(ditu_x-1)+1; srand(time(0)); int y=rand()%(ditu_y-1)+1; for(int i=0;i<shu;i++) { if(x==snkz[i].x&&y==snkz[i].y) flag1=0; } if(flag1) { foodz.x=x; foodz.y=y; break; } } } void snakeyundon()//蛇的運動 { //int speed=40; //zuo temp=z[shu-1]; if(f=='W') { snkz[0].y-=1; } if(f=='D') { snkz[0].x+=1; } if(f=='S') { snkz[0].y+=1; } if(f=='A') { snkz[0].x-=1; } for(int i=shu-1;i>0;i--) { snkz[i]=snkz[i-1]; } } int eat()//判斷是否吃到食物 { if(snkz[0].x==foodz.x&&snkz[0].y==foodz.y) { refood(); shu++; speed-=50; return 1; } return 0; } void fangxiang()//判斷方向 { if(kbhit()) { char f1=getch(); if(f1=='D'||f1=='1'||f1=='S'||f1=='A'||f1=='W'||f1=='d'||f1=='s'||f1=='a'||f1=='w') {if(f=='W'&&f1=='S'||f=='A'&&f1=='D'||f=='S'&&f1=='W'||f=='D'&&f1=='A'||f=='w'&&f1=='s'||f=='a'&&f1=='d'||f=='s'&&f1=='w'||f=='d'&&f1=='a'); else if(f1=='1') { pause=1; } else{ if(f=='W'&&f1=='D'||f=='D'&&f1=='S'||f=='S'&&f1=='A'||f=='A'&&f1=='W'||f=='w'&&f1=='d'||f=='d'&&f1=='s'||f=='s'&&f1=='a'||f=='a'&&f1=='w') xuanz=0; else xuanz=1; f=f1; } } } } void snakyundon()//這個也是蛇的運動,忘記用了那個,自己看 { int k=1; for(int i=shu-1;i>0;i--) { snkz[i]=snkz[i-1]; } if(f=='W'||f=='w')snkz[0].y-=k; if(f=='S'||f=='s')snkz[0].y+=k; if(f=='A'||f=='a')snkz[0].x-=k; if(f=='D'||f=='d')snkz[0].x+=k; } int snakdead()//判斷蛇是否死亡 { int flag=0; for(int i=1;i<shu;i++) { if(snkz[0].x==snkz[i].x&&snkz[0].y==snkz[i].y)flag=1; } if(snkz[0].y==0||snkz[0].y==ditu_y||snkz[0].x==0||snkz[0].x==ditu_x) flag=1; return flag; } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { chus(); ui->setupUi(this); QWidget *widgetMain = new QWidget();//布局管理器 QVBoxLayout *verLayout = new QVBoxLayout(widgetMain);// QTimer *timer = new QTimer(this);//新建一個定時器 connect(timer,SIGNAL(timeout()),this,SLOT(timeUpDate()));//連接信號與槽 timer->start(speed);設置間隔時間 //ui->label_2->setText(QString::number(shu)); } MainWindow::~MainWindow() { //if(pause==-1)close(); delete ui; } void MainWindow::timeUpDate() { if(snakdead()) { ui->pushButton->setText("重新游戲"); pause=-1; } if(!pause) { ui->label_3->setText("gaming..."); ui->lcdNumber->display(shu); ui->lcdNumber_2->display(450-speed); ui->lcdNumber_3->display(snkz[0].x); ui->lcdNumber_4->display(snkz[0].y); eat(); snakyundon(); update(); } } void MainWindow::paintEvent(QPaintEvent*w) { QPainter painter(this); setWindowTitle(QStringLiteral("snake")); QFont ft; ft.setPointSize(20); QPalette clo; clo.setColor(QPalette::WindowText,Qt::blue); ui->label_3->setFont(ft); ui->label_3->setPalette(clo); QPixmap ps(500,500); ps.load(":/new/prefix1/D:/qt/qt/code/sorce/shu.png"); if(pause==-1) { ui->pushButton->setText("重新游戲"); ui->label_3->setText("you are dead..."); painter.drawPixmap(0,0,500,500,ps); } else { painter.drawPixmap(0,0,500,500,QPixmap(":/new/prefix1/D:/qt/qt/code/sorce/beij.png")); painter.setRenderHints(QPainter::Antialiasing,false); QPixmap pixa(20, 20); pixa.load(":/new/prefix1/D:/qt/qt/code/sorce/head (a).png"); // QPixmap pixs(20, 20); pixs.load(":/new/prefix1/D:/qt/qt/code/sorce/head (s).png"); // QPixmap pixd(20, 20); pixd.load(":/new/prefix1/D:/qt/qt/code/sorce/head (d).png"); // QPixmap pixw(20, 20); pixw.load(":/new/prefix1/D:/qt/qt/code/sorce/head (w).png"); // QPixmap pix2(20,20); pix2.load(":/new/prefix1/D:/qt/qt/code/sorce/body.png"); QPixmap pix3(20,20); pix3.load(":/new/prefix1/D:/qt/qt/code/sorce/body (2).png"); painter.drawPixmap(foodz.x*20, foodz.y*20, pix2); for(int i=1;i<shu;i++) { painter.drawPixmap(snkz[i].x*20, snkz[i].y*20, pix3); } if(f=='w'||f=='W')painter.drawPixmap(snkz[0].x*20, snkz[0].y*20, pixw); if(f=='s'||f=='S')painter.drawPixmap(snkz[0].x*20, snkz[0].y*20, pixs); if(f=='a'||f=='A')painter.drawPixmap(snkz[0].x*20, snkz[0].y*20, pixa); if(f=='d'||f=='D')painter.drawPixmap(snkz[0].x*20, snkz[0].y*20, pixd); } } void MainWindow::keyPressEvent(QKeyEvent *e) { //int keyvalue=e->key(); if(e->key()==Qt::Key_W) { // k1++; if(f!='S') { f='W'; } } if(e->key()==Qt::Key_A) { //k1++; if(f!='D') { f='A'; } } if(e->key()==Qt::Key_S) { //k1++; if(f!='W') { f='S'; } } if(e->key()==Qt::Key_D) { //k1++; if(f!='A') { f='D'; } } } void MainWindow::on_label_2_linkActivated(const QString &link) { } void MainWindow::on_pushButton_clicked() { if(pause==1) { ui->pushButton->setText("暫停"); ui->label_3->setText("gaming..."); pause=0; } else if(pause==0) { ui->pushButton->setText("繼續"); ui->label_3->setText("stoping..."); pause=1; } else if(pause==-1) { ui->pushButton->setText("暫停"); chus(); ui->label_3->setText("gaming..."); pause=0; } } void MainWindow::on_pushButton_2_clicked() { // pause=-1; // parentWidget()->show(); delete this; // this->hide();//主界面關閉 }
大概就是這樣,有關qtime,qkeyevent,qpaiter等,自己去查資料,(主要是想睡覺了)
最后分享整個項目(包括我辛辛苦苦剪輯的圖片素材)
鏈接: https://pan.baidu.com/s/1rApHeAUTQ-CpS7y-zetNxg
密碼: 1wgt