一個簡單的“貪吃蛇”小游戲
微信公眾號:migufe
分享人:鄭漲
頁面結構

簡單的21x21的方塊,頁面結構

id為container的div包含所21個class名為row的div,每個row代表貪吃蛇的一整行,每個row中又包含21個div,代表這一行的每一個div方格,如果這個方格是空的話,div的類名為blank,如果這一個方格表示“貪吃蛇”的“食物”,div的類名為food,如果這一個方格表示“蛇”,div的類名為snake。
CSS

JS
然后我們思考下一個貪吃蛇游戲需要那些參數,
首先,界面中可見的元素無非就是空方格,“蛇”還有“食物”,所以需要一個二維數組,用來表示每個方格的狀態0表示方格為空,1表示方格為“食物”,2表示方格為“蛇”,然后是一個數組,存放“蛇”在方格中所占位子的坐標,再然后是一個存放“食物坐標”,由於需要確定“蛇”移動的方向,所以需要個存放方向的變量,還需要一個定時器,控制蛇每秒鍾的移動,最后是需要統計用戶的得分,所以有

我們需要創建游戲界面,所以在Game中添加函數createDOM,根據我們上文所說的頁面結構,我們有

有了createDOM之后,在Game初始化的時候調用,初始化函數名為init
所以有

首先調用上文的createDOM方法生成頁面
然后初始化data,data為一個長度21的二維數組,二維數組的每一個子元素又是一個數組,數組中的每個元素值都為0,
然后初始化蛇的坐標,這里默認為方格的9,10,11行的第10列,
然后是遍歷snake數組,講snake數組中每個元素表示的data中的位置的值改為2,即在data中表示蛇的位置,
接着需要生成食物的坐標,由於之后還要多次生成食物坐標,所以寫了一個create_food方法,方便之后調用,
蛇的初始移動方向默認為“上”,
如果是用戶第二次開始,先清除上一次游戲設置的定時器
初始化玩家得分為0
調用key_action方法,設置鍵盤事件,控制蛇的移動方向
然后是調用display方法,刷新游戲頁面
create_food方法

先隨機生成一個x,y的坐標,由於“食物”的生成位置只能在空位置,即data中值為0的位置,所以如果data[x][y]的值不為0的話,一直重新生成,直到生成的位置為空,將生成位置對應data中的值改為1,
key_action方法

讀取鍵盤事件,並根據情況設置“貪吃蛇”的移動方向,
display方法

遍歷data二維數組,數組中的值0,1,2對應空,“食物”,“蛇”,講頁面中所對應的標簽的類名分別改寫為“blank”,“food”,“snake”,
最為關鍵的是需要讓蛇能動起來,我們寫了一個snake_move方法,
思考一波,比如說snake現在的元素有[{x:9,y:10},{x:10,y:10},{x:11,y:10}],當前的direction的值是“up”向上移動,所以下一個狀態的snake的元素應該是[{x:8,y:10},{x:9,y:10},{x:10,y:10}],也就是說,原來的snake將最后一個元素{x:11,y:10}舍棄,然后根據direction的值,計算出一個新的坐標,並snake數組的頭部加入
所以有

last變量存放原來snake數組的最后一個元素,obj存放下一個時刻的snake頭部的元素
如果direction的值為“up”那么下一個時刻snake頭部元素,應該為原來的snake首個元素snake[0]的x值減1,snake[0]的y值不變,
direction為其他值的時候類推
但這樣還不夠,貪吃蛇存在碰到“牆壁”或者碰到“蛇”自己身體的情況,
還是拿direction的值為“up”類比,當原snake[0]的x值為0的時候,即已經到達了游戲框的頂部,如果繼續向上移動,那么下一個x值應該為-1,顯然是不合理的,所以有

還有“蛇”撞到自己身體的情況,上面說到obj存放的是下一個時刻snake頭部的坐標,如果在data數組中所對應位置的值為2即“蛇”的身體,表示“蛇”撞到了自己的身體
所以有

上面說到obj存放的是下一個時刻snake頭部的坐標,但是實際上snake這個數組並沒有被重新賦值,所以我們還需要一個add_snake方法,每次數組變化的時候更新snake數組

並在snake_move中調用,調用后結果改變了snake數組變味了下一個狀態,但是這個時候data數組所表示的原來的snake數組的最后一個元素,應該為空(蛇移動之后,尾部重新變為空)所以我們將之前保存下來的原snake的最后一個元素在data中對應的值變為0,

最后重新遍歷新生成的snake數組,講snake數組在data數組所對應的位置的值設為2

完整的snake_move方法

最后需要一個start方法,設置一個定時器,不斷調用snake_move方法讓蛇移動

在init的末尾調用start方法,大功告成
最后Game.init();初始化游戲,試玩下

微信公眾號:migufe
