Sign in to follow this  

Control Frame Rates in SFML

This topic is 1278 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi

I'm at the beginning of learning SFML , i wrote a program to show the character moving around but it moves too fast

i want to control its speed and calculate frame rates per second but i have no idea how to do that

here is my code

#ifdef SFML_STATIC
#pragma comment(lib, "glew.lib")
#pragma comment(lib, "freetype.lib")
#pragma comment(lib, "jpeg.lib")
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "gdi32.lib")  
#endif // SFML_STATIC


#include <SFML/Graphics.hpp>
#include <iostream>
#include <string>

const int Window_Width = 800;
const int Window_Height = 600;
const std::string Window_Name = "My First SFML Game";

int main()
{
	sf::RenderWindow window(sf::VideoMode(Window_Width, Window_Height), Window_Name, sf::Style::Close);
	window.setPosition(sf::Vector2i(250, 50));  // change position of the window
	window.setKeyRepeatEnabled(false);

	enum Dirction{ Down, Left, Right, Up };
	sf::Vector2i source(1, 0);

	sf::Texture pTexture;
	sf::Sprite sPlayer;
	if (!pTexture.loadFromFile("Player.png")){
		std::cout << "Error loading the Texture" << std::endl;
		return -1;
	}

	sPlayer.setTexture(pTexture);  //Sprite
	sf::Event MyEvent;
	
	while (window.isOpen())
	{
		
		while (window.pollEvent(MyEvent))
		{
			switch (MyEvent.type)
			{
			case sf::Event::Closed:
				window.close();
				break;
			}

		}

		if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)){
			source.y = Down;
			sPlayer.move(0,1);
		}
		else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)){
			source.y = Left;
			sPlayer.move(-1, 0);
		}
		else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)){
			source.y = Right;
			sPlayer.move(1, 0);
		}
		else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)){
			source.y = Up;
			sPlayer.move(0, -1);
		}
		
		source.x++;
		if (source.x * 32 >= pTexture.getSize().x)
				source.x = 0;
		
		window.clear();
		sPlayer.setTextureRect(sf::IntRect(source.x * 32, source.y*32, 32, 32));
		window.draw(sPlayer);
		window.display();
	}
	return EXIT_SUCCESS;
}

Thanks

Share this post


Link to post
Share on other sites
int main() {
	
	sf::Clock clock;
	float last_render = 0;

	gameIsRunning = true;
	while (gameIsRunning) {
		//**Do your simulation*/

		//Is it time to render?
		if (last_render - clock.getElapsedTime.asSeconds() > 1/60) {// 1:60 for 60 FPS
			//Update the last_render variable			
			last_render = clock.getElapsedTime.asSeconds();
			
			//**Do your rendering*/

		}
	}
}

I haven't tested my code. If someone spots any mistakes please let me know;

Share this post


Link to post
Share on other sites

Give your character a speed. In other words, determine how long it should take your character to move from point 1 to point 2.

 

Then use sfml's getElapsedTime function to determine how much time has passed since the previous simulation step and move your character over the appropriate distance.

Share this post


Link to post
Share on other sites
int main() {
	
	sf::Clock clock;
	float last_render = 0;

	gameIsRunning = true;
	while (gameIsRunning) {
		//**Do your simulation*/

		//Is it time to render?
		if (last_render - clock.getElapsedTime.asSeconds() > 1/60) {// 1:60 for 60 FPS
			//Update the last_render variable			
			last_render = clock.getElapsedTime.asSeconds();
			
			//**Do your rendering*/

		}
	}
}

I haven't tested my code. If someone spots any mistakes please let me know;

 

i don't whats the mistake but it doesn't work  :/

 

 

Give your character a speed. In other words, determine how long it should take your character to move from point 1 to point 2.

 

Then use sfml's getElapsedTime function to determine how much time has passed since the previous simulation step and move your character over the appropriate distance.

i don't know how to detrmine the time  could you please write the code :D

Share this post


Link to post
Share on other sites

It's a function of sf::Clock, see dejaime's piece of code.

 

Something like:

newpos = oldpos + speed * clock.getElapsedTime().asMilliseconds();

 

Where speed is the number of positions to move per millisecond. This code doesn't take the direction into account.

Share this post


Link to post
Share on other sites

It's a function of sf::Clock, see dejaime's piece of code.

 

Something like:

newpos = oldpos + speed * clock.getElapsedTime().asMilliseconds();

 

Where speed is the number of positions to move per millisecond. This code doesn't take the direction into account.

i didn't understand :(

but i watched CodingMadeEay tutorial and it warked but i don't know why did he put 100 to FrameSwitch and 500 for the FrameSpeed.

float FrameCounter=0, FrameSwitch=100, FrameSpeed=500;

FrameCounter += FrameSpeed * MyClock.restart().asSeconds();
if (FrameCounter >= FrameSwitch){
	FrameCounter = 0;
}

Share this post


Link to post
Share on other sites

 

Speed is measured as distance over time, like miles/hour, or km/h.  For computers, you could use pixels/second to determine how fast a character moves on the screen.  Doing this provides you a very easy way of determining where a character should be placed on the screen, based on his x and y speed in pixels/second.

 

To determine how many pixels a object should move, you take the elapsed time in seconds since he last moved, and you multiply it by his speed.

 

So, if your character moves 100 pixels/second on the x-axis, and if 0.033 seconds have elapsed (30 fps), and the character is currently at x location  50, after this frame he'll be at:

50 pixels + 100 pixels/second * 0.033 seconds = 53.3 pixels

 

You need to keep track of the location as a float to allow for smooth movements at a high frame rate.

// deltaTime is the time in seconds since the last update
void Object::Move(float deltaTime)
{
  // move the player
  m_position.x = m_position.x + m_velocity.x * deltaTime;
  m_position.y = m_position.y + m_velocity.y * deltaTime;
}

Thank you

Share this post


Link to post
Share on other sites

Cap that delta before you pass it around everywhere as well. If, say, your virus checker decides to do its thing or whatever, you can suddenly be passing a massive delta around and your simulation can jump by a massive amount.

 

When you are comfortable with a variable timestep, it would be worth taking a look at this article. Fixed timestep, variable render is the most stable way to go. It is very hard to keep even a simple simulation predictable and stable using variable rate timestep for simulation.

 

Even outside of physics sims, if for example, you have a platform game, you want your character to jump to the same height each time, this is difficult if you have a variable update step.

Share this post


Link to post
Share on other sites


...

Time is tricky on computers. It does not flow regularly, nor does it always move forward. Always validate it.

 

That's a great post Frob.  I think it's something that might be worth a short article, or maybe just a separate post.

 

Either way, thanks.  I always learn new things on this site, game related or not.

Share this post


Link to post
Share on other sites
People DO write about it.

There are occasional writeups of time related bugs. I wrote one before several years ago. Our game server would crash around 10:30A every Thursday. It took a bunch of hunting down. Windows has a normally helpful service that automatically updates the system time against Internet time servers, and it normally synchronizes once per week. After some logging, we discovered right before the crash the machine log jumped backwards by several seconds, which clued us in to the problem.

There is a flurry of articles and reminders about every six months (when DST turns on and off) and again every four years, right around the end of February.

Share this post


Link to post
Share on other sites

This topic is 1278 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this