史上最牛C語言控制檯遊戲!C語言控制檯音遊——Rhythm Slasher! 附上原始碼供交流學習
這個遊戲是我大一上學期弄出來,剛學C語言,學了迴圈和選擇結構。那時候資料結構都不太會,但是按捺不住自己的想法,總想用現有的東西做點什麼。
就連窗體程式都不會,沒有任何的圖片,全是ASCII字元的一個遊戲,我為什麼敢說是史上最牛?我感覺牛不在演算法上,牛不在精美的介面,而是你僅僅用這樣的條件,能創造出什麼?
C語言和控制檯,大概是程式設計師最熟悉,最早接觸的東西了吧。說到C語言控制檯遊戲,你可能想到的是,貪吃蛇?RPG遊戲?俄羅斯方塊?我之前見過的比較牛的,也就一個打飛機遊戲了。有人會說,畢竟是C語言控制檯,做出來的東西也就只能是這樣了吧,黑白的介面(也有彩色的,不過很少吶),游標一閃一閃,然後輸入個數字按回車執行……我總覺得不甘心,我感覺還能做得更好。想了挺久,不如做個音遊吧。於是三天之後,有了這個Rhythm Slasher!(我命名為節奏斬擊者,不要吐槽我英語渣,中二什麼的,哈哈)。下面先附上介面圖:
游標呢?序號呢?我只想說,按上下選擇,回車確定。還會變顏色,有沒有很炫酷的感覺~
這遊戲主要就是按你的喜好,錄製出任意曲目的節奏,儲存起來。之後就可以像節奏大師那樣玩了。簡而言之,就是可以用任何你喜歡的音樂,DIY你自己喜歡的任意節奏譜的簡易版節奏大師。
介紹一下游戲方法:
1. 首先將任意一首音樂,放入到遊戲本體目錄所在的資料夾中。
2. 第一步先選擇Record。選擇你喜歡的音樂,然後聽著音樂,錄入節奏。就是根據節奏,按你的喜好敲擊askl四個按鍵,錄製你喜歡的節奏譜。
3. 之後,你就可以選擇Slash,演奏你錄製過節奏譜的音樂。遊戲會按照你錄製節奏譜時候的節奏,生成音符。你根據音符,配合節奏,在適當的時機敲擊相應音符的按鍵,就可以演奏該樂曲,最後會統計你的分數。
ps:四個按鍵是可以設定的,Record只需要一次,之後你可以任意次Slash,即使關掉遊戲,也不會丟失資料。音樂僅支援wav檔案,因為使用的是C語言自帶的播放音樂函式。
下面附上原始碼,程式碼的註釋還是比較詳細的:
#include <stdio.h> #include <conio.h> #include <stdlib.h> #pragma comment(lib, "winmm.lib") //播放音樂所用標頭檔案 #include <windows.h> //函式宣告 void Print_rhythm(char p,int v);//輸出節奏音符 void Hide_cursor();//隱藏游標 int Choice_menus();//選擇選單,返回選項的編號(0,1,2,3) void Cursor_goto_xy(int x,int y);//定位游標位置到指定座標 void Selection(int n);//進入對應選項 void Record();//記錄節奏 void Slash();//斬擊節奏 void Setting();//設定按鍵 void Operate();//遊戲說明 //全域性變數定義 int n,i,start_music,good,miss,end,Select,SM; char p,q,w,key1='a',key2='s',key3='k',key4='l'; char name[20][1000]; //主函式 int main() { Hide_cursor();//隱藏游標 system("mode con cols=66 lines=40 ");//控制檯大小 system("color 19");//前景色,後景色 system("title Rhythm Slasher!");//視窗標題 end=1; printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\tRhythm Slasher!\n\n\n\t\tPress any key to continue..."); getch(); while(end) { n=Choice_menus();//選擇選單,返回選項的編號(0,1,2,3) system("cls"); Selection(n);//進入對應選項 } return 0; } int Choice_menus()//選擇選單,返回選項的編號(0,1,2,3,4) { char number,select; number=0; system("cls"); printf("\n\n\n\n\n\n\n\n\n\t\t\t Record!\n\n\n\n\t\t\t Slash!\n\n\n\n\t\t\t Setting!\n\n\n\n\t\t\t Operate!\n\n\n\n\t\t\t Exit!"); while(1) { switch(number) { case 0: Cursor_goto_xy(21,9);//定位游標位置到指定座標 system("color 6e");//前景色,後景色 break; case 1: Cursor_goto_xy(21,13);//定位游標位置到指定座標 system("color 5d");//前景色,後景色 break; case 2: Cursor_goto_xy(21,17);//定位游標位置到指定座標 system("color 4c");//前景色,後景色 break; case 3: Cursor_goto_xy(21,21);//定位游標位置到指定座標 system("color 2a");//前景色,後景色 break; case 4: Cursor_goto_xy(21,25);//定位游標位置到指定座標 system("color 3b");//前景色,後景色 break; } printf(">>>>"); select=getch(); if(select==72)//方向鍵,上 { number--; } else if(select==80)//方向鍵,下 { number++; } else if(select==13)//回車 { return number; } number=(number+5)%5; printf("\b\b\b\b "); } } void Selection(int n)//進入對應選項 { if(n==0) { Record();//記錄節奏 } else if(n==1) { Slash();//斬擊節奏 } else if(n==2) { Setting();//設定 } else if(n==3) { Operate();//說明 } else { end=0;//退出 } } void Operate()//遊戲說明 { printf("\n\n\n\n\n\t製作人 : Lulu\n\n\n\t操作說明 :\n\n\tRecord! :\n"); printf("\t根據音樂節奏按下按鍵,由左到右依次按鍵為a,s,k,l。\n"); printf("\t系統將記錄下你的按鍵,作為歌曲的節奏譜。\n"); printf("\t按鍵可以在設定中調整。\n"); printf("\n\tSlash! :\n"); printf("\t使用上一次Record!製成的節奏譜,生成節奏音符。\n"); printf("\t由左往右依次按鍵為a,s,k,l。隨音樂節奏擊破!\n"); printf("\t按鍵可以在設定中調整。\n"); printf("\n\tSetting! :\n"); printf("\t設定遊戲按鍵。\n"); printf("\n\tOperate! :\n"); printf("\t遊戲說明。\n"); printf("\n\tExit! :\n"); printf("\t退出。\n"); printf("\n\t\t\t按任意鍵返回。\n"); getch(); } void Setting()//設定按鍵 { printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\tkey1 : "); key1=getch(); printf("%c",key1); Sleep(1000); system("cls"); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\tkey2 : "); key2=getch(); printf("%c",key2); Sleep(1000); system("cls"); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\tkey3 : "); key3=getch(); printf("%c",key3); Sleep(1000); system("cls"); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\tkey4 : "); key4=getch(); printf("%c",key4); Sleep(1000); system("cls"); printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\t\t\tSetting succeeded!"); printf("\n\n\t\t Press any key to continue..."); getch(); } int Select_music()//選擇音樂 { int i,n; FILE *fp = NULL; system("dir /b *.wav>> buf.Ock");//將目錄匯出到buf.Ock fp = fopen("buf.Ock","rb"); i=0; while (!feof(fp)) { fgets(name[i],1000,fp); name[i][strlen(name[i])-6]='\0'; i++; } n=i; fclose(fp); system("del /Q buf.Ock"); //刪除D:目錄下buf.Ock檔案 char number=0,select; Select=0; system("cls"); for(i=0; i<n-1; i++) { printf("\n\t%d. %s\n",i+1,name[i]); } while(1) { Cursor_goto_xy(2,2*number+1);//定位游標位置到指定座標 if(number%2==0) system("color 6e");//前景色,後景色 else system("color 5d");//前景色,後景色 printf(">>>>"); select=getch(); if(select==72)//方向鍵,上 { number--; } else if(select==80)//方向鍵,下 { number++; } else if(select==13)//回車 { return number; } number=(number+n-1)%(n-1); printf("\b\b\b\b "); } } void Record()//記錄節奏 { char musicNamer[100],musicNamew[100],musicName[100],musicNamev[100]; int v; SM=Select_music();//選擇音樂 system("cls"); FILE *fp1;//定義檔案指標 FILE *fp2;//定義檔案指標 FILE *fp3;//定義檔案指標 strcpy(musicNamer,name[SM]); strcpy(musicNamew,name[SM]); strcpy(musicName,name[SM]); strcpy(musicNamev,name[SM]); strcat(musicNamer,"r.txt"); strcat(musicNamew,"w.txt"); strcat(musicNamev,"v.txt"); strcat(musicName,".wav"); fp1=fopen(musicNamer,"w");//以寫入模式(w)開啟檔案 fp2=fopen(musicNamew,"w"); fp3=fopen(musicNamev,"w"); printf("Set the velocity of this song(20 to 70):"); scanf("%d",&v); fprintf(fp3,"%d",v); fclose(fp3); printf("\n\tReady?"); for(i=39; i>0; i--) { printf("\n ! ! ! ! "); } fprintf(fp2,"00000000"); getch(); PlaySound(musicName,NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);//播放音樂 while(1) { if(kbhit())//kbhit(),監測當前是否有按鍵按下,有返回非零值,無,返回零 { p=getch(); while(kbhit()) //實際上,親測發現,只要緩衝區有資料存在,都視為有按鍵按下。故可以用它清空緩衝區 { getch();//當緩衝區有資料時,用getch()提取資料,直至緩衝區空 } if(p==key1) { p='1'; } else if(p==key2) { p='2'; } else if(p==key3) { p='3'; } else if(p==key4) { p='4'; } else { fprintf(fp1,"00000000"); PlaySound(NULL, NULL, SND_PURGE) ;//停止播放音樂 fprintf(fp1,"5");//寫入到檔案函式 fprintf(fp2,"5"); fclose(fp1);//關閉檔案 fclose(fp2); break; } } else { p='0'; } fprintf(fp1,"%c",p); fprintf(fp2,"%c",p); Print_rhythm(p,v);//生成節奏音符 } printf("\n\tComplete!\n"); printf("Press any key to continue..."); getch(); system("cls"); } void Slash()//斬擊節奏 { char musicNamer[100],musicNamew[100],musicName[100],musicNamev[100]; int v; good=0; miss=0; FILE *fin1; FILE *fin2; FILE *fin3; SM=Select_music();//選擇音樂 system("cls"); strcpy(musicNamer,name[SM]); strcpy(musicNamew,name[SM]); strcpy(musicName,name[SM]); strcpy(musicNamev,name[SM]); strcat(musicNamer,"r.txt"); strcat(musicNamew,"w.txt"); strcat(musicNamev,"v.txt"); strcat(musicName,".wav"); fin1=fopen(musicNamer,"r");//以讀取模式(r)開啟檔案 fin2=fopen(musicNamew,"r"); fin3=fopen(musicNamev,"r"); fscanf(fin3,"%d",&v); fclose(fin3); printf("The velocity of this music is %d\n",v); printf("\tReady?"); for(i=39; i>0; i--) { printf("\n ! ! ! ! "); } start_music=0; getch(); while(1) { if(start_music==10)//延遲播放音樂 { PlaySound(musicName,NULL,SND_FILENAME|SND_ASYNC|SND_LOOP);//播放音樂 } start_music++; fscanf(fin1,"%c",&p);//讀取檔案函式 fscanf(fin2,"%c",&w); if(p=='5') { PlaySound(NULL, NULL, SND_PURGE) ; fclose(fin1); fclose(fin2); break; } Print_rhythm(p,v);//生成節奏音符 if(kbhit()) { q=getch(); while(kbhit()) { getch(); } if(q==key1) { q='1'; } else if(q==key2) { q='2'; } else if(q==key3) { q='3'; } else if(q==key4) { q='4'; } } else { q='0'; } if(q==w) { //system("color 20"); printf("Good!");//正確提示 good++; } else { //system("color 40"); printf("Miss!!!!!!!!!!!!!!!!!!!!!!");//錯誤提示 miss++; } } printf("\n\tFinish play!\n"); printf("Total:%d Good:%d Miss:%d\n",good+miss,good,miss); printf("Press any key to continue..."); getch(); system("cls"); } void Cursor_goto_xy(int x,int y)//定位游標位置到指定座標 { HANDLE hOut; hOut = GetStdHandle(STD_OUTPUT_HANDLE); COORD pos= {x,y}; SetConsoleCursorPosition(hOut,pos); } void Hide_cursor()//隱藏游標 { CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); } void Print_rhythm(char p,int v)//生成節奏音符 { if(p=='0') { printf("\n ! ! ! ! "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); } else if(p=='1') { printf("\n ! ! ! ! "); Sleep(v); printf("\n 888 ! ! ! "); Sleep(v); printf("\n 888 ! ! ! "); Sleep(v); printf("\n 888 ! ! ! "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); } else if(p=='2') { printf("\n ! ! ! ! "); Sleep(v); printf("\n ! 888 ! ! "); Sleep(v); printf("\n ! 888 ! ! "); Sleep(v); printf("\n ! 888 ! ! "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); } else if(p=='3') { printf("\n ! ! ! ! "); Sleep(v); printf("\n ! ! 888 ! "); Sleep(v); printf("\n ! ! 888 ! "); Sleep(v); printf("\n ! ! 888 ! "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); } else if(p=='4') { printf("\n ! ! ! ! "); Sleep(v); printf("\n ! ! ! 888 "); Sleep(v); printf("\n ! ! ! 888 "); Sleep(v); printf("\n ! ! ! 888 "); Sleep(v); printf("\n ! ! ! ! "); Sleep(v); } }
程式碼只用了迴圈和判斷,還有檔案讀寫,理解起來應該不難。
本渣渣能力有限,程式碼可能顯得累贅而且程式功能不全,有bug。歡迎各位大佬指出更正。
程式碼和遊戲本體,我一併上傳到百度雲:
我是後記:
即使現在學了很多演算法,學了很多語言,很多東西,也再沒做出來什麼有趣的東西了。最近決定重拾心情做點什麼,哈哈~不管結果如何也算是一個嘗試,一番經歷~
最後,歡迎各位大佬來擾~
相關推薦
史上最牛C語言控制檯遊戲!C語言控制檯音遊——Rhythm Slasher! 附上原始碼供交流學習
這個遊戲是我大一上學期弄出來,剛學C語言,學了迴圈和選擇結構。那時候資料結構都不太會,但是按捺不住自己的想法,總想用現有的東西做點什麼。 就連窗體程式都不會,沒有任何的圖片,全是ASCII字元的一個遊戲,我為什麼敢說是史上最牛?我感覺牛不在演算法上,牛不在精美的介面,而是你
史上最牛的Java架構師進階路線
驀然回首自己做開發已經十年了,這十年中我獲得了很多,技術能力、培訓、出國、大公司的經歷,還有很多很好的朋友。但再仔細一想,這十年中我至少浪費了五年時間,這五年可以足夠讓自己成長為一個優秀的程式設計師,可惜我錯過了,我用這五年時間和很多程式設計師一樣在困惑和迷茫中找不到出路! 路其實一直都在那裡,
史上最牛Java架構師進階路線
1.工程化專題 (團隊大於3個人之後,你需要去考慮團隊合作,科學管理) 2. 原始碼分析專題 (好的程式設計師,一行程式碼一個設計就能看出來,原始碼分析帶你品味程式碼,感受架構) 3.高效能及分散式專題 (跟上技術節奏,擴寬技術視野
史上最牛JAVA思維導圖學習筆記從初級到架構
我做過有道雲筆記、印象筆記,也寫過部落格,幾十篇文章之後,發現對筆記分類整理很麻煩,查詢不容易,往往自己寫的內容都不願意看一眼,後來用了思維導圖,很好用,結構清晰,一目瞭然,又靈機一動把導圖做成chm格式,你知道的API文件都是chm,離線狀態下就以查看了。在開發過程中,遇到
史上最牛逼的純CSS實現tab選項卡,閃瞎你的狗眼
html檔案<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>CSS3外觀漂亮淡入淡出Tab選單演示<
號稱史上最牛X的程式設計師簡歷,萬千辛酸匯聚於此
網上流行著這麼一段程式設計師的自我評價:本人學識淵博、經驗豐富,程式碼風騷、效率恐怖,C/C++、java、php無不精通,熟練掌握各種框架,深山苦練20餘年,一天只睡4個小時,千里之外定位問題,瞬息之間修復上線。身體強壯、健步如飛,可連續程式設計100小時不休息,討論技術方
史上最牛的Java思維學習導圖
我做過有道雲筆記、印象筆記,也寫過部落格,幾十篇文章之後,發現對筆記分類整理很麻煩,查詢不容易,往往自己寫的內容都不願意看一眼,後來用了思維導圖,很好用,結構清晰,一目瞭然,又靈機一動把導圖做成chm格式,你知道的API文件都是chm,離線狀態下就以查看了。在開發過程中,
史上最牛的Linux視訊教程—兄弟連 學習筆記2
7月25日 4.2.2Linux常用命令-許可權管理命令-其他許可權管理命令(chown chgrp umask) 1. chown(改變檔案或者目錄的所有者) 原意:change file ownership 格式:chown [使用者] [檔案或目錄] 備註:只
史上最牛女祕書 郵件內容
如果你今天還不知道“史上最牛女祕書”是誰,或者你還沒收到那封在網路上引起軒然大波的郵件,只能說明你不是那些著名外企中的一員。最近一週,從北京、上海到成都、廣州、南京……全國所有知名外企都在瘋狂轉發一封來自EMC(全球最大的網路資訊儲存商,總部在美國)北京總部的電子郵件:EMC
收益爆表,史上最牛BEAM挖礦指南
BEAM 是基於 MimbleWimble 協議開發的加密貨幣,採用 PoW 共識,致力於解決比特幣在擴充套件性和私密性上的不足,在國內外都備受關注。2019年1月3日晚上10點,各大礦池開始上線開挖。BEAM雖然目前還沒上線交易平臺,但是目前截止發稿時場外收購價已經達到18元一個。按照目前的挖
史上最牛最全的LINUX命令集
Linux # ethtool eth0 # Show the ethernet status (replaces mii-diag) # ethtool -s eth0 speed 100 duplex full # Force 100Mbit Full dup
史上最牛的Linux視訊教程—兄弟連 學習筆記1
7月24日 3.1給初學者的建議——注意事項 1.Linux嚴格區分大小寫 2.硬碟檔案是/dev/sd[a-p] 光碟檔案/dev/sr0等 3.Linux沒有副檔名 4.Linux所有儲存裝置都必須掛載之後才能用(手工分配) 3.2給初學者的建議—
5次史上最牛的黑客攻擊
好萊塢認為,黑客就像是使用計算機的黑魔導士。在電影中,計算機可以炸燬房屋,關閉公路,釋放瘟疫還有引發女權運動。也許有人認為,好萊塢的想象力很豐滿,但現實是骨感的。他們錯了,因為在現實中,確實也有如電影所描述的黑客行動,而且刺激程度絕對不亞於電影。 1、邏輯炸彈引爆西伯利亞 在1982年,在里根gov的CI
史上最牛JAVA思維導圖學習筆記
我做過有道雲筆記、印象筆記,也寫過部落格,幾十篇文章之後,發現對筆記分類整理很麻煩,查詢不容易,往往自己寫的內容都不願意看一眼,後來用了思維導圖,很好用,結構清晰,一目瞭然,又靈機一動把導圖做成chm格式,你知道的API文件都是chm,離線狀態下就以查看了。在開發過程中,遇到某個點有些印象模糊了就開啟看一
史上最牛逼的音樂播放器—仿網易雲音樂(已開源)
前言:音樂播放器倒見過不少,做到幾乎和官方網易雲音樂安卓版差不多的,還是頭第一回見。aa112901 的這款仿網易雲音樂安卓版客戶端,很多地方值得我們學習。無論是下載模組,還是換膚模組,還是炫麗的UI介面。等。用心在每一個細節。aa112901 本專案的github為:
號稱史上最牛X的程序員簡歷,萬千辛酸匯聚於此
工作 效率 支持 不支持 拆遷 大牛 自己 前端 上線 網上流行著這麽一段程序員的自我評價: 本人學識淵博、經驗豐富,代碼風騷、效率恐怖,C/C++、java、php無不精通,熟練掌握各種框架,深山苦練20余年,一天只睡4個小時,千裏之外定位問題,瞬息之間修復上線。身體強壯
史上最牛的5次黑客攻擊!比電影更刺激!
好萊塢認為,黑客就像是使用計算機的黑魔導士。在電影中,計算機可以炸燬房屋,關閉公路,釋放瘟疫還有
史上最全socket模組詳解!沒有學不會的模組!只有學不學的模組!
import socket sk= socket.socket()#建立物件 sk.bind(('127.0.0.1',9999,))#繫結IP和埠,以一個元組的方式傳進去 sk.listen(5)#在前面連結已經建立的情況下,後面最多讓五
史上最全Python基礎合集!集合用法、檔案操作字元轉換、函式
list = {1, 3, 6, 5, 7, 9, 11, 3, 7} # 定義集合方式一 list1 = set([1, 3, 6, 5, 7, 9, 11, 3, 7]) # 定義集合方式二 list2 = set() # 定義一個空集合 p
高新技術企業認定,史上最詳細的申請攻略!(深度好文)
相關 str 直接 方式 項目 微信 組織 名片 數據 在市場廣闊的今天,基本每個省和市地×××府都會建立產業園區或高新技術企業優化孵化帶,提供各種政策支持、稅收優惠以及財政補助。同時,高新技術企業資質對企業來說是一張閃亮的名片,相當於中國的品牌馳名商標,不僅能夠為企業帶來