Friday, October 1, 2010

Licznik ramek

Skoro temat timerów jest jeszcze całkiem świeży jest to doskonały czas na napisanie licznika ramek, czyli.. "FPS countera" :)

Zastanawiałem się czy nie zrobić fpsa na bazie klasy Timer, ale ostatecznie stwierdziłem, że kasuroid będzie potrzebował co najwyżej jednego takiego licznika. Nie ma więc sensu tworzyć obiekt klasy Timer. Jest za to sens stworzenia statycznej klasy Fps, zliczającej poszczególne ramki, a następnie wyliczającej liczbę ramek na sekundę.

W klasie Fps wyróżnić można następujące metody:
public static void reset()
{
    mLastTime = 0;
    mCurrentTime = 0;
    mFrames = 0;
    mElapsedTime = 0;
    mFps = 0;
}
Jak nazwa wskazuje resetuje ona wszystkie zmienne potrzebne do wyliczenia fps.
public static void update()
{
    mFrames++;
    mCurrentTime = System.currentTimeMillis();
    mElapsedTime = mCurrentTime - mLastTime;
    if (mElapsedTime >= (long)mFrameLength)
    {
        mFps = (int)((float)mFrames * mFrameLength / (float)mElapsedTime);
        mFrames = 0;
        mLastTime = mCurrentTime;
    }
}
Aktualizuje czasy poszczególnych ramek oraz oblicza aktualne fps.
public static int get()
{
    return mFps;
}
Zwraca (w formacie całkowitym) liczbę ramek na sekundę.

Metodę reset woła Core podczas inicjalizacji. Aby fps był poprawnie liczony Fps.update() musi być wywoływany w każdym przebiegu głównej pętli tj. w runSlice. Zatem, runSlice wygląda teraz tak:
protected int runSlice()
{
    int ret = RetCode.SUCCESS;

    try
    {
        synchronized (mLock) 
        {
            mRenderer.lock();

            // Update all active timers.
            ret = mTimerManager.updateAll();
            if (ret != RetCode.SUCCESS)
            {
                Debug.err(getClass().getName(), "Problem with updating timers!");
                mRenderer.unlock();
                return ret;
            }

            GameState currentState = null;
            if (mGameStatesStack.isEmpty() == false)
            {
                currentState = mGameStatesStack.peek();
                ret = currentState.update();
                if (ret != RetCode.SUCCESS)
                {
                    Debug.err(getClass().getName(), "Problem with updating the state!");
                    mRenderer.unlock();
                    return ret;
                }

                ret = currentState.render();
                if (ret != RetCode.SUCCESS)
                {
                    Debug.err(getClass().getName(), "Problem with rendering the state!");
                    mRenderer.unlock();
                    return ret;
                }
            }

            Fps.update();
        }
    }
    finally 
    {
        // An exception occured, but try to unlock the canvas.
        mRenderer.unlock();
    }

    return ret;
}
runSlice zmienia się wraz z rozwojem kasuroid. Aby zademonstrować działanie Fpsa zaktualizowałem także test "Two timers" o wyświetlanie aktualnego fpsa. Warto pobawić się "sleepTime" Corea i zobaczyć jak zmienia sie fps.
kasuroid zaczyna w końcu raczkować :) Do następnego!

No comments:

Post a Comment