Как проверить, что тело почти перестало двигаться в libgdx + box2d

Итак, у меня есть игровое тело + приспособление и т. Д., Это, по сути, шар, который отскакивает.

Я хочу определить, когда он «довольно много» закончил двигаться.

На данный момент я это делаю:

public Boolean isStopped() { return body.getLinearVelocity().x <= 0.3f && body.getLinearVelocity().y <= 0.3f; } 

Это в основном работает, проблема заключается в том, что когда игрок что-то наткнулся, есть секунда, где его скорость равна 0, так что это возвращает true. Я действительно хотел просто вернуть true, когда он в основном закончен. Предпочтительно, в пределах диапазона, который я могу установить на все, что мне нравится, когда я настраиваю физику своего игрового мира.

Я не могу использовать чек о том, спит он или нет, потому что это происходит слишком поздно, но он не спит до тех пор, пока он не прекратит оказывать на него силы, мне нужно как раз перед этим.

Я мог бы просто хранить, как долго он был остановлен / количество остановленных шагов, но я надеялся, что будет хороший предыдущий метод, который я пропустил.

Есть идеи?

Вы можете следить за последним движением и обновлять его, слегка перемешивая текущую скорость каждый раз:

 float speedNow = body.getLinearVelocity().len(); recentSpeed = 0.1 * speedNow + 0.9 * recentSpeed; if ( recentSpeed < someThreshold ) ... do something ... 

Для recentSpeed вам нужно установить значение recentSpeed на подходящее значение, иначе оно может быть ниже порога на первом шаге.

Видя, как вы определили, что ваши ложные срабатывания вызваны взаимодействием тела с другим, почему бы не добавить пару строк в метод beginContact вашего ContactListener, сохранив текущую скорость тела в своих пользовательских данных? Затем вы можете проверить скорость в методе isStopped. Если есть сохраненная скорость, и текущая скорость не больше, это означает, что тело находится в процессе отскакивания от того, что он ударил: ignore. Если есть запасенная скорость и текущая скорость больше, шар отскочил и движется в каком-то новом направлении: очистите сохраненную скорость. Если нет сохраненной скорости, и текущая скорость ниже вашего порога, вы обнаружили найденную ситуацию.

В вашем ContactListener:

 public void beginContact(Contact contact) { Body a = contact.getFixtureA().getBody(); Body b = contact.getFixtureB().getBody(); if (a == mBall) { a.setUserData(a.getLinearVelocity().len()); } else if (b == mBall) { b.setUserData(b.getLinearVelocity().len()); } } 

И в вашей проверке isStopped:

 public Boolean isStopped() { float storedSpd = (Float) body.getUserData(); float currentSpd = body.getLinearVelocity().len(); if ((storedSpd > Float.MIN_VALUE) && (currentSpd > storedSpd)) { body.setUserData(Float.MIN_VALUE); return false; } else { return (currentSpd < THRESHOLD); } } 

Это непроверено, но вы получаете идею. Кроме того, не забудьте сначала установить данные пользователя в Float.MIN_VALUE.

В конце концов я просто передал дельта от каждого вызова рендеринга методу isStopped ().

 public Boolean isStopped(float delta) { boolean isMoving = ( Math.abs(body.getLinearVelocity().x) >= 0.25f || Math.abs(body.getLinearVelocity().y) >= 0.25f); if(isMoving) { timeStopped = 0f; return false; } else { timeStopped += delta; return timeStopped >= 0.3f; } } 

TimeStopped – это просто свойство класса, начинающееся с нуля. Это действительно верно для начала игры (до того, как пользователь сделал ход), но в моем приложении это абсолютно нормально. Кроме того, верно, что он остановился в этом обстоятельстве.

Мне все еще хотелось бы видеть способ сделать это, не сохранив лишнее дерьмо, так как я предполагаю, что box2d должен иметь эту информацию где-то, чтобы выяснить, не имеет ли сила тела с нулевой скоростью, или если она просто меняется Направление после удара.

Intereting Posts
Ошибка «Невозможно устранить символ» при использовании андроида: id = «@ + android: id / my_id» Desktop java app копирует и передает данные Android через USB Невозможно изменить идентификатор контейнера фрагмента SupportMapFragment Как использовать отладчик Eclipse в AsyncTask при разработке для Android? Robolectric – Не удалось загрузить класс: org.robolectric.shadows.ShadowMultiDex Android edit text, как начать печатать в левом верхнем углу? Android – Exoplayer 2 – воспроизведение нескольких звуков / аудио одновременно – MergingMediaSource Расположение Android, изменение размера по процентам и поддержание пропорции Как создать Scrollview программно? Android Espresso не ждет завершения пользовательского интерфейса Кордова 6.4.0 Ошибка Android при создании релиза apk Доступ к домашнему / рабочему адресу, хранящемуся на Картах Google («Мое место») JQuery, как тестировать мобильный браузер? Android Parcelable – запись и чтение ArrayList <IA>, когда IA является интерфейсом Удалить значок заголовка группы по умолчанию расширенного списка