Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: White square problem and fixed time step struggle  (Read 2457 times)

0 Members and 1 Guest are viewing this topic.

Romee258

  • Newbie
  • *
  • Posts: 5
    • View Profile
White square problem and fixed time step struggle
« on: May 01, 2016, 07:39:14 pm »
Hello everyone,

I just started learning SFML with the book, "SFML Game Development".
I tried to build the entire example from the first chapter, but I have to questions:

First, my code doesn't work completely. The only thing I'm seeing is a white square. I compared my code a few times with the example code, but I can't seem to find a difference (next to the fact that I declared two variables globally). I checked the forum, but the only thing I can find is that it occurs when you make it leave his scope due to using an function for example, but that doesn't seem to be the problem in my case. So are you able to find it?


(I put the whole code in 1 file in order to copy it more easlily)
#include <SFML/Graphics.hpp>

static const float PlayerSpeed = 100.f;
const sf::Time TimePerFrame = sf::seconds(1.f / 60.f);

class Game{
private:
        sf::RenderWindow mWindow;
        sf::Texture mTexture;
        sf::Sprite mPlayer;
        sf::Time TimePerFrame;
        sf::CircleShape shape;
        bool mIsMovingUp;
        bool mIsMovingDown;
        bool mIsMovingLeft;
        bool mIsMovingRight;
        void processEvents();
        void update(sf::Time time);
        void render();
        void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);
public:
        Game();
        void run();
};

int main()
{
        Game game;
        game.run();
}

Game::Game()
        :mWindow(sf::VideoMode(640, 480), "SFML Application")
{
        if (!mTexture.loadFromFile("Eagle.png")){
                //Handle loading error
        }
        mPlayer.setTexture(mTexture);
        mPlayer.setPosition(100.f, 100.f);
}

void Game::run()    //Here is the fixed time-step code.
{
        sf::Clock clock;
        sf::Time timeSinceLastUpdate = sf::Time::Zero;
        while (mWindow.isOpen()){
                processEvents();
                timeSinceLastUpdate += clock.restart();
                while (timeSinceLastUpdate > TimePerFrame){
                        timeSinceLastUpdate -= TimePerFrame;
                        processEvents();
                        update(TimePerFrame);
                }
                render();
        }
}

void Game::processEvents()
{
        sf::Event event;
        while (mWindow.pollEvent(event)){
                switch (event.type){
                case sf::Event::KeyPressed:
                        handlePlayerInput(event.key.code, true);
                        break;
                case sf::Event::KeyReleased:
                        handlePlayerInput(event.key.code, false);
                        break;
                case sf::Event::Closed:
                        mWindow.close();
                        break;
                }
        }
}

void Game::update(sf::Time time)
{
        sf::Vector2f movement(0.f, 0.f);
        if (mIsMovingUp)
                movement.y -= PlayerSpeed;
        if (mIsMovingDown)
                movement.y += PlayerSpeed;
        if (mIsMovingLeft)
                movement.x -= PlayerSpeed;
        if (mIsMovingRight)
                movement.x += PlayerSpeed;

        mPlayer.move(time.asSeconds() * movement);
}

void Game::render()
{
        mWindow.clear();
        mWindow.draw(mPlayer);
        mWindow.display();
}

void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed)
{
        if (key == sf::Keyboard::W)
                mIsMovingUp = isPressed;
        else if (key == sf::Keyboard::S)
                mIsMovingDown = isPressed;
        else if (key == sf::Keyboard::D)
                mIsMovingLeft = isPressed;
        else if (key == sf::Keyboard::A)
                mIsMovingRight = isPressed;
}

Second, I read the part in the book explaining the fixed time-step. I understand why you do it, but what I can't understand is the given code example (see above). Could you explain it to me?

If you don't understand something, just ask.

Many thanks!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: White square problem and fixed time step struggle
« Reply #1 on: May 01, 2016, 08:53:09 pm »
Since you don't actually handle the failing of texture loading, how do you know it loads properly?
Do you get an error on the console?

If I remember correctly the following article is also linked in the book, did you read it? http://gafferongames.com/game-physics/fix-your-timestep/
What exactly are you not understanding?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Romee258

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: White square problem and fixed time step struggle
« Reply #2 on: May 01, 2016, 09:34:55 pm »
Thanks for the answer,

I completely forgot about the article, I will read it immidiately when I'm home.
If I still find myself not grasping it, I will ask a more specific question.

About the white square error, I initially thought that I might be caused due to
not loading the file properly, so I tried exactly the same thing with an circle, made with
sf::CircleShape, but I got exactly the same problem.

So, maybe do you see something else?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: White square problem and fixed time step struggle
« Reply #3 on: May 02, 2016, 12:19:34 am »
How are you experiencing the white square problem, which is basically a problem with either texture loading or texture referencing, when you use a circle shape (without texture)?
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Romee258

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: White square problem and fixed time step struggle
« Reply #4 on: May 02, 2016, 12:33:01 am »
I'm experiencing the following:

When the window shows up (840, 480), its white. When I enlarge the window (just using the top right corner button, the white spot stays on the same place with the same measurements and another one shows up in the top left corner). This happens both when using a texture and just making a shape.

But I think I might have found the solution, I'm testing it right now and will let you know if that caused the trouble (it has to do with the global variables).

Thanks!

Romee258

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: White square problem and fixed time step struggle
« Reply #5 on: May 02, 2016, 11:40:56 pm »
Hello again,

I indeed found the problem, it was caused by the global variables. I rewrote a small part of the program (private part of the Game class and the constructor), so that the variables were declared locally.

About the fixed time-step problem: I can't put my finger exactly on the spot of what I don't understand. I basically don't know what happens in that part of the update function at all in order to have a constant deltatime at all. For example, I don't know why you have to perform all those steps in the function and why your not able to simply pass a constant variable for a fixed deltatime without performing all those steps.

Could you maybe answer this question and explain to me what you do and why you do it line by line, in order for me to get the whole picture.

If you are not able, let me know as well, then I will still try to make a more clear question.

Thanks.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: White square problem and fixed time step struggle
« Reply #6 on: May 03, 2016, 12:28:11 am »
Your target here is to have a constant delta time so that all of your updates are working to that fixed amount.
Unfortunately, your game loop's cycle will not take the same amount of time each time so the accumulation method allows you to cycle the loop at whatever rate the display takes and still update the actual logic in small chunks of that fixed amount (constant delta time). See the "Free the physics" section of that article linked earlier. I would recommend that until you fully understand "free the physics", ignore the "final touch" section.

I have created a small timing library, called Kairos that may help you here. It has two classes that can simplify constant timesteps: Timestep and Timestep Lite. Although Timestep has more features, can require less code and holds its own clock, trying Timestep Lite first may help you understand the process. There are examples too.
I use Kairos' Timestep for pretty much everything game-related ;)
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Romee258

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: White square problem and fixed time step struggle
« Reply #7 on: May 03, 2016, 08:39:52 pm »
Okay thanks,

I understand why you pass a constant delta time to your update function.

What I only can't grasp yet, is why you count the time the past frame took and subtract this
with the constant time you would like your frame to be?

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: White square problem and fixed time step struggle
« Reply #8 on: May 03, 2016, 10:46:27 pm »
The article does explain this. It does, in fact, repeat the sentence that explains it!

Quote
The renderer produces time and the simulation consumes it in discrete dt sized chunks.

The amount of time that has passed since the last update is how much updating is now required; the program is slightly behind and we want to bring it up-to-date. To update that amount, you update it in a loop of "constant time amounts" (dt) until you are (almost) up-to-date.

The reason it states "the renderer" is that the amount of time for a program loop cycle is one frame of display (you clear, draw, display it once per frame), whereas the logic updates are looped inside (this is the freeing of the physics).
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*