计算如果数字字符串循环|十六进制网格圆形世界

Calculate If Number String Loops | Hex Grid Round World

本文关键字:网格 十六进制 世界 循环 如果 数字 数字字符 字符串 计算      更新时间:2023-09-26

所以我有一个十六进制网格,有一个100x100的网格…网格是递归的,所以当你向左滚动过"0,0"位置时,它会绘制"99,0"行等等……我的问题是找到一个算法,让我计算,如果我是循环回来…

的例子:96 - 97 - 98 - 99 - 0 - 1 - 2 - 3 - 4

它们的起始位置都小于结束位置如果我在第2行,屏幕平移到第98行:

2 to 98 WORKS (98) - 100 = -2 then -2-(2) = 4的距离

96 to 98失败(98)- 100 = -2则-2-(96)=距离98(正确是2)

它们的结束位置都小于起始位置然而,这并不是双向的……所以我们这样做。从第98行到第2行:

98 to 2 WORKS (2) + 100 = 102 then 102-(98) = 4的距离

96 to 98失败(96)+ 100 = 196 then 196-(98) =距离98(正确是2)

你可以看到,我不能只写if start End,因为number循环把它搞砸了。我需要检测何时"越界"以某种方式…


在Jonathan的建议之后,我意识到客户端展示和幕后并不一定要对齐。我已经改变了引擎,所以有2十六进制值…一个是实际位置,比如98 2 0 0 2 1。另一个是视图端口的文字位置。

看起来像这样:

 Actual:  96  97  98  99  00  01  02  03  04  <= display in client & reference hexGridModel
 Literal: -4  -3  -2  -1  00  01  02  03  04  <= use to calculate buffer position updates from camera

文字只是从"显示"的角度来看。稍后我需要修复,看看我们是否通过了-100或+100,但这个问题现在已经解决了,地图大小是动态的,所以需要以后的工作

现在我只是在任何情况下使用这个

    var x, y = 0
    x = this.buffer.coords.current.x - this.buffer.coords.last.x;
    y = this.buffer.coords.current.y - this.buffer.coords.last.y;

我得说,除了你给我们的信息之外,没有更多的信息是不可能的。以从2移动到98为例。您将无法判断用户是从2 -> 1 -> 0 -> 99 -> 98还是从2 -> 3 -> 4 -> ... -> 97 -> 98移动的。

所以决定这一点的关键是知道玩家或物体移动的方向。

如果你知道这一点,你可以说(假设0在网格的左边界,99在网格的右边界):

if ((direction == LEFT && new_pos > old_pos) || (direction == RIGHT && new_pos < old_pos) {
    // The "line" has been crossed.
} else {
    // The "line" was not crossed.
}

如果你还需要知道行进的距离,你可以这样分解:

GRID_SIZE = 100
if (direction == LEFT && new_pos > old_pos) {
    distance = (GRID_SIZE - new_pos) + old_pos;
} else if (direction == RIGHT && new_pos < old_pos) {
    distance = (GRID_SIZE - old_pos) + new_pos;
} else {
    distance = abs(new_pos - old_pos)
}

注意:在我看到问题的更新之前,我发布了以下内容。我猜你最初的问题可能就是这个意思。

我真的不理解这个要求,所以我猜它是"找到两个位置之间的最短距离,如果它更短,允许跨越99/0边界"。

这个函数返回一个具有三个属性的对象:距离、方向和wrapAround (true/false)。为了便于测试,我还放了一个toString()

function shortestDistance(startPosition, endPosition) {
   var difference = startPosition > endPosition
                  ? startPosition - endPosition
                  : endPosition - startPosition,
       wrapped = difference > 50;

   return {
      distance      : wrapped ? 100 - difference : difference,
      direction     : (startPosition < endPosition
                      ? (wrapped ? "left" : "right")
                      : (wrapped ? "right" : "left")),
      wrappedAround : wrapped,
      toString      : function() {
                         return (
                             this.distance === 0
                             ? "Didn't move"
                             : "Travelled " + this.distance 
                               + " to the " + this.direction + ", and "
                               + (this.wrappedAround ? "did" : "didn't")
                               + " wrap around.");
                      }
   };
}
var result = shortestDistance(2,98);
alert(result.distance);      // 4
alert(result.direction);     // "left"
alert(result.wrappedAround); // true
alert(shortestDistance(2,98));
  // Travelled 4 to the left, and did wrap around.
alert(shortestDistance(98,2));
  // Travelled 4 to the right, and did wrap around.
alert(shortestDistance(96,98));
  // Travelled 2 to the right, and didn't wrap around.
alert(shortestDistance(98,96));
  // Travelled 2 to the left, and didn't wrap around.
alert(shortestDistance(43, 43));
  // Didn't move
alert(shortestDistance(1, 50));
  // Travelled 49 to the right, and didn't wrap around.
alert(shortestDistance(1, 51));
  // Travelled 50 to the right, and didn't wrap around.
alert(shortestDistance(1, 52));
  // Travelled 49 to the left, and did wrap around.
alert(shortestDistance(50, 1));
  // Travelled 49 to the left, and didn't wrap around.
alert(shortestDistance(51, 1));
  // Travelled 50 to the left, and didn't wrap around.
alert(shortestDistance(52, 1));
  // Travelled 49 to the right, and did wrap around.