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

Author Topic: [Solved] FPS drops to 1 when moving sprite  (Read 2827 times)

0 Members and 2 Guests are viewing this topic.

Ernyz

  • Newbie
  • *
  • Posts: 3
    • View Profile
[Solved] FPS drops to 1 when moving sprite
« on: March 21, 2015, 12:51:28 pm »
Hello,
I have written a simple program which draws a spaceship which can be moved with WASD keys. The problem is, that when moving continuously, the FPS starts decreasing until it reaches 1. When I release movement keys, FPS starts going back to ~60. So, as long as the ship is being moved, the FPS is dropping, otherwise FPS stays normal or increases to 60.
I am developing in 64bit Linux Mint 17.1. Before posting here, I have read the FAQ, updated my video card drivers. My video card is Nvidia GeForce GT 540M, I am using nvidia-346 drivers. I wrote the program using vim, compiled with g++. SFML version is 2.2 and I have set it up using tutorial: http://www.sfml-dev.org/tutorials/2.2/start-linux.php. I have put all the code to one file, if anyone would like to test it.
Does anyone know why this lag is happening and how to fix it? Thanks in advance :)

Code: [Select]
#include <SFML/Graphics.hpp>

class Game {
    public:
        Game();
        void run();
    private:
        void processEvents();
        void update(sf::Time deltaTime);
        void render();
        void handlePlayerInput(sf::Keyboard::Key key, bool isPressed);

    private:
        static const float PlayerSpeed;
        static const sf::Time TimePerFrame;
        sf::RenderWindow mWindow;
        sf::Texture mTexture;
        sf::Sprite mPlayer;
        bool mIsMovingUp, mIsMovingDown, mIsMovingLeft, mIsMovingRight;
};

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

Game::Game():
mWindow(sf::VideoMode(640, 480), "SFML Application"),
mTexture(),
mPlayer(),
mIsMovingUp(false),
mIsMovingDown(false),
mIsMovingRight(false),
mIsMovingLeft(false)
{
    if(!mTexture.loadFromFile("resources/Ship.png")){/* Handle loading error */}
    mPlayer.setTexture(mTexture);
    mPlayer.setPosition(100.f, 100.f);
}

void Game::run() {
    sf::Clock clock;
    sf::Time timeSinceLastUpdate = sf::Time::Zero;
    while(mWindow.isOpen()) {
        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 deltaTime) {
    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(movement * deltaTime.asSeconds());
}

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::A) {
        mIsMovingLeft = isPressed;
    } else if(key == sf::Keyboard::D) {
        mIsMovingRight = isPressed;
    }
}

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

    return 0;
}
« Last Edit: March 21, 2015, 05:31:34 pm by Ernyz »

victorlevasseur

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: FPS drops to 1 when moving sprite
« Reply #1 on: March 21, 2015, 03:13:57 pm »
Hi,

The processEvents() need to be outside the second while.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: FPS drops to 1 when moving sprite
« Reply #2 on: March 21, 2015, 03:50:18 pm »
A tiny detail; I believe
while(timeSinceLastUpdate > TimePerFrame)
Should be
while(timeSinceLastUpdate >= TimePerFrame)
:-)

Ernyz

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: FPS drops to 1 when moving sprite
« Reply #3 on: March 21, 2015, 04:24:03 pm »
Yes, moving processEvents() out of the second while solved the problem (thanks!), though fps still sometimes drops to 45 and movement is not as smooth as I would like it to be. The code now looks like this:
Code: [Select]
...
while(mWindow.isOpen()) {
        timeSinceLastUpdate += clock.restart();
processEvents();
        while(timeSinceLastUpdate >= TimePerFrame) {
            timeSinceLastUpdate -= TimePerFrame;
            update(TimePerFrame);
        }
        render();
    }
...
By the way, I wrote this program according to first chapter of this book: SFML Game Development and after that I have even downloaded the sample code from their git repo to compare performance and source code, and in both of them processEvents() was in that second while and both of them lagged. I am wondering, did they include not working example, or is it a problem specific to linux/my computer?
@Jesper Juhl
Thanks for the notice, I've fixed that part too :)
« Last Edit: March 21, 2015, 04:25:36 pm by Ernyz »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: FPS drops to 1 when moving sprite
« Reply #4 on: March 21, 2015, 05:23:17 pm »
Try enabling vsync (for "smoothness"/consistency, not absolute perf).
Also make sure you are building with optimization enabled (aka release build). Modern C++ is pretty dependant on the compiler for performance and unoptimized C++, although being a lot more debugable, performs pretty crappy.

Ernyz

  • Newbie
  • *
  • Posts: 3
    • View Profile
Re: FPS drops to 1 when moving sprite
« Reply #5 on: March 21, 2015, 05:30:46 pm »
Okay, I'll try out your suggestions as soon as I can, thanks for all the help :)

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: [Solved] FPS drops to 1 when moving sprite
« Reply #6 on: March 21, 2015, 05:36:23 pm »
As for making sure it's an optimized build, since you are using GCC on Linux, just make sure your compiler commandline includes '-O2' (or '-O3' although profile that since O3 may help or hurt performance depending on your app. Use -O2 unless you know why to use something else).
And always read the documentation for your compiler's options as well as other resources on the subject.
« Last Edit: March 21, 2015, 05:40:21 pm by Jesper Juhl »

 

anything