I
I
Ivan Ivanov2014-07-16 13:32:46
Programming
Ivan Ivanov, 2014-07-16 13:32:46

How to achieve the desired fps?

From the calculation of 1000ms/30fps = 33.3333ms , we get that we must perform some action in at least 33.3ms to get 30fps. But I get 21fps every launch. Here is the code:

bool Game::run(void)
{
  startTime = GetTickCount(); //получаем время прошедшее с запуска программы
  frameCount = 0; //подсчет фреймов
  lastTime = 0;

  char key = ' ';

  while(key != 'q') //пока не нажали на выход
  {
    while(!getInput(&key)) 
    {
      timerUpdate(); //обновляем 
    }

    cout << "You pressed: " << key << endl;
  }
  cout << frameCount / ((GetTickCount() - startTime) / 1000) << "fps" << endl; //высчитываем фпс по формуле: [Кол-во сделанных фреймов / на прошедшее время после старта в сек]

  return true;
}

bool Game::getInput(char *c)
{
  if( kbhit() ) //если клавиша нажата
  {
    *c = getch(); //то считать
    return true;
  }
  //иначе
  return false;
}

void Game::timerUpdate(void)
{
  double currentTime = GetTickCount() - lastTime; //получаем текущее время выполнения

  if(currentTime < GAME_SPEED) //если оно меньше 33,33мс(нужной частоты), то ждем еще, чтобы обновить фрейм 
    return;
  else
    frameCount++; //иначе обновляем фрейм, т.к. время пришло

  lastTime = GetTickCount(); //получаем конечное время
}

Answer the question

In order to leave comments, you need to log in

3 answer(s)
A
AxisPod, 2014-07-17
@Csklassami

Ну во первых для этого существуют high-resolution timers. И никогда для этого не используйте GetTickCount и подобные. В винде для этого надо использовать multimedia timers. В принципе можно использовать boost::asio для этого. Здесь требуется событийная система.
Дальше, что сильно пугает, так это опрос клавиатуры, вы не сможете таким образом нажать 2 клавиши одновременно. Так никогда не стоит делать. В винде для этого есть RawInput. Как в никсах уже не подскажу.
А вообще возьмите готовый движок, не парьте мозг.
PS In general, read how game cycles are organized. A certain timer is started in the main loop, but it is not intended to control fps (here, as I said above, a high-resolution timer is needed and an event-based one is very desirable), it is intended to calculate the state of the game world so that the game speed does not depend on the number of fps. In fact, FPS is usually controlled by the means of the system (and in particular the video card) and this is called "beam waiting" (in ancient times), now it is simply called frame / video synchronization and something else. At the same time, it can be a multiple of the vertical frequency of the monitor, if the monitor has a frequency of 60, then you can get a frame rate of 30. Ready-made game engines will help you with this.

B
bogolt, 2014-07-16
@bogolt

If you want to lower the fps (as I understood from the question that you want exactly this), then after calculating the time of the current cycle, add sleep () for the missing number of milliseconds.
For example, you need 1 loop to run in 30ms, and it runs in 20, so you need to sleep 10 more before exiting the loop.

S
Sergey, 2014-07-16
Protko @Fesor

Why wait? Is this how you save the CPU?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question