Beginning C++ Game Programming
上QQ阅读APP看书,第一时间看更新

Timing

Before we can move the bee and the clouds, we need to consider timing. As we already know, the main game loop executes over and over again, until the player presses the Esc  key.

We have also learnt that C++ and SFML are exceptionally fast. In fact, my ageing laptop executes a simple game loop (such as the current one) at around five thousand times per second.

The frame-rate problem

Let's consider the speed of the bee. For the purpose of discussion we could pretend that we are going to move it at 200 pixels per second. On a screen that is 1920 pixels wide, it would take, very approximately, 10 seconds to cross the entire width, because 10 x 200 is 2000 (near enough to 1920).

Furthermore, we know that we can position any of our sprites with setPosition(...,...). We just need to put the x and the y coordinates in the parentheses.

In addition to setting the position of a sprite, we can also get the position of a sprite. To get the horizontal x coordinate of the bee, for example, we would use this code:

int currentPosition = spriteBee.getPosition().x; 

The current x coordinate of the bee is now stored in currentPosition. To move the bee to the right, we could then add the appropriate fraction of 200 (our intended speed) divided by 5000 (the approximate frames per second on my laptop) to currentPosition like this:

currentPosition += 200/5000; 

Now we could use setPosition to move our bee. It would smoothly move from left to right by 200 divided by 5000 pixels each frame. But there are two big problems with this approach.

Frame rate is the number of times per second that our game loop is processed. That is, the number of times that we handle the player's input, update the game objects, and draw them onto the screen. We will expand on and discuss frame rate implications now and throughout the rest of the book.

The frame rate on my laptop might not always be constant. The bee might look like it is intermittently boosting its way across the screen.

And of course, we want a wider audience for our game than just my laptop! Every PC's frame rate will vary, at least slightly. If you have a really old PC, the bee will appear to be weighed down with lead and if you have the latest gaming rig it will probably be something of a blurry turbo bee.

Fortunately, this problem is the same for every game and SFML has provided a solution. The easiest way to understand the solution is to implement it.

The SFML frame-rate solution

We will now measure and use the frame rate to control our game. To get started with implementing this, add this code just before the main game loop:

// How fast is each cloud? 
float cloud1Speed = 0; 
float cloud2Speed = 0; 
float cloud3Speed = 0; 
    
// Variables to control time itself Clock clock; 
 
while (window.isOpen()) 
{ 

In the previous code we declare an object of the type Clock and we name it clock. The class name starts with a capital letter and the object name (that we will actually use) starts with a lower-case letter. The object name is arbitrary but clock seems like an appropriate name for, well, a clock. We will add some more time-related variables here soon as well.

Now in the update section of our game code add this highlighted code:

/* 
**************************************** 
Update the scene 
**************************************** 
*/ 
 
// Measure time Time dt = clock.restart(); 
 
/* 
**************************************** 
Draw the scene 
**************************************** 
*/ 

The clock.restart() function, as you might expect, restarts the clock. We want to restart the clock each and every frame so that we can time how long each and every frame takes. In addition, however, it returns the amount of time that has elapsed since the last time we restarted the clock.

As a result of this, in the previous code, we are declaring an object of the type Time, called dt, and using it to store the value returned by the clock.restart() function.

Now, we have a Time object, called dt, which holds the amount of time that elapsed since the last time we updated the scene and restarted the clock. Maybe you can see where this is going.

Let's add some more code to the game and then we will see what we can do with dt.

Note

dt stands for delta time, the time between two updates.