If you are drawing a background that will always cover the entire window and all of its pixels then clear is not necessary but, however, it can be cleared anyway, just to be safe and shouldn't affect the performance.
The skeleton version of a main window loop with a fixed time step would look something like this:
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
// handle events
}
sf::Time frameTime += getFrameTime(); // "getFrameTime()" would be the time since last frame
while (frameTime >= dt) // dt is fixed frame time (delta time)
{
frameTime -= dt;
// update everything using dt as the time frame
}
window.clear();
window.draw(everything);
window.display();
}
One other thing that I forgot to mention is that you should be avoiding rand() as much as possible as it has a number of failings; it's not even fairly choosing the numbers!
Instead, you can use the newer random number generators. Here's an example:
http://www.cplusplus.com/reference/random/uniform_int_distribution/
Just to be clear, Kairos isn't tied to SFML and doesn't use it; it's a timing library only and doesn't use SFML internally. It does, however, allow you to work with SFML.
References just mean that you are working on the original variable that was passed into the function instead of a temporary copy, which allows you to modify external variables in a function, like you do with the window.
Pointers are similar but different and tend to be more confusing at first although they can be avoided completely for a lot of applications.
Since you are having trouble with the newer (better) random stuff, I have put together an example for you:
#include <random>
#include <iostream>
namespace
{
std::default_random_engine generator;
} // namespace
void randomSeed()
{
std::random_device rd;
generator.seed(rd());
}
double getRandomDouble(double min, double max)
{
std::uniform_real_distribution<double> distribution(min, max);
return distribution(generator);
// can be shortened to just: return std::uniform_int_distribution<double>(min, max)(generator);
}
int getRandomInt(int min, int max)
{
std::uniform_int_distribution<int> distribution(min, max);
return distribution(generator);
// can be shortened to just: return std::uniform_int_distribution<int>(min, max)(generator);
}
int main()
{
// randomise the seed so that the same random numbers aren't given in each run of the program (think srand)
randomSeed();
// use functions
std::cout << "Random integer between 0 and 100: " << getRandomInt(0, 100) << std::endl;
std::cout << "Random double between 0 and 1000: " << getRandomDouble(0.0, 1000.0) << std::endl;
// use inline
std::cout << "Random inline random integer between 0 and 1000000: " << std::uniform_int_distribution<int>(0, 1000000)(generator) << std::endl;
std::cout << "Random inline random double between 0 and 1: " << std::uniform_real_distribution<double>(0.0, 1.0)(generator) << std::endl;
// throw 4 dice
std::cout << "DICE:" << std::endl;
std::uniform_int_distribution<int> diceRoll(1, 6);
for (std::size_t i{ 0u }; i < 4u; ++i)
std::cout << diceRoll(generator) << std::endl;
}
You only really need the one generator so it can be reused by all random numbers.
You pretty much always should be using uniform distribution although you have to choose whether or not it's an integer or a real number.
In this example, it shows you:
- how to generate a random seed (think srand(time(NULL)) or whatever),
- how to use simple functions to make getting a random number really clear in the code,
- how to use direct inline calls to get the number without creating functions, and
- how to re-use the same distribution if you expect the range to stay the same.
Hope that helps.