ходьба с wdsa на яве и птс и bump type

  • Автор темы Автор темы AlhimN1
  • Дата начала Дата начала

AlhimN1

Свой человек
Хроники
  1. Interlude
Исходники
Отсутствуют
Сборка
L2JTD
кто то делал на яве что б можно было ходить с клавиатуры? - так с этим всё понятно, работает везде и независимо от сервера

а вот как определять столкновения не понятно - принятие / не принятие команд bump type
 
Последнее редактирование:
задается двумя комплектами координат, нынешними XYZ + xyz вершины вектора? или как?
Выше писал. Нужно в зависимости от скорости бега\ шага ( в зависимости от состояния перса) вычислить расстояние, которое пробежит персонаж до отправки следующего пакета движения( он зависит от скорости бега). Так же учесть, что при смене H тебе нужно перенаправить персонажа в другую координату.
В пакете от клиента приходит только
_heading = readD();
 

Вложения

Последнее редактирование:

задается двумя комплектами координат, нынешними XYZ + xyz вершины вектора? или как?
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 клиентских тика.

По сути, это просто триггер для мув-движка, который регает чара на движение и пока ты жмешь кнопку в клиенте, он проводит мув-тики для чара в переданном направлении.
 
Последнее редактирование:
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) а почему Z нет в формуле? как она учитывается? или он считает все три арктангенса между xyz?
2) D то что выше описывалось в пакетах - это коэффициент скорости? или это как раз и есть арктангес по оси ху?
3) и если идет обрыв тиков движения по васд от клиента, сервер останавливает чара, или продолжает бежать?
 
во! ты гораздо понятнее объяснил! то есть он из двух пар координат задающих вектор по сути считает угол направления хождения лесом) вопросики:
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) Если обрыв движения - сервер останавливает движение и оповещает об этом клиент.
 
1) Движение в л2 идет по 2D сетке. Z - это это не условная высота чара, а высота ближайшей ячейки в искомых XY в которую возможен переход из ячейки для текущих XY. Т.е условно, координаты можно представить как двумерный массив int[X и Y][Z и NSWE], где на один XY может быть от 1 до 255 Z-NSWE. Поэтому когда ты двигаешься, Z координата не учитывается и не нужна для обозначения точки назначения.
2) D? Ты имеешь ввиду readD()?
3) Если обрыв движения - сервер останавливает движение и оповещает об этом клиент.
Ты пытаешься объяснить простые и очевидные вещи абсолютному маргинезу, там тупа дыбил, остановись.
 
Ты пытаешься объяснить простые и очевидные вещи абсолютному маргинезу, там тупа дыбил, остановись.
Ну если челу интересно, почему бы не объяснить? Тем более это форум, а не личка. Мало ли кому еще будет интересно почитать.
 
Ну если челу интересно, почему бы не объяснить? Тем более это форум, а не личка. Мало ли кому еще будет интересно почитать.
Можешь подойти к ближайшему бомжу по твоей локации и объяснить в целом принципы геометрии, расчетов и базовых алгоритмов. Я думаю, ему будет невероятно интересно.
 
Можешь подойти к ближайшему бомжу по твоей локации и объяснить в целом принципы геометрии, расчетов и базовых алгоритмов. Я думаю, ему будет невероятно интересно.
Ты слишком категоричен) Я стараюсь быть добрее ко всем людям.
 
2) D? Ты имеешь ввиду readD()?
выше ВиндОфЧейнж писал -
"В пакете от клиента приходит только
_heading = readD();"

вот что это за Д такая? что означает и какое содержимое?

Можешь подойти к ближайшему бомжу по твоей локации и объяснить в целом принципы геометрии, расчетов и базовых алгоритмов. Я думаю, ему будет невероятно интересно.

если ты не перестанешь срать в теме, я не поленюсь, и сделаю тему, где так макну тебя в очевидные твои косяки, что даже от такого дурака и бомжа это будет просто в хлам разнос и конец репы.
 
вот что это за Д такая? что означает и какое содержимое?
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)( пришли из ПТС, где они являются обозначениями маски для дизасемблирования пакета из буфера)
 
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)
Ты получаешь его и на его основе считаешь смещение по осям 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);
    }
 
Это значение направления в формате 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 бита в секунду.
Современным сервакам не стоит никаких затруднений посчитать направление твоего движения хоть миллион раз в секунду, поэтому это проще считать на серваке, чем гонять сотни здоровых пакетов по сети.
 
Отличие новых клиентов от старых как раз в том, о чем идет разговор в этой ветке.
Было: Ты тыкаешь кнопку W - сервер получает пакет с координатами XYZ твоего чара и XYZ(которые посчитал клиент) и бежит туда.
Итого 7 полей по 32 бита. Т.е 1 пакет минимум 224 бита. Сервер лишь проверяет, может ли чар туда добежать или нет. Проблем в том, что таких пакетов летело очень много с клиента, при зажатой кнопке, т.к там мувинг был кривым. Т.е ты зажал кнопку и в клиент полетело 500 пакетов в секунду с мувингом, вычисление координат которого упало на ТВОЙ проц, а также засрало сетку как твою, так и серверную.
Стало: Ты тыкаешь кнопку W - сервер получает пакет с направлением. Все остальные вычисление переложили на сервер.
Пока ты не вертишь камерой, а тупо жмешь 1 кнопку, летит 1 пакет 1 раз в 600мс. + сам пакет 32 бита. Что немного меньше, чем 500 пакетов по 224 бита в секунду.
Современным сервакам не стоит никаких затруднений посчитать направление твоего движения хоть миллион раз в секунду, поэтому это проще считать на серваке, чем гонять сотни здоровых пакетов по сети.

спасибо за разъяснение. я просто пытался понять именно структуру процесса и рассчета что описана выше. а изменения схожи переходу на аналоговый сигнал) типа клиент стал выдавать примитивный простой сигнал серверу с клавы + направление, а тот уже сам это переваривает.
еще вопросик - при предварительной отрисовке начала движения до ответа сервера, используются ли инфа из предыдущего пакета о состоянии и скорости чара, или нет предугадывания клиентом и последующего синхрона, а движение начинается только после ответа сервера с данными?
 
Aristo тебе дизер всё правильно написал. Зачем ты распыляешься, этот кловен рандомными вопросами сыплет, ему эта инфа по сути не нужна)
 
Deazer, Aristo, вы пытаетесь объяснить что-то челику, которого походу в свое время, двое мужчин с нетрадиционной ориентацией, заказали на алиэкспресс. Завязывайте.
 
спасибо за разъяснение. я просто пытался понять именно структуру процесса и рассчета что описана выше. а изменения схожи переходу на аналоговый сигнал) типа клиент стал выдавать примитивный простой сигнал серверу с клавы + направление, а тот уже сам это переваривает.
еще вопросик - при предварительной отрисовке начала движения до ответа сервера, используются ли инфа из предыдущего пакета о состоянии и скорости чара, или нет предугадывания клиентом и последующего синхрона, а движение начинается только после ответа сервера с данными?
По сути, движение в клиенте и движение на сервере - это два независимых процесса. Ну т.е для понимания, серверу для движения персонажа из точки А в точку Б не требуется клиент. Он его туда переместит независимо от того, будет ли клиент рисовать этот процесс или нет. При этом конечно, сервер заинтересован в том, чтобы клиент все же отрисовал анимацию движения персонажа из точка А в точку Б. Более того, он заинтересован в том, чтобы такая анимация отрисовалась корректно. Поэтому сервер должен строить маршрут и двигать персонажа так, чтобы в любой конкретный момент времени, координаты на сервере совпадали с координатами в клиенте. Проблема в том, что это все передается по сети и из-за всевозможных оптимизаций от 2004 года(когда в л2 играли на диалап модемах и GPRS), сервер также заинтересован в том, чтобы не разориться на трафике и не разорить клиентов.

Поэтому для оптимизации, сервер передает в клиент только точки начала и конца движения. Скорость персонажа передается отдельно в общем пакете информации о персонаже и клиент ей уже владеет на момент расчета вектора движения.
Исходя из двух полученных точек, известной скорости персонажа, клиент начинает движение из точки А в точку Б. И даже если ты прям сразу немедленно выключишь сервер или выдернешь Ethernet-кабель из мамки, то персонаж не остановится, а продолжит бежать, т.к он получил команду отрисовать движение из А в Б и сделает это не зависимо от того, будет ли связь с сервером или нет.

Поэтому, когда серверу необходимо остановить движение чара, то он шлет ему отдельный пакет остановки. Кроме того, если сервер направит новый пакет движения из Б в Ц, то персонаж побежит в Ц не из Б, а из фактической точки в клиенте, где он сейчас находится(Из-за этого возникают всевозможные рассинхронизации, когда персонаж на сервере добежал до конечной, а в клиенте нет, т.к сервер отправил пакеты движения слишком рано). По-сути, клиент при каждом получении пакета движения из точки в точку, просто меняет вектор движения и задает время окончания анимации исходя из фактического расстояния между точками.

Вот два видео с демонстрацией корректной и некорректной синхронизации.
Корректная:
Посмотреть вложение Нормальная синхронизация.mp4
Некорректная:

Посмотреть вложение Некорректная скорость.mp4
 

Пользуясь случаем Aristo спасибо за этот мануал Мануал ГЕО с помощью которого геодвиг стал лучше работать на DAT файлах (на Java).​

 
По сути, движение в клиенте и движение на сервере - это два независимых процесса. Ну т.е для понимания, серверу для движения персонажа из точки А в точку Б не требуется клиент. Он его туда переместит независимо от того, будет ли клиент рисовать этот процесс или нет. При этом конечно, сервер заинтересован в том, чтобы клиент все же отрисовал анимацию движения персонажа из точка А в точку Б. Более того, он заинтересован в том, чтобы такая анимация отрисовалась корректно. Поэтому сервер должен строить маршрут и двигать персонажа так, чтобы в любой конкретный момент времени, координаты на сервере совпадали с координатами в клиенте. Проблема в том, что это все передается по сети и из-за всевозможных оптимизаций от 2004 года(когда в л2 играли на диалап модемах и GPRS), сервер также заинтересован в том, чтобы не разориться на трафике и не разорить клиентов.

Поэтому для оптимизации, сервер передает в клиент только точки начала и конца движения. Скорость персонажа передается отдельно в общем пакете информации о персонаже и клиент ей уже владеет на момент расчета вектора движения.
Исходя из двух полученных точек, известной скорости персонажа, клиент начинает движение из точки А в точку Б. И даже если ты прям сразу немедленно выключишь сервер или выдернешь Ethernet-кабель из мамки, то персонаж не остановится, а продолжит бежать, т.к он получил команду отрисовать движение из А в Б и сделает это не зависимо от того, будет ли связь с сервером или нет.

Поэтому, когда серверу необходимо остановить движение чара, то он шлет ему отдельный пакет остановки. Кроме того, если сервер направит новый пакет движения из Б в Ц, то персонаж побежит в Ц не из Б, а из фактической точки в клиенте, где он сейчас находится(Из-за этого возникают всевозможные рассинхронизации, когда персонаж на сервере добежал до конечной, а в клиенте нет, т.к сервер отправил пакеты движения слишком рано). По-сути, клиент при каждом получении пакета движения из точки в точку, просто меняет вектор движения и задает время окончания анимации исходя из фактического расстояния между точками.

Вот два видео с демонстрацией корректной и некорректной синхронизации.
Корректная:
Посмотреть вложение 84476
Некорректная:

Посмотреть вложение 84475
Вот тебе более сложная задача, рассказать дыбилам как работает теорема отскока.

1739744172822.webp

Как игроки могут на ПТСе стрелять со стен находясь прямо в притык к непроходимости/не видимости и атакующие с земли нарушая твое описание NWSE. Можешь стать ровно так же и попробовать атаковать.
 
Назад
Сверху