2015-11-07 93 views
1

請問,我正在關注如何製作蛇遊戲的教程,並且我理解了代碼中的所有內容,直到蛇運動到哪裏。我似乎沒有得到蛇如何移動的邏輯。代碼片段如下:蛇遊戲中的蛇運動

. . . //the code block to setup the canvas and other basic stuff for the game 
//creating the snake 
var snake_array; //an array of cells to make up the snake 
function create_snake(){ 
    var length = 5; //length of the snake 
    snake_array = [] //starting with an empty array 
    for (var i = 0; i < length; i++) { 
     //this will create a horizontal snake starting from top left 
     snake_array.push({x:i,y:0}); 
    } 
} 

create_snake() // invoking the method 

//painting the snake 
function paint(){ 

    . . . // code block to clear the trail of the snake on the canvas before the snake moves 

    var nx = snake_array[0].x; 
    var ny = snake_array[0].y; 
    if(d == "right") nx++; //d is a variable updated by the keydown event listener code(not shown here) 
    else if(d == "left") nx--; 
    if(d == "up") ny--; 
    if(d == "down") ny++; 

    var tail = snake_array.pop(); // pops out the last cell 
    tail.x = nx; 
    tail.y = ny; 
    snake_array.unshift(tail) 

    . . . // code block to paint the snake cells 

    } 
} 

paint() // invoking the method 

我的問題是:如何做的代碼我上面列出做推進蛇,因爲當我試圖用我的瀏覽器控制檯的代碼之後,調用create_snake()後的工作部分,我有五個對象(它們代表蛇細胞)的陣列,它們具有以下屬性和值:{x:0,y:0}{x:1,y:0},{x:2,y:0},{x:3,y:0},{x:4,y:0}。調用paint方法後,我仍然有五個對象的數組,但具有以下屬性和值:{x:1,y:0},{x:0,y:0},{x:1,y:0},{x:2,y:0},{x:3,y:0}。那麼當d = "right"時,蛇如何向前移動,因爲調用paint()後蛇的最後一個單元格的x屬性/座標在調用該方法之前比其原始值小1,並且同時兩個單元格現在重疊,因爲兩個對象在在snake_array現在具有相同的座標({x:1,y:0}

回答

0

相關的代碼發起這樣的:

var snake_array; 
function create_snake(){ 
    var length = 5; 
    snake_array = []; 
    for(var i = length-1; i>=0; i--){ 
     snake_array.push({x: i, y:0}); 
    } 
} 

注意到這段代碼最重要的是,它向後產生的蛇,所以它看起來像這個:{x:4,y:0},{x:3,y:0},{x:2:,y:0},{x:1,y:0},{x:0,y:0}。這是因爲i開始於length-1length在for循環之上設置爲5。這看起來像:

[T][x][x][x][H][ ] 
[ ][ ][ ][ ][ ][ ] 
[ ][ ][ ][ ][ ][ ] 
[ ][ ][ ][ ][ ][ ] 

然後,在塗料的功能它抓住尾巴的位置,它打算尾巴舉至頭頂大約是位置(做這種方式,它不需要移動任何其它小區的,直到下一個油漆,如那些永遠不會改變作爲蛇不會移動超過每循環單細胞更。)

var nx = snake_array[0].x; 
    var ny = snake_array[0].y; 
    if(d == "right") nx++; 
    else if(d == "left") nx--; 
    else if(d == "up") ny--; 
    else if(d == "down") ny++; 

蛇的尾部是總是的最後一個元素在該方案下的陣列中,頭部總是第一個。所以,snake_array [snake_array.length]總是尾巴,而snake_array [0]總是頭部。

記住{x:4,y:0}{x:3,y:0}{x:2:,y:0}{x:1,y:0}{x:0,y:0},並假設我們的默認運動是正確的,我們可以計算出{nx:5,ny:0}。 nx和ny現在代表一個不是蛇的一部分的細胞,而是蛇想要移入的細胞。因此,代碼會在該單元格上進行一些界限和碰撞檢查,以查看它是否與任何牆或其他蛇段相交,並且如果這樣做會重新啓動遊戲。

它還檢查食物碰撞並處理它(而不是移動尾巴,它只是在細胞位置創建一個新的頭部並生成另一片食物。)

但是,假設該小區(NX,NY)的位置不與任何碰撞,運行這段代碼:

var tail = snake_array.pop(); 
    tail.x = nx; tail.y = ny; 

從而消除來自snake_array尾巴,將它的位置的位置我們計算出的較早(NX,NY),然後細胞轉移這個「尾巴」到陣列的第一位置(其總是頭,由我們的從以前的約定):

snake_array.unshift(tail); 

所以它最終像這個:

[ ][x][x][x][H][T] 
[ ][ ][ ][ ][ ][ ] 
[ ][ ][ ][ ][ ][ ] 
[ ][ ][ ][ ][ ][ ] 

但實際上,該數組仍然是[H] [X] [X] [X] [T]的形式,因爲我們決定了snake_array [0]的第一個元素位置是頭部, snake_array [snare_array.length]的最後一個元素位置的任何內容都是尾部。所以它的確是:

[ ][T][x][x][x][H] 
[ ][ ][ ][ ][ ][ ] 
[ ][ ][ ][ ][ ][ ] 
[ ][ ][ ][ ][ ][ ] 

然後整個過程可以一遍又一遍地重複,直到你輸或贏!

+0

如果有重疊,那麼你可以申請嗎?那麼應該有3個蛇細胞在畫布上,而不是4,因爲兩個細胞將被繪製在x,y座標的相同位置。 – Ayo

+0

實際上,我誤解了一下代碼,給我一分鐘來修復我的答案。 – jconder

+0

感謝您的回答,也讓我們明白了一點東西,但是從你的答案,新的統籌不應be' {X:5,Y:0} {但X:1,Y:0}'因爲從代碼我在上面貼上了'nx = snake_array [0] .x'這個'0'的問題,如果我們假設蛇正在朝着正確的方向移動,代碼中的'nx ++'運行,'nx'變成'1' '然後我們'彈出'蛇的頭部並將其返回到陣列中,使它的座標等於'nx'和'ny'的座標。 – Ayo