#史上最詳細(xì)的C語言貪吃蛇教程
#前言
在有用C寫貪吃蛇的一個(gè)想法之后梅忌,上網(wǎng)查了幾個(gè)教程狰腌,覺得不是很能看懂。恩牧氮。琼腔。□飧穑或者說不是一下子就能看出來思路+具體怎么實(shí)現(xiàn)丹莲。所以光坝,我花了早自習(xí)的時(shí)間想了想如何用最簡(jiǎn)單的方法實(shí)現(xiàn),晚上大約兩個(gè)小時(shí)寫了出來甥材。別說我用兩小時(shí)裝逼盯另,有了思路之后就是碼代碼和查細(xì)節(jié)的問題。
PS:這里補(bǔ)充說一下C語言寫的控制臺(tái)游戲的原理是什么洲赵,知道的同學(xué)直接跳過這一段鸳惯。實(shí)際上就是不斷的用system("cls");
清除屏幕再重新打印不一樣的內(nèi)容,在速度較快的時(shí)候就會(huì)有一種動(dòng)畫效果了叠萍,當(dāng)然這是控制臺(tái)芝发,就沒法究美觀了(可以改一下控制臺(tái)字體和背景顏色相對(duì)好看一點(diǎn),具體百度)苛谷,晃眼睛也是肯定的辅鲸。
如圖(中間有一點(diǎn)空白gif抓取的時(shí)候沒抓到請(qǐng)忽略):
源代碼已經(jīng)放在了github上感興趣的可以參考一下(順便star一下看官們)
** 這是源碼!3弧瓢湃! C-snake-iimT **
#步入正題
我們開始說思路。
- 我們需要一張地圖赫蛇,中間是空的四周有墻體绵患。
- 我們需要一條蛇,這條蛇由蛇頭和蛇身組成悟耘。
- 我們需要食物落蝙,并且在蛇吃掉食物之后將蛇的身體變長(zhǎng),而且重新生成一個(gè)食物暂幼。
- 蛇需要移動(dòng)筏勒,這應(yīng)該是最難實(shí)現(xiàn)的。
- 蛇撞到墻或者撞到自己的身體就會(huì)死亡旺嬉。
- 我們需要能用鍵盤控制蛇的運(yùn)動(dòng)方向管行,這個(gè)會(huì)和蛇的移動(dòng)有一些聯(lián)系。
Balabala我們有這么一大堆問題邪媳,我們來想想應(yīng)該如何用代碼實(shí)現(xiàn)捐顷。
整個(gè)地圖我們用一個(gè)坐標(biāo)系建立起來,這用一個(gè)二維字符數(shù)組就能實(shí)現(xiàn)了雨效,然后我們的蛇和食物只需要將中間的空格改成蛇的頭或者身體或者食物的樣子就行了迅涮。
這條蛇應(yīng)該如何描述,我們先區(qū)分蛇頭和蛇的身體徽龟,然后一組坐標(biāo)來將這個(gè)蛇的頭叮姑、頭后面第一節(jié)、第二節(jié)据悔、第三節(jié)传透。耘沼。。旷祸。以此類推耕拷。我現(xiàn)在是2050的地圖,所以我用一個(gè)
snake[1000][3]
來描述托享,這里面的1000是2050就是現(xiàn)在有1000個(gè)空(假如有人就玩到將整個(gè)地圖霸占了呢)坐標(biāo),snake[i][0]
的值用來描述這個(gè)坐標(biāo)是頭·snake[i][0]=1
還是身體snake[i][0]=0
浸赫,然后snake[i][1] snake[i][2]
分別用來描述所在的X坐標(biāo)和Y坐標(biāo)(i表示某一節(jié))闰围。這樣我們就用一個(gè)數(shù)組將蛇描述出來了,在后面我們生成視圖的時(shí)候?qū)⒃擖c(diǎn)的空格換成'#'或者'@'就好了既峡。生成食物我們需要產(chǎn)生隨機(jī)數(shù)作為食物的坐標(biāo)羡榴,而且這個(gè)隨機(jī)數(shù)要在一定的范圍內(nèi)不能在圍墻上,也不能和蛇的坐標(biāo)一樣运敢。生成隨機(jī)數(shù)用
srand(time(0));
int a = rand()%10+1;
這樣我們就能得到1-10的數(shù)校仑,這里的srand(time(0));
初始化一下時(shí)間函數(shù),然后rand會(huì)給我們一個(gè)很大的秒數(shù)传惠,這個(gè)秒數(shù)在不斷的變化迄沫,%10之后得到的數(shù)就在0-9,然后+1得到1-10的數(shù)卦方。根據(jù)這個(gè)原理羊瘩,生成一個(gè)在固定范圍內(nèi)的X坐標(biāo)和Y坐標(biāo),然后用這個(gè)x坐標(biāo)和y坐標(biāo)去遍歷snake數(shù)組看看x盼砍、y會(huì)不會(huì)同時(shí)相同尘吗,如果相同就重新生成一個(gè)知道不相同為止。這樣我們就生成了一個(gè)食物的坐標(biāo)浇坐。
蛇的移動(dòng)睬捶,就是不斷的變化那個(gè)坐標(biāo)集合,我們將蛇頭移動(dòng)到下一個(gè)坐標(biāo)之后近刘,后面的節(jié)一次覆蓋前一個(gè)就完成了一個(gè)單位的移動(dòng)擒贸。這樣的話,我們的方向只需要對(duì)蛇頭作用就行了〉穑現(xiàn)在我們?cè)O(shè)定一個(gè)
direct=1
即向上酗宋,direct的值1/2/3/4分別代表上下左右。現(xiàn)在蛇向上走疆拘,蛇頭向上的話蜕猫,X不變,Y-1就好了哎迄。
(注意我們這里的坐標(biāo)系是類似數(shù)學(xué)上第四象限的坐標(biāo)系回右,所以X軸在最上面隆圆。)
然后我們將第二個(gè)節(jié)換成前一次蛇頭所在的坐標(biāo),第三個(gè)坐標(biāo)變成前一次第二個(gè)的坐標(biāo)翔烁,以此類推渺氧,蛇就往前移動(dòng)了一個(gè)單位。蛇頭撞到墻或者撞到自己的身體蹬屹,我們只需要判斷蛇頭的坐標(biāo)是否和墻的坐標(biāo)重合或者和蛇的某一節(jié)重合侣背。所以在蛇移動(dòng)之后我們用蛇頭的坐標(biāo)去遍歷蛇自己的所有坐標(biāo)并且判斷蛇的X或者Y是否大于或者小于地圖邊界了,這樣就能知道是否發(fā)生碰撞慨默,發(fā)生碰撞之后直接break不在刷新視圖就好贩耐。
當(dāng)鍵盤有輸入的時(shí)候判斷是上或者下后者左或者右,然后重置direct的值厦取,就將方向重置了潮太。當(dāng)然在向上走的時(shí)候按下鍵是不行的其他也是類似,所以還要判斷一下虾攻。鍵盤讀入事件我們需要用到一個(gè)函數(shù)
_kbhit();
如果有鍵盤敲擊铡买,這個(gè)函數(shù)就會(huì)返回一個(gè)非0的數(shù)。所以我們可以在每一次刷新的時(shí)候
char ch;
if(_kbhit()) //有鍵盤敲擊
{
ch = _getchar();
}
switch(ch)
{
//判斷用戶按下了哪個(gè)鍵
case 'H':
//按下鍵盤的上鍵_getchar()得到的是H
//可以自己寫一個(gè)程序看看上下左右分別是哪幾個(gè)字符然后用來判斷就行了
if(direct!=2)
//如果當(dāng)前的方向不是向下 就將方向重新定義為向上 其他的類似
direct=1;
}
這樣我們就通過讀取鍵盤重新設(shè)置了方向霎箍。
- 這些問題我們都一一解決了奇钞,現(xiàn)在我們來想一下程序運(yùn)行的順序是什么。
1)初始化朋沮,將地圖造出來蛇券。
2)如果有鍵盤輸入的話,就重新設(shè)置運(yùn)動(dòng)方向樊拓。
3)制造食物纠亚。
4)讓蛇移動(dòng),如果吃掉食物就重新生成一個(gè)食物筋夏,如果會(huì)死亡就break蒂胞。
5)用蛇的坐標(biāo)將地圖中的空格替換為'#'和'@',將食物所在的坐標(biāo)設(shè)置為'O'。
6)輸出視圖条篷,即將最終生成的地圖打印出來骗随。
7)Sleep(200) 暫停200毫秒之后在進(jìn)行上面的。
我們將上面這些都放在一個(gè)while(1)
循環(huán)里面赴叹,只有死了才會(huì)跳出循環(huán)不在清屏打印(清屏打印其實(shí)就是刷新視圖)鸿染,然后輸出游戲結(jié)束得分就好。
#將上述的代碼實(shí)現(xiàn)方法寫成一個(gè)一個(gè)函數(shù)乞巧,然后按照順序放在循環(huán)體涨椒,就完成了貪吃蛇的制作。
#理解思路,模仿一下代碼蚕冬,寫一個(gè)你自己的貪吃蛇免猾,并且自己DIY一點(diǎn)其他的小創(chuàng)意,動(dòng)手折騰吧囤热。
我叫掏糞猎提,如果喜喜歡我的文章請(qǐng)點(diǎn)個(gè)喜歡~歡迎關(guān)注我的的博客www.iimt.me和新浪微博。