Почему сенсорные события разрушают мою частоту кадров Android? - PullRequest
15 голосов
/ 27 апреля 2009

Я разрабатываю игру для Android. У него много чего происходит, но все идет довольно гладко. Это, конечно, пока пользователь не коснется экрана.

Пока они касаются этого, onTouchEvent вызывается (с action = ACTION_MOVE, x = 0 и y = 0) примерно раз в десять миллисекунд с тем, что кажется достаточно высоким приоритетом, поскольку оно абсолютно стирает частоту кадров. , Как только прикосновение заканчивается, частота кадров возвращается в свое приятное состояние.

Я пробовал

  • с onTouchEvent ручкой ввода для игры как обычно
  • имеющий onTouchEvent возврат true сразу
  • вообще не реализовано onTouchEvent

Проблема сохраняется во всех трех ситуациях.

Кто-нибудь сталкивался с этим? Есть ли способ уменьшить скорость, с которой генерируются события ACTION_MOVE, или гарантировать, что они генерируются только при фактическом движении, или использовать метод опроса, который просто получает текущее местоположение касания? Или даже просто способ полностью его отключить?

Ответы [ 5 ]

14 голосов
/ 27 апреля 2009

Читать эту тему. По сути, вы хотите приостановить поток событий, так как в противном случае система будет перекачивать много событий (между x, y и давлением всегда происходит какое-то движение), которые вам нужно обработать.

1 голос
/ 01 января 2010

Я пытался следовать всему, о чем вы, ребята, говорили о, но я должен признать, что после попытки нескольких способов реализации что вы предлагаете, я до сих пор не смог добиться какого-либо положительного Результаты. Может ли один из вас предоставить пример кода? В частности, Я хотел бы знать, как сделать сон основного потока / пользовательского интерфейса. Если это применимо к моим играм, также было бы неплохо знать, как установить модель опроса, как реализовал Джон.

Вот как выглядит мой код. В потоке пользовательского интерфейса:

public boolean onTouchEvent(MotionEvent event) {
    // Store event somewhere the game thread can see it:
    // ...

    synchronized (someObject) {
        try {
            someObject.wait(1000L);
        } catch (InterruptedException e) {
        }
    }

    return true;
}

и в ветке Игры:

void myGame() {
    while (!stopping) {
        // ...

        // Get a touch event:
        synchronized (someObject) {
            someObject.notify();
        }
        Thread.yield();

        // ...
    }
}
0 голосов
/ 24 ноября 2014

Обычно события имеют свойство отметки времени, поэтому их легко вычислять и регулировать частоту событий.

if (currentEventTimestamp - lastEventTimestamp > 500) { 

    lastEventTimestamp = currentEventTimestamp;

    // do something 

}
0 голосов
/ 14 ноября 2011

Если вам нужно решение без необходимости синхронизации потоков, я могу порекомендовать использовать интерфейс Handler для отправки события и соответствующих данных с помощью Message / Bundle в поток рендеринга игры. Намеченный здесь обходной путь сна все еще применяется.

0 голосов
/ 27 апреля 2009

Возможно несколько очевидное решение, но ... вы пробовали обрабатывать только 1/10 из них? Если вы выполняете обработку, которая запускается каждые 10 мс в потоке пользовательского интерфейса, это, скорее всего, замедлит частоту кадров, да. Так что, если вы просто накапливаете счетчик несколько раз и выполняете какую-либо обработку только после того, как достигнут некоторый минимальный порог?

...