20行code實現貪吃蛇功能

2021-08-03 07:09:49 字數 3928 閱讀 6934

看到一位大神用20行**就寫出了乙個貪吃蛇的小遊戲,感覺被驚豔到了,就試著讀了一下這段**,閱讀過程中不斷為作者寫法的巧妙而叫絕,其中我發現自己對運算子優先順序和一些js的技巧不是很清楚,所以看完之後決定把思路分享出來,方便和我一樣的小白學習。

我對**稍稍做了些修改,並新增了一些注釋,方便理解。

lang="en">

charset="utf-8">    貪吃蛇重構title>    

body    

style>

head>

id="can"

width="400"

height="400"

style="background-color: black">對不起,您的瀏覽器不支援canvascanvas>    

var snake = [41, 40],

//snake佇列表示蛇身,初始節點存在但不顯示

direction = 1,      

//1表示向右,-1表示向左,20表示向下,-20表示向上

food = 43,          

//食物的位置

n,                  

//與下次移動的位置有關

box = document.getelementbyid('can').getcontext('2d');                                    

//從0到399表示box裡[0~19]*[0~19]的所有節點,每20px乙個節點

function

draw(seat, color)        

document.onkeydown = function(evt) ;

!function()

draw(n, "lime");    

//畫出蛇頭下次出現的位置

if(n == food) else

settimeout(arguments.callee, 150);      

//每隔0.15秒執行函式一次,可以調節蛇的速度

}();    

script>

body>

html>

首先,我們要知道做乙個貪吃蛇最主要的是什麼,是做出蛇活動的場所和如何使蛇動起來。

我們先看蛇活動的場所:

id="can"

width="400"

height="400"

style="background-color: black">

對不起,您的瀏覽器不支援canvas

canvas>

box = document.getelementbyid('can').getcontext('2d');

這是乙個400px*400pxcanvas,思路是以20px*20px為乙個方格,組成2020列的方陣,總共400格,然後綠色填充的格仔表示蛇身,用黃色表示食物。這400個格仔和數字0~399一一對應,對應的方式就是以20作為基數,n / 20再取整表示第幾行,n % 20表示第幾列。行數和列數都用0~19表示。

蛇用乙個一維陣列表示,每個值都是這400個數中的乙個,用var snake = [41, 40];初始化這條蛇,索引0為蛇頭。food表示食物的位置,direction表示蛇頭下一次運動的轉向。蛇的運動就用新增和刪除陣列元素來實現,每次執行繪製蛇頭,去掉蛇尾,迴圈執行使蛇運動。

下邊從函式執行的起始處開始看:

!function() {}();

什麼鬼?這其實是立即執行函式

iife的另一種寫法。繼續往下看,給蛇頭新增乙個節點n,其值為當前蛇頭的值加direction的值,如此一來就能理解為什麼要用20表示向下,-20表示向上了。

再下一行是乙個if語句,其中值得提醒的是&&的優先順序高於||,這個語句就是判斷即將出現的蛇頭是不是屬於蛇身,或者跑到box外邊去了。如果沒有死亡,就把這個蛇頭繪製出來,下邊就看看繪製的**:

function draw(seat, color) 

填充時填充18*18的畫素,留1px邊框。.fillrect()中第乙個引數就是要繪製的矩形的x座標seat % 20 *20 + 1,即先得到所要繪製的矩形塊在方陣中的位置:第~~(seat / 20)行,第seat % 20列,再* 20 + 1具體到畫素點。

可能這個~~有點難理解,我感覺在這裡的用處應該和math.floor()差不多,對乙個浮點型的數取反再取反,得到的數就是去掉小數字的整數了。

回到前面,又是乙個判斷語句,判斷下次蛇頭出現的位置是不是和當前的食物的位置相同,如果相同,生成下乙個食物,食物的位置為乙個隨機數,但是要判斷這個點不是出現在當前的蛇身上,繪製食物。

如果沒有吃到食物,即蛇在正常運動時,每向前一次,將蛇尾彈出,並利用其返回值將這個點重新繪製為黑色。

最後的settimeout,迴圈執行當前函式,設定執行週期來調蛇的移動速度。

到了這裡,我們發現這條蛇已經可以動了,加上鍵盤的操作就完成了:

document.onkeydown = function(evt) ;

將這個函式繫結到鍵盤事件上,evt || event用法的原因這裡有詳細的解釋,是為了相容

ie

三目運算子?前邊的判斷語句又可分為兩部分:

snake[1] - snake[0]的值應該就是-direction,按理說此處寫成-direction應該和原來是乙個效果,那為什麼沒有這麼做呢,因為如果這樣寫,玩家可能在乙個函式週期中多次改變direction的值,最後使得direction和當前真正的運動方向不一致,導致遊戲崩潰。

==後邊,[-1, -20, 1, 20][(evt || event).keycode - 37]中前邊的是乙個陣列,後邊的是取索引,左上右下四個鍵的keycode分別為37, 38, 39, 40,計算後的索引為0, 1, 2, 3,使方向鍵與direction的取值對應起來。這裡的巧妙之處在於如果按下的按鍵不是方向鍵,在陣列中將得不到對應的值,返回undefine。此時,由於之後的||運算子,n會取到direction原來的值。

再用三目運算子來判斷,如果按鍵方向不是反方向,就更新direction的值。

以上雖然都是一些基礎的東西,但是感覺還是挺好玩的。要是**理解的不對還希望指證出來,共同進步。

C 貪吃蛇200行以內實現完整功能

include include include include include using namespace std define size 22 define max snake length 400 typedef structpoint char map size size point sn...

實現貪吃蛇

貪吃蛇 1.它的移動我們採用頭部加乙個尾巴減乙個 2.我們將view的大小分成很多個格仔 3.蛇的移動是以乙個格仔為單位 created by administrator on 2016 10 11.public class gameview extends view public gameview...

c 實現貪吃蛇

include include include include include include include include include word square color 7 義方向 define key up 72 define key down 80 define key left 75...