Страницы

Поиск по вопросам

суббота, 16 марта 2019 г.

Как происходит расчет физики и отрисовка графики в разных потоках?

Решил дописать игрушку: Есть 4 фигуры который двигаются по экрану. например метод figure.update() перерасчитывает координаты фигуры. И есть пятая фигура, которой я управляю посредством касания к сенсору. Переопределенный метод onTouchEvent(MotionEvent event) считывает данные с сенсора и обновляет координаты мной управляемой фигуры. Теперь как идет отрисовка: выполнил figure.update() для всех фигур, нарисовал. А вот управляемая мной фигура тоже рисуется на втором шаге, но изменение ее координат происходит в зависимости от касаний сенсора. Т.е. может возникнуть ситуация , что в момент когда я рисую, обновились координаты фигуры, X уже обновлен, а переменная Y еще не обновлена. В итоге отрисуется не совсем верное положение фигуры. Возможно на 60 fps эти косяки не заметны..я лично не вижу никаких таких ошибок, когда запускаю игру, как будто всё точно рассчитывается. Но ведь по логике ошибки должны быть..Разве не должна возникнуть такая ошибка: что идет отрисовка, а у этой фигуры координата в этот момент обновляется сенсором, ведь работа от сенсора идет в UI потоке, а весь остальной расчет физики и отрисовки в доп. потоке. Выходит я должен эти переменные пометить как синхронизированные, но даже без этой пометки никаких исключений нет.
Я бы привел код, но думаю он тут лишний, еще раз повторюсь: В UI потоке изменяется значение фигуры в зависимости от результатов сенсора, а в доп. потоке идет отрисовка этой фигуры. Почему нет исключений, вызванных тем, что на отрисовку нужна координата, которая в данный момент изменяется в UI потоке. Или же почему не заметно на глаз таких вот моментов, что координата X изменилась при резком движении по сенсору , а Y еще имеет старое значение. Мне в голову приходит такой ответ: UI потоку всего то надо от сенсора полученные две переменные обновить и справляется с этим он быстро. Доп. поток имеет всегда обе координаты считанные от одного и того же считывания сенсора. Но вопрос остается такой: если UI часто обновляется координаты (я быстро вожу пальцем по экрану), то почему доп. поток не нарывается на ситуация, когда координата занята записью из UI потока.


Ответ

Используются объекты синхронизации и поочередный расчет физики, отрисовки и ввода от пользователя. Как вы верно заметили, одновременно работать с данными из нескольких потоков просто так нельзя.
К примеру, вы делаете расчет физики 50 раз в секунду (чаще не имеет смысла, т.к. на экране вы не увидите более 100 кадров в сек и поймете что что-то движется не идеально). Каждый тик физики вы можете смотреть изменилось ли что-то, пришли ли новые команды от игрока, и примените их. Команды игрока обычно буферизируются и обрабатываются между физикой и отрисовкой. То есть ваша программа будет работать примерно так:
Ф О О О В Ф О О В Ф О О О В Ф О О // Ф-физика, О-отрисовка, В-ввод от игрока
Физика и команды обрабатываются с фиксированным шагом, отрисовка - сколько успеет. Для плавности картинки - используйте интерполяцию (или экстраполяцию).
Пролет через другие тела решается на стороне обработчика коллизий (проверяйте не только точки на коллизию, но и полный путь между ними).

Комментариев нет:

Отправить комментарий