Рассчитать, если число строк цикла |Hex Grid Round World - PullRequest
0 голосов
/ 10 ноября 2011

Итак, у меня есть шестнадцатеричная сетка, которая имеет сетку 100x100 ... Сетка рекурсивная, поэтому, когда вы прокручиваете влево после позиции '0,0', она рисует строку '99, 0 'и т. Д. ... Моя проблеманайти алгоритм, который позволит мне вычислить, возвращаюсь ли я обратно ...

Пример: 96 - 97 - 98 - 99 - 0 - 1 - 2 - 3 - 4

Оба изу них есть начальные местоположения, меньшие, чем конечное местоположение. Если я был в строке 2, а экран перемещался в строку 98:

2 до 98 РАБОТ (98) - 100 = -2, а затем -2- (2) = расстояниеот 4

96 до 98 FAILS (98) - 100 = -2, затем -2- (96) = расстояние 98 (правильное значение 2)

Оба из них имеют конечные местоположения меньше, чемстартовое местоположение Однако это не работает в обоих направлениях ... поэтому мы делаем это ... из строки 98 в строку 2:

98 до 2 РАБОТ (2) + 100 = 102, затем 102- (98)) = расстояние от 4

96 до 98 FAILS (96) + 100 = 196, затем 196- (98) = расстояние от 98 (правильное значение 2)

Как видите, я не могу простоскажем, если начало <конец или начало> конец какчисло петель шурупов.Мне нужно определить, когда "Пересекая черту", как ...


После предложений Джонатана я понял, что отображение клиента и за кулисами не должно совпадать.Я изменил двигатель, поэтому есть 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 ]

3 голосов
/ 10 ноября 2011

Я бы сказал, что на самом деле это невозможно без большей информации, чем вы нам дали. Возьмите пример перехода с 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)
}
0 голосов
/ 10 ноября 2011

Примечание: я разместил следующее, прежде чем увидел обновление вопроса. Это то, что, как я догадался, вы могли иметь в виду в своем первоначальном вопросе. Может быть, это все равно будет полезно.

Я не совсем понимаю требование как сформулированное, поэтому я предполагаю, что это «Найти кратчайшее расстояние между двумя позициями, позволяющее переносить через границу 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.    
...