蛇游戏中的蛇运动

时间:2015-11-07 10:12:30

标签: javascript logic game-physics

拜托,我正在学习如何制作蛇游戏的教程,我了解了代码的所有内容,直到蛇必须移动的地方。我似乎没有得到蛇如何移动的逻辑。代码段如下所示:

. . . //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},{{1} }。现在,当{x:3,y:0}之后蛇是如何向前移动的,因为在调用d = "right"之后蛇的最后一个单元格的x属性/坐标比调用方法之前的原始值小1,并且再次,两个单元格现在重叠,因为snake_array中的两个对象现在具有相同的坐标(paint()

1 个答案:

答案 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},{ {1}}。这是因为{x:0,y:0}i开始,length-1设置为高于for循环的5。这看起来像:

length

然后,在绘画功能中它抓住尾巴位置,因为它打算将尾巴移动到头部即将到达的位置(通过这样做,它不需要移动任何其他的细胞直到下一次涂抹,因为蛇永远不会改变,因为每个循环的蛇从不会移动超过一个细胞。)

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

蛇的尾部总是此方案下数组中的最后一个元素,并且头部始终是第一个。所以,snake_array [snake_array.length]总是尾巴,而snake_array [0]始终是头部。

记住 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++; {x:4,y:0}{x:3,y:0}{x:2:,y:0}{x:1,y:0},并假设我们的默认动作是正确的,我们可以计算{{1} }。 nx和ny现在代表的是一个不属于蛇的细胞,而是蛇想进入的细胞。因此代码对该单元格进行一些边界和碰撞检查,以查看它是否与任何墙壁或其他蛇段相交,如果是,则重新启动游戏。

它还检查食物碰撞并处理它(而不是移动尾巴,它只是在细胞位置创建一个新头并产生另一块食物。)

但是,假设这个单元格(nx,ny)位置没有与任何东西发生碰撞,它会运行以下代码:

{x:0,y:0}

从snake_array中删除尾部,将其位置设置为我们之前计算的单元格的位置(nx,ny),然后将其移动到尾部&#39;进入数组的第一个位置(根据我们之前的惯例,它始终是头部):

{nx:5,ny:0}

所以最终会这样:

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

但实际上,数组仍然是[H] [x] [x] [x] [T]的形式,因为我们决定了snake_array [0]的第一个元素位置中的任何东西都是头部,而且任何东西都在snake_array [snare_array.length]的最后一个元素位置是尾部。所以它确实如此:

    snake_array.unshift(tail);

然后整个过程可以一遍又一遍地重复,直到你赢或输!