-
BTW, if the line below is commented out, it will be fast enough:
window.setFramerateLimit(60);
-----------------------------------------------------
When navigating on the map, it is not smooth enough, especially when the resolution of the view is high.
Any way to optimize? Thanks.
int main()
{
sf::View view(sf::FloatRect(0, 0, 1280, 720));
sf::Texture texture;
texture.loadFromFile("world.png");
sf::Sprite map(texture);
sf::RenderWindow window(sf::VideoMode(640, 480), "test view");
window.setFramerateLimit(60);
// run the main loop
while (window.isOpen())
{
// handle events
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
default:
break;
}
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
view.move(0, -4);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
view.move(-4, 0);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
view.move(0, 4);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
view.move(4, 0);
}
window.clear();
window.setView(view);
window.draw(map);
window.display();
}
return 0;
}
-
Have you tried linear interpolation yet? That's what I use in my 2D platformer and it's very smooth.
-
don't use immediate value for move view or other stuff, search inside tutorial or google for use deltatime with sf::Clock.
-
don't use immediate value for move view or other stuff, search inside tutorial or google for use deltatime with sf::Clock.
Like this? But still not smooth enough.
#include "stdafx.h"
int main()
{
sf::View view(sf::FloatRect(0, 0, 640, 480));
//view.setViewport(sf::FloatRect(0.25f, 0.25, 0.5f, 0.5f));
sf::Texture texture;
texture.loadFromFile("world.png");
sf::Sprite map(texture);
sf::Clock clock;
sf::RenderWindow window(sf::VideoMode(1280, 720), "test view");
window.setFramerateLimit(60);
sf::RenderTexture render_texture;
if (!render_texture.create(1280, 720))
{
std::cerr << "render_texture.create() failed" << std::endl;
return -1;
}
float speed = 0.1f;
// run the main loop
while (window.isOpen())
{
sf::Time time_elapsed = clock.restart();
// handle events
sf::Event event;
while (window.pollEvent(event))
{
switch (event.type)
{
case sf::Event::Closed:
window.close();
break;
default:
break;
}
}
float delta = speed * time_elapsed.asMilliseconds();
if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
view.move(0, -delta);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
view.move(-delta, 0);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
view.move(0, delta);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
view.move(delta, 0);
}
render_texture.clear();
render_texture.setView(view);
render_texture.draw(map);
render_texture.display();
const sf::Texture& texture = render_texture.getTexture();
sf::Sprite sprite(texture);
window.draw(sprite);
window.display();
}
return 0;
}
-
Have you tried linear interpolation yet? That's what I use in my 2D platformer and it's very smooth.
Not yet, how to do linear interpolation? Does sfml support it directly? I just can't find from the tutorials.
-
In this context, using linear interpolation to make the game appear smoother is a much higher-level task than what SFML provides. It's the sort of thing a game *engine* might do, but not a library.
For the general issue of writing a game loop that ensures both visual smoothness and stable game logic, these are some of the standard links to read:
http://gameprogrammingpatterns.com/game-loop.html
http://gafferongames.com/game-physics/fix-your-timestep/
http://www.koonsolo.com/news/dewitters-gameloop
-
Well I'm using a fixed time step (see links posted above) to update my game, independent of how it's rendered.
To achieve a fixed time step you just update the game at a constant rate, for example 60 times / sec
sf::Clock c;
const sf::Time timePerFrame = sf::seconds(1.0f / 60.0f);
sf::Time timeSinceLastUpdate = sf::Time::Zero;
The game loop would then look something like this
while (window.isOpen()) {
timeSinceLastUpdate += c.restart();
// poll events
sf::Event evt;
while (window.pollEvent(evt)) {
// ...
}
// update
while (timeSinceLastUpdate > timePerFrame) {
timeSinceLastUpdate -= timePerFrame;
game.update(timePerFrame);
}
// render (clear, draw, display)
game.render();
}
Inside game.update you'd then use timePerFrame to update your physics etc.
To use linear interpolation with your view, you could calculate the new position with
currentPos = currentPos + (fraction * (targetPos - currentPos))
where currentPos and targetPos are the position (e.g. a float or a vector) and fraction (a float) is how fast it will be interpolated, for example 0.1
-
This may help with your linear interpolation:
https://github.com/Hapaxia/Hx/blob/master/include/Hx/Plinth/Tween.inl#L33