Выше писал. Нужно в зависимости от скорости бега\ шага ( в зависимости от состояния перса) вычислить расстояние, которое пробежит персонаж до отправки следующего пакета движения( он зависит от скорости бега). Так же учесть, что при смене H тебе нужно перенаправить персонажа в другую координату.задается двумя комплектами координат, нынешними XYZ + xyz вершины вектора? или как?
задается двумя комплектами координат, нынешними XYZ + xyz вершины вектора? или как?
static double getVectorDirection(IPoint start, IPoint end) {
return Math.atan2(getVectorLengthY(start, end), getVectorLengthX(start, end)) * 65535.0 / 6.283185307179586; //2 * Math.PI
}
Java:static double getVectorDirection(IPoint start, IPoint end) { return Math.atan2(getVectorLengthY(start, end), getVectorLengthX(start, end)) * 65535.0 / 6.283185307179586; //2 * Math.PI }
Арктангенс угла между точкой назначения и 0,0 приведенный к диапазону 0-65535
1 клик на WASD пытается подвинуть персонажа на 1 ячейку(16 точек) в этом направлении. Пакеты с направлением летят при каждом его изменении, либо если оно не меняется, то каждые 3 клиентских тика.
По сути, это просто триггер для мув-движка, который регает чара на движение и пока ты жмешь кнопку в клиенте, он проводит мув-тики для чара в переданном направлении.
1) Движение в л2 идет по 2D сетке. Z - это это не условная высота чара, а высота ближайшей ячейки в искомых XY в которую возможен переход из ячейки для текущих XY. Т.е условно, координаты можно представить как двумерный массив int[X и Y][Z и NSWE], где на один XY может быть от 1 до 255 Z-NSWE. Поэтому когда ты двигаешься, Z координата не учитывается и не нужна для обозначения точки назначения.во! ты гораздо понятнее объяснил! то есть он из двух пар координат задающих вектор по сути считает угол направления хождения лесом) вопросики:
1) а почему Z нет в формуле? как она учитывается? или он считает все три арктангенса между xyz?
2) D то что выше описывалось в пакетах - это коэффициент скорости? или это как раз и есть арктангес по оси ху?
3) и если идет обрыв тиков движения по васд от клиента, сервер останавливает чара, или продолжает бежать?
Ты пытаешься объяснить простые и очевидные вещи абсолютному маргинезу, там тупа дыбил, остановись.1) Движение в л2 идет по 2D сетке. Z - это это не условная высота чара, а высота ближайшей ячейки в искомых XY в которую возможен переход из ячейки для текущих XY. Т.е условно, координаты можно представить как двумерный массив int[X и Y][Z и NSWE], где на один XY может быть от 1 до 255 Z-NSWE. Поэтому когда ты двигаешься, Z координата не учитывается и не нужна для обозначения точки назначения.
2) D? Ты имеешь ввиду readD()?
3) Если обрыв движения - сервер останавливает движение и оповещает об этом клиент.
Ну если челу интересно, почему бы не объяснить? Тем более это форум, а не личка. Мало ли кому еще будет интересно почитать.Ты пытаешься объяснить простые и очевидные вещи абсолютному маргинезу, там тупа дыбил, остановись.
Можешь подойти к ближайшему бомжу по твоей локации и объяснить в целом принципы геометрии, расчетов и базовых алгоритмов. Я думаю, ему будет невероятно интересно.Ну если челу интересно, почему бы не объяснить? Тем более это форум, а не личка. Мало ли кому еще будет интересно почитать.
Ты слишком категоричен) Я стараюсь быть добрее ко всем людям.Можешь подойти к ближайшему бомжу по твоей локации и объяснить в целом принципы геометрии, расчетов и базовых алгоритмов. Я думаю, ему будет невероятно интересно.
выше ВиндОфЧейнж писал -2) D? Ты имеешь ввиду readD()?
Можешь подойти к ближайшему бомжу по твоей локации и объяснить в целом принципы геометрии, расчетов и базовых алгоритмов. Я думаю, ему будет невероятно интересно.
readD() это команда прочитать из буфера целочисленное 32 битное значение Integer(Decimal).вот что это за Д такая? что означает и какое содержимое?
readD() это команда прочитать из буфера целочисленное 32 битное значение Integer(Decimal).
У тебя пакет приходящий с клиента содержит в себе массив битов, которые могут считываться в определенном порядке.
_heading = readD(); - конкретно эта запись означает, что из буфера будет попытка считать значение Integer и присвоить его переменной _heading, чтобы сохранить его и использовать дальше.
Эта команда не является частью стандартной библиотеки Java и ее реализация может отличаться от сборки к сборке. Где-то это может быть readD(), где-то readInt(), где-то еще какое-то значение. Вообще эти обозначения(D(int32), C(char), F(double), Q(int64), S(string), E(float), B(byte array)( пришли из ПТС, где они являются обозначениями маски для дизасемблирования пакета из буфера)
Выше писал. Нужно в зависимости от скорости бега\ шага ( в зависимости от состояния перса) вычислить расстояние, которое пробежит персонаж до отправки следующего пакета движения( он зависит от скорости бега). Так же учесть, что при смене H тебе нужно перенаправить персонажа в другую координату.
В пакете от клиента приходит только
_heading = readD();
Это значение направления в формате int16 беззнакового. (2^16 - 1)так, но в примере выше это получается считывание вектора движения, или о чем говорил Винд?
static double calculatePointX(double startX, double direction, double offset) {
double directionRadians = direction * 6.283185307179586 / 65535.0;
return startX + offset * Math.cos(directionRadians);
}
static double calculatePointY(double startY, double direction, double offset) {
double directionRadians = direction * 6.283185307179586 / 65535.0;
return startY + offset * Math.sin(directionRadians);
}
Это значение направления в формате int16 беззнакового. (2^16 - 1)
Ты получаешь его и на его основе считаешь смещение по осям X и Y исходя из необходимого расстояния. Чистая тригонометрия.
Код:static double calculatePointX(double startX, double direction, double offset) { double directionRadians = direction * 6.283185307179586 / 65535.0; return startX + offset * Math.cos(directionRadians); } static double calculatePointY(double startY, double direction, double offset) { double directionRadians = direction * 6.283185307179586 / 65535.0; return startY + offset * Math.sin(directionRadians); }
Отличие новых клиентов от старых как раз в том, о чем идет разговор в этой ветке.так, ну если передается значение направления (по сути угол относительно севера или востока) то как считается смещение без параметра скорости в формулах выше? или задается желаемое смещение, а далее сервер исходя из состояния чара и условий - возвращает реальное совершенное? пытаюсь уловить весь основной смысл процесса)
Отличие новых клиентов от старых как раз в том, о чем идет разговор в этой ветке.
Было: Ты тыкаешь кнопку W - сервер получает пакет с координатами XYZ твоего чара и XYZ(которые посчитал клиент) и бежит туда.
Итого 7 полей по 32 бита. Т.е 1 пакет минимум 224 бита. Сервер лишь проверяет, может ли чар туда добежать или нет. Проблем в том, что таких пакетов летело очень много с клиента, при зажатой кнопке, т.к там мувинг был кривым. Т.е ты зажал кнопку и в клиент полетело 500 пакетов в секунду с мувингом, вычисление координат которого упало на ТВОЙ проц, а также засрало сетку как твою, так и серверную.
Стало: Ты тыкаешь кнопку W - сервер получает пакет с направлением. Все остальные вычисление переложили на сервер.
Пока ты не вертишь камерой, а тупо жмешь 1 кнопку, летит 1 пакет 1 раз в 600мс. + сам пакет 32 бита. Что немного меньше, чем 500 пакетов по 224 бита в секунду.
Современным сервакам не стоит никаких затруднений посчитать направление твоего движения хоть миллион раз в секунду, поэтому это проще считать на серваке, чем гонять сотни здоровых пакетов по сети.
По сути, движение в клиенте и движение на сервере - это два независимых процесса. Ну т.е для понимания, серверу для движения персонажа из точки А в точку Б не требуется клиент. Он его туда переместит независимо от того, будет ли клиент рисовать этот процесс или нет. При этом конечно, сервер заинтересован в том, чтобы клиент все же отрисовал анимацию движения персонажа из точка А в точку Б. Более того, он заинтересован в том, чтобы такая анимация отрисовалась корректно. Поэтому сервер должен строить маршрут и двигать персонажа так, чтобы в любой конкретный момент времени, координаты на сервере совпадали с координатами в клиенте. Проблема в том, что это все передается по сети и из-за всевозможных оптимизаций от 2004 года(когда в л2 играли на диалап модемах и GPRS), сервер также заинтересован в том, чтобы не разориться на трафике и не разорить клиентов.спасибо за разъяснение. я просто пытался понять именно структуру процесса и рассчета что описана выше. а изменения схожи переходу на аналоговый сигнал) типа клиент стал выдавать примитивный простой сигнал серверу с клавы + направление, а тот уже сам это переваривает.
еще вопросик - при предварительной отрисовке начала движения до ответа сервера, используются ли инфа из предыдущего пакета о состоянии и скорости чара, или нет предугадывания клиентом и последующего синхрона, а движение начинается только после ответа сервера с данными?
Вот тебе более сложная задача, рассказать дыбилам как работает теорема отскока.По сути, движение в клиенте и движение на сервере - это два независимых процесса. Ну т.е для понимания, серверу для движения персонажа из точки А в точку Б не требуется клиент. Он его туда переместит независимо от того, будет ли клиент рисовать этот процесс или нет. При этом конечно, сервер заинтересован в том, чтобы клиент все же отрисовал анимацию движения персонажа из точка А в точку Б. Более того, он заинтересован в том, чтобы такая анимация отрисовалась корректно. Поэтому сервер должен строить маршрут и двигать персонажа так, чтобы в любой конкретный момент времени, координаты на сервере совпадали с координатами в клиенте. Проблема в том, что это все передается по сети и из-за всевозможных оптимизаций от 2004 года(когда в л2 играли на диалап модемах и GPRS), сервер также заинтересован в том, чтобы не разориться на трафике и не разорить клиентов.
Поэтому для оптимизации, сервер передает в клиент только точки начала и конца движения. Скорость персонажа передается отдельно в общем пакете информации о персонаже и клиент ей уже владеет на момент расчета вектора движения.
Исходя из двух полученных точек, известной скорости персонажа, клиент начинает движение из точки А в точку Б. И даже если ты прям сразу немедленно выключишь сервер или выдернешь Ethernet-кабель из мамки, то персонаж не остановится, а продолжит бежать, т.к он получил команду отрисовать движение из А в Б и сделает это не зависимо от того, будет ли связь с сервером или нет.
Поэтому, когда серверу необходимо остановить движение чара, то он шлет ему отдельный пакет остановки. Кроме того, если сервер направит новый пакет движения из Б в Ц, то персонаж побежит в Ц не из Б, а из фактической точки в клиенте, где он сейчас находится(Из-за этого возникают всевозможные рассинхронизации, когда персонаж на сервере добежал до конечной, а в клиенте нет, т.к сервер отправил пакеты движения слишком рано). По-сути, клиент при каждом получении пакета движения из точки в точку, просто меняет вектор движения и задает время окончания анимации исходя из фактического расстояния между точками.
Вот два видео с демонстрацией корректной и некорректной синхронизации.
Корректная:
Посмотреть вложение 84476
Некорректная:
Посмотреть вложение 84475
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?