2013-09-13 2 views
2

Я работаю над 2D-игрой для школьного проекта. Шаблон, который мой учитель дал хорошо, но я хотел заменить очень, очень глупую вещь в коде. В коде он называет тяжелый метод 20 раз, чтобы замедлить игру. Вместо этого я хочу проверить, нужно ли обрабатывать следующий кадр.Настройка фиксированного FPS не работает

Игра является объектом внутри пространства имен шаблонов. В этом пространстве имен был бесконечный цикл, который вызывает метод тика игры и свопирует буферы кадров.

Внутри этого шаблона, я заменил Game->Tick() с простой, если заявление:

if (game->Ready(lastftime)) { 
    game->Tick(); 
} 

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

Это Ready метод:

bool Game::Ready(float timedif) { 
    // Add time to framecounter 
    framecounter += timedif; 

    // Check if the counter over lapses the fps 
    if (framecounter > fps) { 
     // If so, substract the fps from the counter 
     while (framecounter > fps) { 
      framecounter -= fps; 
     } 
     m_Screen->Clear(0); 
     Draw(); 

     return true; 
    } 

    // Frame is still inside the fps margin 
    return false; 
} 

fps рассчитывается следующим образом: fps = 1000.0f/60

Я понятия не имею, почему он не бежит со скоростью 60 кадров в секунду, и я 100 % уверен, что это было вызвано больше, чем (проверено на printf). Любая помощь будет оценена по достоинству.

+1

, что это то, что 'lastftime' вы передаете' Ready'? имя указывает на момент времени, но в Ready вы относитесь к нему как к разнице – codeling

+0

Если «разница» - это время в секундах, вам будет очень сложно провести отсчет кадров выше 1fps ... – RedX

+1

Также переменная «fps» представляет количество миллисекунд между кадрами, а не количество кадров в секунду – Paddyd

ответ

4

Что такое timedif?
у вас должна быть информация о том, когда в «реальном времени» - примеры в ms были последним фреймом
Мне кажется, что вы предполагаете, что каждая итерация цикла ur while занимает один мс.

bool Game::Ready(float msSinceLastFrame) 
{ 
    if(msSinceLastFrame > fps) 
    { 
     m_Screen->Clear(); 
     Draw(); 
     return true; 
    }  
    return false 
} 

//call this using some kind of while where you update msSinceLastFrame 
if(game->Ready(msSinceLastFrame) 
{ 
    msSinceLastFrame = 0; 
    game->Tick(); 
} 

но, если вы будете использовать этот подход, вам нужно вызвать игру :: ready loop using while();

Я бы предложил другой подход.

void Game::gameLoop() 
{ 
    auto lastFrameTimeStamp = GetTickCount(); // if you are on windows 
    auto frameLength = 1000/fps; 
    while(true) //true or some kind of condition 
    { 
     auto currentTimeStamp = GetTickCount(); 
     if(currentTimeStamp - lastFrameTimeStamp >= frameLength) 
     { 
      //do your job; 
      lastFrameTimeStamp = currentTimeStamp; 
     } 
     Sleep(1); // you can use sleep here if you dont want to heat ur pcu =) 
    } 
} 
+0

Спасибо за ваш ответ. Используя последний пример, он работает с той же скоростью, что и у меня. Он также работает быстрее, если значение fps установлено выше, чего не должно быть. Или мой мозг не может думать прямо сейчас. – Broxzier

+0

Да, в коде было неправильное условие, исправил его. –

+0

Большое вам спасибо! это сработало сразу.:) – Broxzier

2

Почему вы вычитанием fps из framecounter? Вам необходимо сбросить framecounter, если он превышает fps.

Попробуйте следующее:

bool Game::Ready(float timedif) { 
    // Add time to framecounter 
    framecounter += timedif; 

    // Check if the counter over lapses the fps 
    if (framecounter > fps) { 
     framecounter = 0; 
     m_Screen->Clear(0); 
     Draw(); 

     return true; 
    } 

    // Frame is still inside the fps margin 
    return false; 
} 
+0

Я вычитаю его, потому что если кадр занимает почти время двух кадров, если будет выполняться в следующий раз, когда он будет вызван снова, вместо того, чтобы ждать, пока он снова не достигнет fps. – Broxzier

Смежные вопросы