C語(yǔ)言實(shí)現(xiàn)貪吃蛇游戲代碼
本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)貪吃蛇游戲的具體代碼,供大家參考,具體內(nèi)容如下
//------------------------------------------problm區(qū)------------------------------ //①思考typedef 定義的變量如何利用fwrite進(jìn)行存儲(chǔ) //②典型可利用sleep()語(yǔ)句類實(shí)現(xiàn)控制移動(dòng)速度 //③BOOL PlaySoundW(LPCWSTR, HMODULE, DWORD)”: 無(wú)法將參數(shù) 1 從“const char[8]”轉(zhuǎn)換為“LPCWSTR -->導(dǎo)致原因-->即原因vc2010開(kāi)發(fā)環(huán)境中可能找不到字符串的音樂(lè)導(dǎo)致 //④思考怎么消去不是這四個(gè)鍵的情況 #include<stdio.h> #include<stdlib.h> #include<Windows.h> #include<conio.h> #include<string.h> #include<time.h> #include <MMSystem.h>//導(dǎo)入聲音頭文件-->即聯(lián)合形成 #pragma warning(disable:4996)//可以利用該代碼消去警告類 #pragma comment(lib, "Winmm.lib")//鏈接庫(kù) //------------------------------------------變量區(qū)--------------------------------- //---------------------------------------宏定義變量定義---------------------------- #define H 24//定義高為24 #define W 78//定義寬為78 #define false 0 #define true 1 //-------------------------------------非宏定義變量定義---------------------------- int n=0;//全局變量定用于寫界面的狀況 int zpalyer=0;//記錄總玩家的個(gè)數(shù) int fs;//用于記錄玩家的分?jǐn)?shù) int key=72;//用于控制玩家的移動(dòng)方向的變量,且賦予初始化值為上 int changeFlag = 0;//判斷是否吃到了果實(shí),用于確定是否需要擦除蛇尾 int i;//用于函數(shù)中控制循環(huán)的變量 char name[20]; char name1[20]; struct palyerinfo//定義玩家的名稱與分?jǐn)?shù)的結(jié)構(gòu)體 { char name[20]; int palyefs; }player[100]; struct //定義貪吃蛇的食物產(chǎn)生的坐標(biāo)類 { int x; int y; }food; struct //利用鏈表實(shí)現(xiàn)貪吃蛇的長(zhǎng)度 { int x[100]; int y[100]; int len; int zfs; int speed; }snake1; //------------------------------------------聲明區(qū)--------------------------------- 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(); //------------------------------------------函數(shù)區(qū)--------------------------------- //-----------------------------------------界面函數(shù)區(qū)------------------------------ void menu1()//進(jìn)入游戲后選擇讀取用戶還是新建用戶 { int n; system("color 3e");//即加一個(gè)語(yǔ)句即可控制顏色,即與cmd中類似進(jìn)行控制顏色-->控制的是控制臺(tái)的顏色 printf("====================================================\n"); printf("# #\n"); printf("# #\n"); printf("# 1. 建立新玩家 #\n"); printf("# 2. 讀取存檔 #\n"); printf("# #\n"); printf("# #\n"); printf("====================================================\n"); printf(" 選項(xiàng):"); scanf("%d", &n); if (n == 1) { xj(); } else if (n == 2) { dq(); } else { printf("輸入錯(cuò)誤,請(qǐng)重新選擇:\n"); menu1(); } } void menu2()//游戲里面的主菜單 { int n; printf("====================================================\n"); printf("# #\n"); printf("# 貪吃蛇 Version goddemon #\n"); printf("# #\n"); printf("# 1. 開(kāi)始游戲 #\n"); printf("# 2. 查看排行榜 #\n"); printf("# 3. 查看我的分?jǐn)?shù) #\n"); printf("# 4. 退出游戲 #\n"); printf("# #\n"); printf("# #\n"); printf("====================================================\n"); printf(" 選項(xiàng):\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("輸出錯(cuò)誤,請(qǐng)重新輸入:\n"); break; } } } void xj()//新建用戶的名字 { ck(); ++zpalyer; //注意如果是在退出的時(shí)候賦予的值,會(huì)出現(xiàn)只能讀出兩個(gè)值的狀況特點(diǎn)-->即在子函數(shù)中賦予值,必須在讀取值后進(jìn)行賦予值加減才可,否則可能出現(xiàn)亂碼狀況 printf("\t\t輸入用戶名:\n");//注意利用\t\t進(jìn)行控制界面-->很nice scanf("%s", name); strcpy(player[zpalyer].name,name);//注意賦值的先后 menu2(); } void dq()//讀取存檔里面的用戶且進(jìn)行選擇 { ck(); printf("請(qǐng)輸入讀取的姓名:\n"); scanf("%s", name1); for (i = 0; i <= zpalyer; i++) { if ((strcmp(player[i].name, name1) == 0)) { menu2(); } else if(i==zpalyer) { printf("未找到該用戶,請(qǐng)?jiān)诖芜x擇讀取與創(chuàng)建功能\n"); menu1(); } } } //-----------------------------功能函數(shù)區(qū)--------------------------------- int begin()//開(kāi)始游戲 { 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()//查看自己的分?jǐn)?shù) { printf("你的分?jǐn)?shù)為:\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), 1, fp); } fclose(fp); } void ck()//讀取文檔中的數(shù)據(jù)狀況 { FILE *fp; int i; fp = fopen("tcs.txt", "r+"); fread(&zpalyer, 4, 1, fp); for (i = 0; i <=zpalyer; i++) { fread(&player[i], sizeof(struct palyerinfo), 1, fp); } fclose(fp); } void xuanz() { int j = 0, x = 1; menu2(); } void getoxy(int x,int y)//定位坐標(biāo)位置的函數(shù) { 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"); //打印上下邊界的循環(huán) 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;//即在中間區(qū)域打印蛇頭 snake1.y[0] = H / 2; getoxy(snake1.x[0], snake1.y[0]); printf("★"); for (i = 1; i < snake1.len; i++)//打印蛇頭的狀況特點(diǎn)-->利用getoxy(光標(biāo)移動(dòng))+printf語(yǔ)句聯(lián)合打印出蛇 { snake1.x[i] = snake1.x[i - 1] + 2;//即將坐標(biāo)賦值加2的狀況理解 snake1.y[i] = snake1.y[i - 1]; getoxy(snake1.x[i], snake1.y[i]); printf("★"); } getoxy(W - 2,0); return; } void creatfood()//創(chuàng)建食物的函數(shù) { if (snake1.x[0] == food.x&&snake1.y[0] == food.y)//即蛇會(huì)吃掉這個(gè)食物 { 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)//用該語(yǔ)句進(jìn)行判斷是否該結(jié)束坐標(biāo)賦值 { break; } } getoxy(food.x, food.y);//即創(chuàng)建食物,每一次都進(jìn)行創(chuàng)造 printf("*"); snake1.len++;//即蛇的長(zhǎng)度加1,因?yàn)槌缘搅耸澄飳?dǎo)致 snake1.speed -= 5; snake1.zfs += 10;//即一個(gè)果實(shí)的分?jǐn)?shù)等于10分 changeFlag = 1;//即意味著吃到了食物,不需要擦除蛇尾的含義 } return;//即return可以為空 }void keyDown()//控制移動(dòng)的函數(shù) { int pre_key = key;//記錄前一個(gè)按鍵的方向 if (_kbhit()) { fflush(stdin); //getch()讀取方向鍵的時(shí)候,會(huì)返回兩次,第一次調(diào)用返回0或者224,第二次調(diào)用返回的才是實(shí)際值 key = _getch();//第一次調(diào)用返回的不是實(shí)際值 key = _getch();//第二次調(diào)用返回實(shí)際值 } if (changeFlag == 0) { getoxy(snake1.x[snake1.len - 1], snake1.y[snake1.len - 1]); printf(" ");//在蛇尾處輸出空格即擦去蛇尾 } //將蛇的每一節(jié)依次向前移動(dòng)一節(jié)(蛇頭除外) 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); //由于目前沒(méi)有吃到食物,changFlag值為0 changeFlag = 0; return; } bool sfjs()//判斷游戲是否結(jié)束的函數(shù) { 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])//注意判斷是否結(jié)束的函數(shù)需要注意 { return false; } } return true;//即返回這個(gè)函數(shù)本身為真 } int yy() { PlaySound(TEXT("F:\\小蘋果.wav"), NULL, SND_NODEFAULT | SND_ASYNC | SND_LOOP);//即利用轉(zhuǎn)換參數(shù)進(jìn)行代 //SND_LOOP-->//重復(fù)播放聲音,必須與SND_ASYNC標(biāo)志一塊使用 //SND_ASYNC-->//用異步方式播放聲音,PlaySound函數(shù)在開(kāi)始播放后立即返回 //SND_NODEFAULT -->不播放缺省聲音,若無(wú)此標(biāo)志,則PlaySound在沒(méi)找到聲音時(shí)會(huì)播放缺省聲音-->典型找文件音樂(lè)是用的格式查看方式進(jìn)行找的 return 0; } //------------------------------------------主函數(shù)區(qū)------------------------------- int main() { yy(); menu1(); system("pause"); return 0; }
效果圖:
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++的STL中accumulate函數(shù)的使用方法
這篇文章主要介紹了C++的STL中accumulate的使用方法,accumulate作用是累加求和即自定義類型數(shù)據(jù)處理,下文具體的操作方法需要的小伙伴可以參考一下2022-03-03C++11中bind綁定器和function函數(shù)對(duì)象介紹
這篇文章主要介紹了C++11中bind綁定器和function函數(shù)對(duì)象介紹,綁定器,函數(shù)對(duì)象和lambda表達(dá)式只能使用在一條語(yǔ)句中,更多相關(guān)內(nèi)容需要的小伙伴可以參考一下2022-07-07基于QT的TCP通信服務(wù)的實(shí)現(xiàn)
在項(xiàng)目開(kāi)發(fā)過(guò)程中,很多地方都會(huì)用到TCP通信,本文主要介紹了基于QT的TCP通信服務(wù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05c++利用windows函數(shù)實(shí)現(xiàn)計(jì)時(shí)示例
這篇文章主要介紹了c++利用windows函數(shù)實(shí)現(xiàn)計(jì)時(shí)示例,需要的朋友可以參考下2014-05-05深入解析C++編程中對(duì)設(shè)計(jì)模式中的策略模式的運(yùn)用
這篇文章主要介紹了C++編程中對(duì)設(shè)計(jì)模式中的策略模式的運(yùn)用,需要的朋友可以參考下2016-03-03