简体   繁体   English

蛇游戏中的蛇运动

[英]Snake movement in snake game

Please, I was following a tutorial on how to make a snake game and I understood everything about the code up until the where the snake has to move.拜托,我正在学习如何制作蛇游戏的教程,并且我了解有关代码的所有内容,直到蛇必须移动的位置。 I just don't seem to get the logic of how the snake is moving.我只是似乎不明白蛇是如何移动的逻辑。 The code snippet is shown below:代码片段如下所示:

. . . //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

My problem is: How does portion of code I outlined above do the work of advancing the snake because when I tried following the code with my browser console, after the call to create_snake() , I have an array of five objects(which represent the snake cells) which have the following property and values : {x:0,y:0} , {x:1,y:0} , {x:2,y:0} , {x:3,y:0} , {x:4,y:0} .我的问题是:我上面概述的部分代码如何完成推进蛇的工作,因为当我尝试使用浏览器控制台跟踪代码时,在调用create_snake() ,我有一个包含五个对象的数组(它们代表蛇细胞)具有以下属性和值: {x:0,y:0} , {x:1,y:0} , {x:2,y:0} , {x:3,y:0} , {x:4,y:0} After invoking the paint method, I still have an array of five objects but with the following property and values : {x:1,y:0} , {x:0,y:0} , {x:1,y:0} , {x:2,y:0} , {x:3,y:0} .调用paint方法后,我仍然有一个包含五个对象的数组,但具有以下属性和值: {x:1,y:0} , {x:0,y:0} , {x:1,y:0} , {x:2,y:0} , {x:3,y:0} Now how does the snake move forward when d = "right" since the x property/co-ordinate of the last cell of the snake after calling paint() is 1 less than its original value before calling the method, and again, two cells now overlap since two objects in the snake_array now have the same co-ordinate( {x:1,y:0} )现在当d = "right"时,蛇如何向前移动,因为调用paint()后蛇的最后一个单元格的x 属性/坐标比调用该方法之前的原始值小1,同样,两个单元格现在重叠,因为蛇阵列中的两个对象现在具有相同的坐标( {x:1,y:0}

The relevant code initiates like this:相关代码是这样启动的:

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});
    }
}

The important thing to notice about this code is that it generates the snake backwards, so it looks like this: {x:4,y:0} , {x:3,y:0} , {x:2:,y:0} , {x:1,y:0} , {x:0,y:0} .这段代码需要注意的重要一点是它向后生成了蛇,所以它看起来像这样: {x:4,y:0} , {x:3,y:0} , {x:2:,y:0} , {x:1,y:0} , {x:0,y:0} That is because i starts at length-1 and length is set to 5 up above the for loop.那是因为ilength-1开始,并且length在 for 循环上方设置为 5。 This looks like:这看起来像:

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

Then, in the paint function it grabs the tails position as it intends to move the tail to the position the head is about to be (by doing it this way, it doesn't need to move any of the other cells until the next paint, as those will never change as the snake never moves more than a single cell per cycle.)然后,在绘制函数中,它抓取尾部位置,因为它打算将尾部移动到头部即将到达的位置(通过这样做,它不需要移动任何其他单元格,直到下一次绘制,因为这些永远不会改变,因为蛇每个周期移动的细胞永远不会超过一个细胞。)

    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++;

The tail of the snake is always the last element in the array under this scheme, and the head is always the first .在这个方案下,蛇的尾巴总是数组中的最后一个元素,头总是第一个 So, snake_array[snake_array.length] is ALWAYS the tail, and snake_array[0] is ALWAYS the head.所以,snake_array[snake_array.length] 始终是尾部,而 snake_array[0] 始终是头部。

Remembering {x:4,y:0} , {x:3,y:0} , {x:2:,y:0} , {x:1,y:0} , {x:0,y:0} , and assuming that our default movement is right, we can calculate {nx:5,ny: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 and ny now represent a cell that is not part of the snake, but the cell the snake wants to move into. nx 和 ny 现在代表一个不属于蛇的单元格,而是蛇想要进入的单元格。 So the code does some bounds and collision checking on that cell to see if it intersects with any wall or other snake segments, and if it does it restarts the game.因此,代码对该单元格进行了一些边界和碰撞检查,以查看它是否与任何墙壁或其他蛇段相交,如果相交,则重新启动游戏。

It also checks for food collision and handles that (instead of moving the tail, it just creates a new head at the cell position and generates another piece of food.)它还检查食物碰撞并处理它(而不是移动尾部,它只是在单元格位置创建一个新的头部并生成另一块食物。)

But, assuming this cell (nx,ny) position is not colliding with anything, it runs this code:但是,假设这个单元格 (nx,ny) 位置没有与任何东西发生碰撞,它会运行以下代码:

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

Which removes the tail from the snake_array, sets its position to the position of the cell that we calculated earlier (nx,ny) and then shifts this 'tail' into the first position of the array (which is always the head, by our convention from earlier):从snake_array中删除尾部,将其位置设置为我们之前计算的单元格的位置(nx,ny),然后将此“尾部”移动到数组的第一个位置(根据我们的约定,它始终是头部)从之前):

    snake_array.unshift(tail);

So it ends up like this:所以它最终是这样的:

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

But really, the array still is in the form of [H][x][x][x][T] because we decided anything in the first element position of snake_array[0] was the head, and anything in the last element position of snake_array[snare_array.length] was the tail.但实际上,数组仍然是 [H][x][x][x][T] 的形式,因为我们决定蛇数组 [0] 的第一个元素位置的任何东西都是头,最后一个元素的任何东西snake_array[snare_array.length] 的位置是尾巴。 So it's really:所以它真的是:

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

And then the whole process can repeat again over and over until you win or lose!然后整个过程可以一遍又一遍地重复,直到你赢或输!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM