Непостоянное время в игровом цикле Android - PullRequest
1 голос
/ 07 января 2012

Я занимаюсь разработкой игры для Android.Так как это моя первая игра для Android, я хотел сделать ее максимально простой.Я хочу отобразить последовательность случайных чисел (по одному за раз).Между каждой парой чисел должно пройти определенное количество времени (в настоящее время я использую 500 мс).

Проблема в том, что задержка между двумя числами не постоянна (ни на эмуляторе, ни на реальном устройстве под управлением Android2.3.4).Большую часть времени числа меняются с постоянной скоростью, но иногда появляется значительная и заметная задержка (даже достигающая более 1 секунды).

Я включаю части кода, отвечающие за рендеринг чисел.Я использую SurfaceView, и следующая часть - это метод run() игрового цикла, реализованный в дополнительном потоке:

while (!mDone) {
    long now = System.nanoTime();
    if (mLastTime == -1) mLastTime = now;
    long delta = now - mLastTime;
    if (delta > 500000000) {
        mNumberBox.update();
        mLastTime = now;
    }

    if ((w > 0) && (h > 0)) {
        Canvas canvas = mSurfaceHolder.lockCanvas();
        if (canvas != null) {
            mRenderer.drawFrame(canvas);
            mSurfaceHolder.unlockCanvasAndPost(canvas);
        }
    }
}

mNumberBox.update() обновляет число, которое нужно нарисовать, и оно должно быть вызванокаждые 500 мс.Его код очень прост:

mCurrNumber = mRand.nextInt(9) + 1;

mRenderer.drawFrame() отвечает за отображение числа на экране.Вот код:

canvas.drawRoundRect(mBoxRect, 45, 45, mBoxPaint);
String numStr = String.format("%d", mCurrNumber);
Rect bounds = new Rect();
mTextPaint.getTextBounds(numStr, 0, 1, bounds);
int height = bounds.bottom - bounds.top;
canvas.drawText(numStr, canvas.getWidth() / 2, canvas.getHeight() / 2 + height / 2, mTextPaint);

Я профилировал код, запустив приложение в течение примерно 260 секунд.Вот результаты, которые я нашел:

  • Количество run() итераций цикла: 16765
  • Среднее время на итерацию: 16 мс
  • Максимальное время для всехитерации: 97 мс

Практически 100% этого времени расходуется на drawFrame(), особенно на вызовы lockCanvas() и unlockCanvasAndPost(), которые я не могу избежать.

Самое странное, что максимальное время для всех итераций составляло 97 миллисекунд, что намного меньше задержек, которые я замечаю при запуске игры.Так или иначе, я считаю, что проблема может быть не в коде игрового цикла, а, возможно, в конфигурации или где-то еще.У кого-нибудь есть совет?

Ответы [ 2 ]

0 голосов
/ 11 октября 2012

Попробуйте это:

Используйте задачу таймера с 500 мс, обновите ваш mNumberBox и лишите законной силы вашу поверхность.

В вашем классе поверхности в onDraw () вызовите mRenderer.onDraw (canvas).

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

Вы также заметите, что проблемы с задержкой будут решены.

0 голосов
/ 07 января 2012

Вы должны спроектировать свой компонент, чтобы рисовать числа, и все.

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

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

Более того, ваш игровой логический компонент должен ждать меньше.Подождите 100 мс, и каждый раз проверяйте, ждали ли вы более 500 мс после выбора последнего номера.

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