C語言實現貪吃蛇遊戲程式碼
阿新 • • 發佈:2020-09-23
本文例項為大家分享了C語言實現貪吃蛇遊戲的具體程式碼,供大家參考,具體內容如下
//------------------------------------------problm區------------------------------ //①思考typedef 定義的變數如何利用fwrite進行儲存 //②典型可利用sleep()語句類實現控制移動速度 //③BOOL PlaySoundW(LPCWSTR,HMODULE,DWORD)”: 無法將引數 1 從“const char[8]”轉換為“LPCWSTR -->導致原因-->即原因vc2010開發環境中可能找不到字串的音樂導致 //④思考怎麼消去不是這四個鍵的情況 #include<stdio.h> #include<stdlib.h> #include<Windows.h> #include<conio.h> #include<string.h> #include<time.h> #include <MMSystem.h>//匯入聲音標頭檔案-->即聯合形成 #pragma warning(disable:4996)//可以利用該程式碼消去警告類 #pragma comment(lib,"Winmm.lib")//連結庫 //------------------------------------------變數區--------------------------------- //---------------------------------------巨集定義變數定義---------------------------- #define H 24//定義高為24 #define W 78//定義寬為78 #define false 0 #define true 1 //-------------------------------------非巨集定義變數定義---------------------------- int n=0;//全域性變數定用於寫介面的狀況 int zpalyer=0;//記錄總玩家的個數 int fs;//用於記錄玩家的分數 int key=72;//用於控制玩家的移動方向的變數,且賦予初始化值為上 int changeFlag = 0;//判斷是否吃到了果實,用於確定是否需要擦除蛇尾 int i;//用於函式中控制迴圈的變數 char name[20]; char name1[20]; struct palyerinfo//定義玩家的名稱與分數的結構體 { char name[20]; int palyefs; }player[100]; struct //定義貪吃蛇的食物產生的座標類 { int x; int y; }food; struct //利用連結串列實現貪吃蛇的長度 { int x[100]; int y[100]; int len; int zfs; int speed; }snake1; //------------------------------------------宣告區--------------------------------- void xj(); void dq(); void save(); void ck(); void xuanz(); void jm(); void phb(); void fs1(); int begin(); void creatfood(); void keyDown(); bool sfjs(); void getoxy(int x,int y); void ex(); int yy(); //------------------------------------------函式區--------------------------------- //-----------------------------------------介面函式區------------------------------ void menu1()//進入遊戲後選擇讀取使用者還是新建使用者 { int n; system("color 3e");//即加一個語句即可控制顏色,即與cmd中類似進行控制顏色-->控制的是控制檯的顏色 printf("====================================================\n"); printf("# #\n"); printf("# #\n"); printf("# 1. 建立新玩家 #\n"); printf("# 2. 讀取存檔 #\n"); printf("# #\n"); printf("# #\n"); printf("====================================================\n"); printf(" 選項:"); scanf("%d",&n); if (n == 1) { xj(); } else if (n == 2) { dq(); } else { printf("輸入錯誤,請重新選擇:\n"); menu1(); } } void menu2()//遊戲裡面的主選單 { int n; printf("====================================================\n"); printf("# #\n"); printf("# 貪吃蛇 Version goddemon #\n"); printf("# #\n"); printf("# 1. 開始遊戲 #\n"); printf("# 2. 檢視排行榜 #\n"); printf("# 3. 檢視我的分數 #\n"); printf("# 4. 退出遊戲 #\n"); printf("# #\n"); printf("# #\n"); printf("====================================================\n"); printf(" 選項:\n"); while (1) { scanf_s("%d",&n); switch (n)//選擇功能 { case 1: begin(); break; case 2: phb(); break; case 3: fs1(); break; case 4: ex(); break; default: printf("輸出錯誤,請重新輸入:\n"); break; } } } void xj()//新建使用者的名字 { ck(); ++zpalyer; //注意如果是在退出的時候賦予的值,會出現只能讀出兩個值的狀況特點-->即在子函式中賦予值,必須在讀取值後進行賦予值加減才可,否則可能出現亂碼狀況 printf("\t\t輸入使用者名稱:\n");//注意利用\t\t進行控制介面-->很nice scanf("%s",name); strcpy(player[zpalyer].name,name);//注意賦值的先後 menu2(); } void dq()//讀取存檔裡面的使用者且進行選擇 { ck(); printf("請輸入讀取的姓名:\n"); scanf("%s",name1); for (i = 0; i <= zpalyer; i++) { if ((strcmp(player[i].name,name1) == 0)) { menu2(); } else if(i==zpalyer) { printf("未找到該使用者,請在次選擇讀取與建立功能\n"); menu1(); } } } //-----------------------------功能函式區--------------------------------- int begin()//開始遊戲 { system("cls"); jm(); while (1) { keyDown(); if (!sfjs()) break; creatfood(); Sleep(snake1.speed); } player[zpalyer].palyefs = snake1.zfs; getoxy(W / 2,H / 2); printf("本次得分:%d\n",snake1.zfs); Sleep(3000); system("cls"); menu2(); Sleep(5000); return 0; } void phb()//排行榜 { int i; printf("====================== 排行榜 ====================\n"); for (i = 0; i <zpalyer; i++) { printf("%s\t%d\n",player[i].name,player[i].palyefs); } printf("====================================================\n"); } void fs1()//檢視自己的分數 { printf("你的分數為:\n"); printf("%d",player[zpalyer].palyefs); } void ex()//退出功能 { save(); exit(0); } void save() { FILE *fp; fp = fopen("tcs.txt","w+"); fwrite(&zpalyer,4,1,fp); for (i = 0; i <= zpalyer; i++) { fwrite(&player[i],sizeof(struct palyerinfo),fp); } fclose(fp); } void ck()//讀取文件中的資料狀況 { FILE *fp; int i; fp = fopen("tcs.txt","r+"); fread(&zpalyer,fp); for (i = 0; i <=zpalyer; i++) { fread(&player[i],fp); } fclose(fp); } void xuanz() { int j = 0,x = 1; menu2(); } void getoxy(int x,int y)//定位座標位置的函式 { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord); } void jm()//貪吃蛇初始化介面 { SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_INTENSITY); system("color 3e"); //列印上下邊界的迴圈 for (i = 0; i <= W; i+=2) { getoxy(i,0); printf("++"); getoxy(i,H);//列印下邊界 printf("++"); } for (i = 0; i < H; i++) { getoxy(0,i); printf("++"); getoxy(W,i); printf("++");//列印下邊界 } while (1)//生成初始化的食物 { srand((unsigned int)time(NULL)); food.x = rand() % (W - 4) + 2; food.y = rand() % (H - 2) + 1; if (food.x % 2 == 0) { break; } } getoxy(food.x,food.y); printf("*"); snake1.len = 3; snake1.speed = 200; snake1.x[0] = W / 2 + 1;//即在中間區域列印蛇頭 snake1.y[0] = H / 2; getoxy(snake1.x[0],snake1.y[0]); printf("★"); for (i = 1; i < snake1.len; i++)//列印蛇頭的狀況特點-->利用getoxy(游標移動)+printf語句聯合打印出蛇 { snake1.x[i] = snake1.x[i - 1] + 2;//即將座標賦值加2的狀況理解 snake1.y[i] = snake1.y[i - 1]; getoxy(snake1.x[i],snake1.y[i]); printf("★"); } getoxy(W - 2,0); return; } void creatfood()//建立食物的函式 { if (snake1.x[0] == food.x&&snake1.y[0] == food.y)//即蛇會吃掉這個食物 { while (1) { int flag = 1; srand((unsigned int)time(NULL)); food.x = rand() % (W - 4) + 2; food.y = rand() % (H - 2) + 1; for (i = 0; i < snake1.len; i++) { if (snake1.x[i] == food.x&&snake1.y[i] == food.y) { flag = 0; break; } } if (flag&&food.x % 2 == 0)//用該語句進行判斷是否該結束座標賦值 { break; } } getoxy(food.x,food.y);//即建立食物,每一次都進行創造 printf("*"); snake1.len++;//即蛇的長度加1,因為吃到了食物導致 snake1.speed -= 5; snake1.zfs += 10;//即一個果實的分數等於10分 changeFlag = 1;//即意味著吃到了食物,不需要擦除蛇尾的含義 } return;//即return可以為空 }void keyDown()//控制移動的函式 { int pre_key = key;//記錄前一個按鍵的方向 if (_kbhit()) { fflush(stdin); //getch()讀取方向鍵的時候,會返回兩次,第一次呼叫返回0或者224,第二次呼叫返回的才是實際值 key = _getch();//第一次呼叫返回的不是實際值 key = _getch();//第二次呼叫返回實際值 } if (changeFlag == 0) { getoxy(snake1.x[snake1.len - 1],snake1.y[snake1.len - 1]); printf(" ");//在蛇尾處輸出空格即擦去蛇尾 } //將蛇的每一節依次向前移動一節(蛇頭除外) for (i = snake1.len - 1; i > 0; i--) { snake1.x[i] = snake1.x[i - 1]; snake1.y[i] = snake1.y[i - 1]; } if (pre_key == 72 && key == 80) key = 72; if (pre_key == 80 && key == 72) key = 80; if (pre_key == 75 && key == 77) key = 75; if (pre_key == 77 && key == 75) key = 77; switch (key) { case 75: snake1.x[0] -= 2;//往左 break; case 77: snake1.x[0] += 2;//往右 break; case 72: snake1.y[0]--;//往上 break; case 80: snake1.y[0]++;//往下 break; } //打印出蛇頭 getoxy(snake1.x[0],snake1.y[0]); printf("★"); getoxy(W - 2,0); //由於目前沒有吃到食物,changFlag值為0 changeFlag = 0; return; } bool sfjs()//判斷遊戲是否結束的函式 { if (snake1.y[0] == 0 || snake1.y[0] == H) { return false; } if (snake1.x[0] == 0 || snake1.x[0] == W) { return false; } for (i = 1; i < snake1.len; i++) { if (snake1.x[i] == snake1.x[0] && snake1.y[i] == snake1.y[0])//注意判斷是否結束的函式需要注意 { return false; } } return true;//即返回這個函式本身為真 } int yy() { PlaySound(TEXT("F:\\小蘋果.wav"),NULL,SND_NODEFAULT | SND_ASYNC | SND_LOOP);//即利用轉換引數進行代 //SND_LOOP-->//重複播放聲音,必須與SND_ASYNC標誌一塊使用 //SND_ASYNC-->//用非同步方式播放聲音,PlaySound函式在開始播放後立即返回 //SND_NODEFAULT -->不播放預設聲音,若無此標誌,則PlaySound在沒找到聲音時會播放預設聲音-->典型找檔案音樂是用的格式檢視方式進行找的 return 0; } //------------------------------------------主函式區------------------------------- int main() { yy(); menu1(); system("pause"); return 0; }
效果圖:
更多有趣的經典小遊戲實現專題,分享給大家:
C++經典小遊戲彙總
python經典小遊戲彙總
python俄羅斯方塊遊戲集合
JavaScript經典遊戲 玩不停
java經典小遊戲彙總
javascript經典小遊戲彙總
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。