Snake游戏算法不使用网格,并且片段的移动速度可能比其尺寸慢

Dan*_*lan 5 javascript algorithm canvas coffeescript

我正在努力做到这个人正在做的事情,但我认为他的要求可能比我少,因为那篇文章中的答案似乎并不适合我的游戏.让我内联他的算法让我的问题更容易理解:

最简单的解决方案是从尾部到头部循环,并将当前位置设置为下一个部分的位置,即: segment[i].position = segment[i - 1].position

我认为我们的要求之间的关键区别是我想在每个刻度上移动每个部分小于它自己的宽度/高度.例如:

在此输入图像描述

假装这些正方形是水平对齐的(我把它画成未对齐的,因为我认为这样可以更容易地看到正在发生的事情).红色H是头部的当前位置.红色T是尾巴当前的位置.黑色H'是下一个头部的位置.所以蛇从右到左移动.如果我使用上述算法,这些段是否会重叠或开始分开?让我一步一步地演绎出来:

  1. 创造H'.position
  2. T.position = H.position
  3. H.position = H'.position

结果将成为:

在此输入图像描述

我可以使用什么算法来确保所有碎片以相同的速度移动并保持彼此相同的距离?


我会提出我的想法,但我对此持怀疑态度,因为我的研究没有显示其他人使用此信息:

每个段将存储它的坐标和方向.EG : [[50, 50, LEFT], [100, 50, LEFT]]. 头部是索引0,尾部是索引1. 蛇移动的速度是10,即使段是50x50.

每个刻度我都会这样做:

  1. 如果按下鼠标,则用按下nextDirection的方向覆盖变量.否则,nextDirection是最后一次滴答.在这个例子中,让我们假设有人按下了UP.
  2. 迭代数组并将方向应用于每个tick.例如:[[40, 50, LEFT], [90, 50, LEFT]]
  3. 将方向从头部移动到尾部并将头部的新方向设置为nextDireciton.例如:[[40, 50, UP], [90, 50, LEFT]]
  4. 重复每一个滴答.

这个算法看起来好像有效吗?我问的部分原因是因为它比其他人的算法更复杂,所以我觉得我做错了.而且,我对他的算法的思考越多,它看起来就越少.


重写我的问题

假装蛇的每个部分是一个20x20像素的矩形.每个刻度,我希望头部在某个方向上移动5个像素. 如何确保所有段保持相互接触?

@ Rafe在评论中的描述如下:

考虑蛇在步骤中占据的有序位置集,t最左边是尾部,最右边是头部:{A, B, C, D, E}.在步骤中t+1,蛇所占据的有序位置集是{B, C, D, E, F}尾部从哪里移动AB头部已经移动E到的位置F.

我不认为这个算法有效,因为:

是的,但如果宽度A = B = C = D = E = F = 20px.移动{A, B, C, D, E}使其{B, C, D, E, F}刚刚向右侧添加20px并从左侧移除20px.这是不是意味着他移动了20px,而不是5px? 我想移动5px,而不是20px 如果你说你的建议完成了,请解释如何.我没有看到它.

Joh*_*ohn 3

我知道你忽略了网格,但是如何使蛇向前移动的距离均匀地影响你的大块大小呢?

假设您仅向前移动了区块宽度/高度的一半。

现在您可以进行一些优化。

  • 启动一个计数器 ,n在整个游戏中运行。
  • 显示组成蛇 ( ) 的块n = 0。我们就这样称呼吧snake_even
  • 下一步 ( n = 1),通过将它们全部向前移动 1/2 个单位来创建构成下一条蛇的块。我们就这样称呼吧snake_odd
  • 对于所有后续移动,您显示 或snake-evensnake_odd但您可以通过将头部更改为新位置并覆盖尾部来创建snake_even(n+2)fromsnake_even(n)snake_odd(n+2)from 。snake_odd(n)
  • 每当蛇吃东西时,将长度加到snake_xxxx你所在的那条蛇上,然后将长度加到另一条蛇上。

如果您只想向前移动 1/5 高度,您会做同样的事情,但您需要跟踪五个数组,而不是两个。

基于您添加的示例的其他信息(20x20 像素段每步移动 5 像素):

拿一条向右移动的 4 段蛇。线段大小为 20x20 像素,每次移动移动 5 像素。我将把蛇定义为坐标列表(x, y)。我将用“H”标记头部,蛇将在列表中向右移动,如果需要则循环回到开头。

// n = 0
snake_0 => H(60, 0), (40, 0), (20, 0), (0, 0)

// Snake is moving to the right.
// n = 1 -- construct snake_1 from snake_0 and display that one (n % 4 = 1)
snake_1 => H(65, 0), (45, 0), (25, 0), (5, 0)

// n = 2 -- construct snake_2 from snake_1 and display that one (n % 4 = 2)
snake_2 => H(70, 0), (50, 0), (30, 0), (10, 0)

// n = 3 -- construct snake_3 from snake_2 and display that one (n % 4 = 3)
snake_3 => H(75, 0), (55, 0), (35, 0), (15, 0)

// n = 4 -- Now just move the head, and re-use all but the tail of snake_0
snake_0 => (60, 0), (40, 0), (20, 0), H(80, 0)

// n = 5
snake_1 => (65, 0), (45, 0), (25, 0), H(85, 0)

// n = 6
snake_2 => (70, 0), (50, 0), (30, 0), H(90, 0)

// etc.
Run Code Online (Sandbox Code Playgroud)

现在我忘记考虑的一件事是每个部分需要移动的方向。它可以存储在坐标旁边。但我认为这部分你可能已经理解了。