I have three loops. One is of my own design and runs just like I want it to, but from what I am reading, is the wrong way to do things. I have two others from Dewitter's tutorial and the Fix Your Timestep article, that almost work, but I am certain I am missing something to bring it home.
I would love if someone took a look at my project and tell me what I am doing wrong.
The below code should compile without issue and without need of outside resources. Just copy and paste it. It will first launch a window with my gameloop. When you close that window, my take on Dewitter's loop will launch, and finally the FYT loop.
#include <SFML\Graphics.hpp>
void startMinimalExample();
void startDeWitters();
void startGafferonGames();
int main()
{
startMinimalExample();
startDeWitters();
startGafferonGames();
return 0;
}
//I cannot see a fault with this but apparently it is bad practice.
void startMinimalExample()
{
sf::RenderWindow window;
window.create(sf::VideoMode(640, 480),"SFML Window");
window.setActive(false);
sf::Event event;
sf::RectangleShape sprite(sf::Vector2f(300, 300));
sprite.setFillColor(sf::Color::Blue);
float speed = 150.0f;
sf::Clock updateClock;
float updatesPerSecond = 1.0f / 30.0f;
sf::Time timeSinceLastUpdate;
sf::Clock drawClock;
float drawsPerSecond = 1.0f / 60.0f;
sf::Time timeSinceLastDraw;
while (window.isOpen())
{
if (updateClock.getElapsedTime().asSeconds() > updatesPerSecond)
{
timeSinceLastUpdate = updateClock.restart();
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
sprite.move(speed * timeSinceLastUpdate.asSeconds(), 0);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
sprite.move(-speed * timeSinceLastUpdate.asSeconds(), 0);
}
}
if (drawClock.getElapsedTime().asSeconds() > drawsPerSecond)
{
timeSinceLastDraw = drawClock.restart();
window.clear();
window.draw(sprite);
window.display();
}
}
}
//High framerate and good speed consistency only if TICKS PER SECOND stays at a fairly low value
void startDeWitters()
{
sf::RenderWindow window;
window.create(sf::VideoMode(640, 480),"SFML Window");
window.setActive(false);
sf::Event event;
sf::RectangleShape sprite(sf::Vector2f(300, 300));
sprite.setFillColor(sf::Color::Blue);
float speed = 10.0f;
sf::Clock clock;
const int TICKS_PER_SECOND = 25;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 5;
sf::Int64 next_game_tick = clock.getElapsedTime().asMilliseconds();
int loops;
float interpolation;
while (window.isOpen())
{
loops = 0;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
while (clock.getElapsedTime().asMilliseconds() > next_game_tick && loops < MAX_FRAMESKIP)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
sprite.move(speed, 0);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
sprite.move(-speed, 0);
}
next_game_tick += SKIP_TICKS;
loops++;
}
//AM I MISSING SOMETHING HERE?
interpolation = float(clock.getElapsedTime().asMilliseconds() + SKIP_TICKS - next_game_tick) / float(SKIP_TICKS);
window.clear();
window.draw(sprite);
window.display();
}
}
//High framerate but poor speed consistency
void startGafferonGames()
{
sf::RenderWindow window;
window.create(sf::VideoMode(640, 480),"SFML Window");
window.setActive(false);
sf::Event event;
sf::RectangleShape sprite(sf::Vector2f(300, 300));
sprite.setFillColor(sf::Color::Blue);
float speed = .25f;
double t = 0.0;
const double dt = 0.01;
sf::Clock clock;
sf::Int32 currentTime = clock.getElapsedTime().asMilliseconds();
double accumulator = 0.0;
while (window.isOpen())
{
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
{
window.close();
}
}
sf::Int32 newTime = clock.getElapsedTime().asMilliseconds();
double frameTime = newTime - currentTime;
if (frameTime > 0.25)
{
frameTime = 0.025;
}
currentTime = newTime;
accumulator += frameTime;
while (accumulator >= dt)
{
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
sprite.move(speed, 0);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
sprite.move(-speed, 0);
}
t += dt;
accumulator -= dt;
}
//AM I MISSING SOMETHING HERE?
const double alpha = accumulator / dt;
window.clear();
window.draw(sprite);
window.display();
}
}