Android-игра заикается; gc под контролем и сброс кадра вместо Thread.sleep - PullRequest
0 голосов
/ 04 мая 2018

Я сталкиваюсь с довольно известной проблемой (для новичков, как я) заикания игры. Это происходит почти непрерывно, и я не могу найти причину. Я уже нашел проблемы, связанные с созданием объектов и активностью gc, благодаря монитору памяти Android Studio, и теперь они решаются. Благодаря некоторым ответам, найденным здесь на сайте, я заменил подход Thread.sleep для управления частотой кадров логикой, подобной пропаданию кадров, чтобы избежать безответственности из-за графика работы ОС. Более того, я заметил, что переключение на «Производительность» на моем Xiaomi MI 4, поэтому при стабильной и высокой частоте процессора оно работает плавно; это позволило мне подумать о «неожиданных» пиках загрузки процессора. К сожалению, снижение целевой частоты кадров до 30 ничего не изменит.

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

private static final float TARGET_FPS=60;

private final SurfaceHolder mSurfaceHolder;

private Paint mBackgroundPaint;

boolean  mIsOnRun;

/**
 * This is the main nucleus of our program.
 * From here will be called all the method that are associated with the display in GameEngine object
 * */
@Override
public void run()
{
    long currTime, lastFrameTime=0;
    float nFrameTot=1, nUpdateTot=1;
    float totalRenderTime=0.002f, totalUpdateTime=0.002f;
    float estimatedFrameRenderTime=0.002f, estimatedUpdateTime;

    //Looping until the boolean is false
    while (mIsOnRun)
    {
        currTime=System.nanoTime();

        //Updates the game objects business logic
        AppConstants.getEngine().update();

        if ((nUpdateTot + 1) > Float.MAX_VALUE || (totalUpdateTime + 0.002f) > Float.MAX_VALUE) {
            nUpdateTot=1;
            totalUpdateTime=0.002f;
        }
        nUpdateTot++;

        totalUpdateTime=totalUpdateTime + ((System.nanoTime() - currTime) / 1000000000f);
        estimatedUpdateTime = totalUpdateTime / nUpdateTot;

        currTime=System.nanoTime();

        if ((currTime - lastFrameTime)/1000000000f > (1/TARGET_FPS)-estimatedFrameRenderTime-estimatedUpdateTime) {

            lastFrameTime=currTime;

            //locking the canvas
            Canvas canvas = mSurfaceHolder.lockCanvas(null);

            if (canvas != null)
            {
                //Clears the screen with black paint and draws object on the canvas
                synchronized (mSurfaceHolder)
                {
                    canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), mBackgroundPaint);
                    AppConstants.getEngine().draw(canvas);
                }

                //unlocking the Canvas
                mSurfaceHolder.unlockCanvasAndPost(canvas);
            }

            nFrame++;

            if ((nFrameTot + 1) > Float.MAX_VALUE || (totalRenderTime + 0.002f) > Float.MAX_VALUE) {
                nFrameTot=1;
                totalRenderTime=0.002f;
            }
            nFrameTot++;

            totalRenderTime=totalRenderTime + ((System.nanoTime() - lastFrameTime) / 1000000000f);
            estimatedFrameRenderTime = totalRenderTime / nFrameTot;

        }
    }
}

Теперь, если говорить о том, что делает игра, это карточная игра и цветной фон, и рисуется не более 16 растровых изображений одновременно; единственная «анимация» - это перемещение растровых изображений. Честно говоря, я не знаю, смогу ли я что-то делать глупо, и был бы рад поделиться с вами фрагментами кода, если это поможет вам лучше понять мою проблему.

Спасибо, что уделили время на этом!

...