2015-11-07 92 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