1小時開發(fā)貪吃蛇,原來編程如此簡單

本系列實例教程第二趴,作者僅僅想通過一些實際案例,帶領(lǐng)大家了解編程,編程其實如此簡單。

在學(xué)習(xí)本教程之前,需要有兩個準(zhǔn)備,首先,您需要有一點點的編程基礎(chǔ),比如什么是變量、條件判斷、循環(huán)等。其次,請先玩一玩貪吃蛇這個游戲,如果沒有玩過,是不太容易理解其中的一些算法的。

當(dāng)然,也可以先學(xué)習(xí)一下第一趴 1小時開發(fā)2048,原來游戲如此簡單。

我能給您的保證就是,通過本文,您一定可以自己手動編碼一個貪吃蛇的游戲,如果不行,請在評論區(qū)轟炸我~

材料準(zhǔn)備

  1. 開發(fā)環(huán)境準(zhǔn)備
  2. 代碼基礎(chǔ)準(zhǔn)備
  3. 涉及到的樣式

1. 開發(fā)環(huán)境準(zhǔn)備

首先,您需要先有一臺電腦,如果是手機(jī)查看,就算了。。。然后,一個代碼編輯器,可以是記事本,也可以是IDEA。這里推薦使用visual studio code編輯器和chrome瀏覽器。至于visual studio code是啥,請自行百度了。
就是這么簡單,開發(fā)環(huán)境已經(jīng)準(zhǔn)備好了。

2. 代碼基礎(chǔ)準(zhǔn)備

  • 完全沒有基礎(chǔ)的同學(xué),可以先看看w3school關(guān)于html的教程、CSS的教程JS的教程。比較不是僅僅寫個hello world,還有需要有一丟丟基礎(chǔ)的。
  • 教程中,不是使用的原生js,而是基于Jquery進(jìn)行的編碼,使用了一些Jquery的語法,請參考:Jquery的教程

3. 涉及到的樣式說明

  • width 寬度

  • height 高度

  • background-color 設(shè)置背景顏色

  • float 浮動模式

  • .content 代表某個標(biāo)簽下class屬性為content,是一個css選擇器,以下是例子:

<div class="content"></div>

好了,我們開始進(jìn)入正題,進(jìn)入編碼環(huán)節(jié)

正式編碼,一共分為

  1. 頁面基礎(chǔ)框架編寫
  2. 樣式編寫
  3. 通過數(shù)組展示
  4. 向右移動第一顆
  5. 通過方向控制移動
  6. 多顆如何移動(第一種方法)
  7. 多顆如何移動(第二種方法)
  8. 隨機(jī)出現(xiàn)食物
  9. 吃到食物如何處理
  10. 解決隨機(jī)出現(xiàn)食物bug
  11. 判斷游戲失?。撼鲞吔?/li>
  12. 判斷游戲失敗:撞到自己
  13. 處理一些其他bug

1. 頁面基礎(chǔ)框架編寫

圖片 1

詳見上圖,這是一個最基礎(chǔ)的html代碼,分為三塊,頁面、css樣式、js邏輯,請參考圖中的注釋。直接瀏覽器打開本文件,即可看到效果。(可按F12,調(diào)出chrome的控制臺)
再次說明,html基礎(chǔ)標(biāo)簽和結(jié)構(gòu),請參考html的教程

2. 樣式編寫

圖片 2

我們設(shè)置整個幕布大小是400px * 400px,每個小塊是10 * 10,每行每列就是40個塊,一共1600個 。分別定義出蛇身體顏色黑色、蛇頭顏色紅色、食物顏色綠色。整體樣式設(shè)置較為交單,具體請參考代碼注釋,刷新運(yùn)行,查看效果。

3. 通過數(shù)組展示

3.1 思路

多說幾句,關(guān)于這個小標(biāo)題,通過數(shù)組展示,其實具有了編程思維的同學(xué),應(yīng)該很好理解,但是對于沒有基礎(chǔ)的同學(xué),就有點難了,先看這張圖:

圖片 3

游戲中貪吃蛇,就是一條蜿蜒的小蛇,沿著自己走過的路,一步一步往前挪動。我們理解其位在一個二維數(shù)組中,連續(xù)的一系列方格代表蛇。感覺自己沒說清楚,但是不理解也沒有關(guān)系,編程就是,編著編著就會了。先往下看。

3.2 老實孩子的寫法

之前通過樣式,我們已經(jīng)清楚了,我們一共是一個40*40,一共1600個格子的二維數(shù)組。先來直觀的感受下,有多少。

圖片 4

每一行40個0,一共40行,代碼冗余了,反正我是看不下去,所以簡化它。

3.3 通過循環(huán)來初始化

這里我們先定義了一個總的gameArr變量,用于存放所有塊,是一個二維數(shù)組。Array(40)代表生成了一個40位長度的數(shù)組。然后,我們遍歷這個數(shù)據(jù),目前這個數(shù)組還是一維的,里面所有元素都是null,所以,我們遍歷后,給每個遍歷值gameArr[i]又賦值A(chǔ)rray(40),然后再次遍歷,通過雙層遍歷,設(shè)置gameArr[i][j]等于0,就這樣,完成了數(shù)組的初始化。請看下圖代碼。

圖片 5
3.4 數(shù)組通過畫布來呈現(xiàn)

我們通過數(shù)組,在畫布上將1600個div呈現(xiàn)出來。雙層循環(huán)遍歷,仔細(xì)看代碼即可。通過瀏覽器,將鼠標(biāo)移動到對應(yīng)的代碼上,就可以看到頁面上對應(yīng)的div呈現(xiàn)出來。

圖片 6

現(xiàn)在,我們僅僅呈現(xiàn)了空白,那么其他值,我們也需要讓其呈現(xiàn)出來。

0代表沒有任何東西
1代表蛇的身子
2代表蛇頭
9代表食物
這些數(shù)值的含義,都是我們自己定義的而已,可以改為其他的。

通過判斷gameArr[i][j]的值,拼接不同的div。設(shè)置是設(shè)置好了,但是看不到效果呢。不著急,我們設(shè)置一些示例代碼即可。請看代碼:

圖片 7

然后我們分別設(shè)置幾個位置為1、2、9,刷新頁面,即可看到內(nèi)容呈現(xiàn)出來了。

圖片 8

4. 向右移動第一顆

4.1 重新初始化一下代碼

好了,準(zhǔn)備工作都做好了,現(xiàn)在開始有意思的了。首先我們僅設(shè)置1個蛇塊,其余的去掉。

首先,我們定義了一個snakeItem作為蛇身,初始化位置為第11行,第11列(js數(shù)組下標(biāo)是從0開始的),然后將對應(yīng)的gameArr的值,設(shè)置為1。snakeItem主要是用于表示蛇的坐標(biāo),用于計算。而gameArr是用于最終展示畫圖的。所以需要根據(jù)snakeItem修改gameArr對應(yīng)的值。刷新頁面后結(jié)果,請參考圖片。

圖片 9
4.2 添加定時任務(wù)

好了,現(xiàn)在,我們需要讓其動起來了。這里就不將原理了,設(shè)計異步、并行等概念,畢竟我們是實際編程例子,不講基礎(chǔ)(其實是我也說不清。。。)

涉及到JavaScript的定時執(zhí)行方法,setInterval,該方法涉及兩個參數(shù),第一個參數(shù)是需要執(zhí)行的方法,第二個參數(shù)是多久執(zhí)行一次,單位是毫秒。請參考下面的代碼

圖片 10

以上代碼,會不停的在控制臺打印出日志。

4.3 讓小方塊動起來

關(guān)鍵的來了,如何讓小方塊動起來呢,向右移動,其實就是snakeItem的列坐標(biāo)有之前的10,變?yōu)?1,定時任務(wù)中,就是不停的+1。剛剛說了snakeItem是用于計算的,修改了snakeItem后,還要更新gameArr,然后執(zhí)行drawGame,才能刷新游戲幕布。執(zhí)行效果如下:

圖片 11

呀,奇怪,動是動起來了,但是變長了,而不是往右移動。

原因是第11列,之前是1,現(xiàn)在12列變?yōu)?后,11列還是原來的值1,所以需要重新設(shè)置一下。所以在看代碼

圖片 12

這里的思路是:先清除畫布,然后變到下一個坐標(biāo),然后在按新坐標(biāo)畫上去。仔細(xì)看代碼注釋,您就能理解了。

好了,我們的第一個塊,終于動起來了,建議設(shè)置定時任務(wù)的值不要太小,否則你的瀏覽器會卡死,電腦風(fēng)扇會狂響。。。不要問我為什么知道的。

5. 通過方向控制移動

上面的代碼,我們已經(jīng)讓方塊動起來了,但是固定往右的,所以,我們需要加一個變量來代表方向,然后通過監(jiān)聽鍵盤事件,控制變量,而定時任務(wù)根據(jù)方向變量,來確定下一個出現(xiàn)的塊的位置。請看代碼:

5.1添加方向變量
圖片 13

方向變量的值,是可以任意定義的,我這里是用的鍵盤事件中,上下左右方向鍵所代表的值,方便對應(yīng)而已,你也可以用1,2,3,4來代表,對應(yīng)處理的地方,判斷處理即可。

5.2 添加鍵盤監(jiān)聽方法
圖片 14

這里定義了一個方法,里面添加了jQuery的鍵盤監(jiān)聽事件,我們僅處理上下左右鍵,所有,判斷等于37、38、39、40的值進(jìn)行賦值即可。

僅添加方法是不行的,沒有地方觸發(fā)調(diào)用,所以我們在啟動進(jìn)入方法里面,調(diào)用addListener

圖片 15
5.3 通過方向變量控制走向

先看下之前的代碼

gameArr[snakeItem[0]][snakeItem[1]] = 0 // 先將snakeItem位置置為0
snakeItem[1] += 1 // 再向右移動,其實就是列坐標(biāo)加1,
gameArr[snakeItem[0]][snakeItem[1]] = 1 // 最后設(shè)置新的位置為1

第一句和第三句,都是固定的,不需要變化,只有第二句,在方向改變的時候,需要調(diào)整。所以,看下面的代碼:

圖片 16

通過switch語句,判斷方向變量moveDirection的值,然后做出響應(yīng)。具體請看代碼注釋。

好了,大家可以刷新頁面,然后體驗一下根據(jù)方向鍵,小方塊移動了,如果速度比較慢,可以將定時任務(wù)的間隔值,調(diào)低一些,但是不建議小于100,否則會卡的。

6. 多顆如何移動(第一種方法)

我們先來說第一種移動的思路。每一塊,按順序往前移動,前是哪里,主要看方向變量。

我們先定義連續(xù)的三個塊,代表蛇的身體。

圖片 17

然后修改初始化方法,之前我們只畫了一個點,現(xiàn)在我們畫3個點。

圖片 18

最后,我們來處理移動。先看我第一步這樣寫。

圖片 19

先理解這里,我們默認(rèn)的是往右,所以我們先改39這個分支。
那么向右移動,按之前的思路先清除原先位置,然后所有塊向前走,最后再將新的塊畫上去。先看下效果。向右沒問題。那我們先按這樣的方式,將上下所有都填好。

圖片 20

向左、向右,挺好,但是向上向下,不對了。整體移動。

我們這樣寫是有問題的,其實思路上,不應(yīng)該世界按方向加,而是只有第一個頭,按方向加,其余的應(yīng)該往前覆蓋。
將snakeItem1的坐標(biāo)給snakeItem2
將snakeItem2的坐標(biāo)給snakeItem3
將snakeItem3的坐標(biāo)清空
然后snakeItem1設(shè)置為下一個坐標(biāo)

看代碼:

圖片 21

仔細(xì)理解下代碼,思考,為什么先2賦值給3,再1賦值給2。
而不是我們上面說的,先1賦值給2,再2賦值給3。應(yīng)該比較好理解的??梢宰约赫{(diào)下順序。

這里再說下,不能直接snakeItem3 = snakeItem2,這樣是引用賦值了,最后三個都指向一個變量了。大家也可以調(diào)下代碼試試。

好了,現(xiàn)在第一個思路基本將清楚了,解決最后一個問題,這是三個,如何變成多個呢。這里就不能固定寫snakeItem1,snakeItem2,snakeItem3了。要用數(shù)組來表示??聪旅娴拇a:

首先修改為數(shù)組:

圖片 22

然后,初始化幾個蛇身子坐標(biāo)

圖片 23

修改移動里面方法的處理,也改為數(shù)組的方式

圖片 24

其實代碼里面的注釋已經(jīng)很清晰了,請多多理解。注意里面第二塊,迭代,要從倒數(shù)第二個開始后移。多多思考思考。

刷洗下頁面,看看效果吧。

圖片 25

也可以自己改改蛇的長度,這個數(shù)組及后續(xù)的算法,就可以支持任意長度了。

第一個算法介紹完畢,建議多寫幾遍,熟練貫通。

7. 多顆如何移動(第二種方法)

第一種方法,是所有的塊都在往前移動。第二種方式,我們換個思路:
首先有三個塊,位置是1,2,3。現(xiàn)在要變?yōu)椋?,3,4,看前來是不是第一個思路的,2->1,3->2,4是下一個,4->3。

但是,我們觀察,首先所有的塊都是小黑塊,1,2,3在頁面上除了位置,其他都一樣,那我們換一個思路,將1位置刪除掉,數(shù)組變成了2,3,再在最前面添加一個4。是不是就行了呢。說起來不是特別清楚,我們直接上代碼吧:(以后重新編寫的時候,應(yīng)該會上一些圖來幫助理解)

圖片 26

第一,即以當(dāng)前蛇的第一塊為主,根據(jù)方向,生成下一個塊。
第二,將新生成的下一個塊,添加到蛇數(shù)組的最前面,作為蛇頭。
第三,將蛇數(shù)組的最后一塊去掉,記得清空游戲幕布的值。

好了,第二個方法完成。第二種方法,移動量比較少,只涉及到新增的下一個塊和最后一個塊。這樣蛇不管有多長,計算量都是固定的。而第一種方法,每一個塊都要移動。新多看幾遍,琢磨琢磨。

這里我們的蛇頭都沒有寫,修改下代碼,看看效果:

圖片 27

第一步修改下初始化位置的代碼

圖片 28

其次修改新增的蛇頭的代碼。要注意,新增的蛇頭設(shè)置為2,之前老的蛇頭要設(shè)置為1喲。要不蛇頭越來越長,你可以試試看看。

8. 隨機(jī)出現(xiàn)食物

開始寫食物了,隨機(jī),Math.random()會生成一個0到1之間的一個隨機(jī)浮點小數(shù)。

圖片 29

先添加一個全局的食物坐標(biāo)存儲的變量,一個數(shù)組,用于表示食物在幕布上的位置。

圖片 30

然后隨機(jī)生成兩個0到39的整數(shù),賦值給foodItem,設(shè)置上幕布在該坐標(biāo)的值為9,下面判斷了,9的值的位置,會顯示綠色。

好了現(xiàn)在加好方法了,在哪里觸發(fā)呢?

1,在初始化后,就觸發(fā)一次
2,在吃到這個食物的時候觸發(fā)

我們先來在初始化的位置,調(diào)用該方法:

圖片 31

刷新頁面后,已經(jīng)可以看到了,現(xiàn)在你可以控制方向,將蛇引導(dǎo)過去。但是碰得到卻吃不掉。

9. 吃到食物如何處理

這里,我們僅基于第二種移動算法來進(jìn)行處理喲。為什么呢?因為我把第一種算法的代碼刪掉了。。。所以,第一種算法的同學(xué),自己寫吧。

還是一樣,先說下思路,如何判斷吃到食物:
第一:就是蛇身新增的下一個塊,如果坐標(biāo)和食物重合,其實就是吃到了食物。
第二:然后貪吃蛇會怎么樣呀,對了,對變長。其實就是長度+1。換句話說,就是不需要丟掉尾巴。
第三:最后,重新隨機(jī)食物。
話不多說,看代碼 :

圖片 32

注釋寫得很清楚拉,刷新后,可以試試玩玩啦,我們貪吃蛇已經(jīng)初具樣子了。

10. 解決隨機(jī)出現(xiàn)食物bug

是什么bug呢,其實就是隨機(jī)的時候,有可能隨機(jī)到蛇身體上,這樣就不對了。做下判斷處理即可,看代碼:

圖片 33

11. 判斷游戲失敗:出邊界

游戲已經(jīng)可以玩了,但是跑到邊框,就報錯,這樣不對。我們要判斷游戲結(jié)束:出邊界。如何判斷呢,其實就是新生成的蛇頭,坐標(biāo)超出了邊看范圍。即行坐標(biāo)大于39,小于0,列坐標(biāo)大于39,小于0,都是出界了。所以,看代碼:

圖片 34

注意,這段代碼的位置,在新坐標(biāo)出來后,就直接可以判斷了。

12. 判斷游戲失?。鹤驳阶约?/h2>

一樣的道理,新生成的塊,同自己所有的塊進(jìn)行下比較,看代碼:

圖片 35

13. 處理一些其他bug

第一個bug

現(xiàn)在失敗后,你試試點擊彈出框的確定按鈕,發(fā)現(xiàn)會一直彈框。是因為我們的這個定時任務(wù)會一直不停的繼續(xù)請求。我們需要加一個變量來控制游戲結(jié)束,結(jié)束后就不要再觸發(fā)了。

圖片 36
圖片 37
圖片 38

查看上面三塊代碼,看看注釋,主要注意最后不要缺少一個“}”符號。代碼比較長,就沒有一起截圖了。

好了現(xiàn)在再試試,結(jié)束后,就不會一直彈出來了。

第二個bug

現(xiàn)在正在向右移動的貪吃蛇,可以直接向左返回,而且會直接死掉。。。所以我們要限制一下,向右走的,不能向左走,只能上下。其他方向依次類推。看代碼注釋吧:

圖片 39

好了,到這里為止,我們的整個基礎(chǔ)版的貪吃蛇就開發(fā)好了,可以自己玩一玩,畢竟是自己的開發(fā)成果呢。小有成就感是吧。

這是一個基礎(chǔ)版的貪吃蛇,大家可以自己完后完善,包括積分、時間、速度快慢、游戲模式:多個食物、穿墻、障礙等等。以后我會更新高級版本的實例教程,敬請期待~~

謝謝大家耐心看完本教程,如果覺得還不錯,請點個贊,幫忙轉(zhuǎn)發(fā)一下,謝謝~~

歡迎各位留言~~原創(chuàng)不易,也請大家多多轉(zhuǎn)發(fā),將這么好的教程讓更多人看到。后續(xù)將推出更多其他詳細(xì)案例講解。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容