To be honest, I had modified it slightly since that post to take time into consideration so that its speed isn't dependant on computer so this is the improved version:
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(1024, 768), "", sf::Style::Close);
sf::View view(window.getDefaultView());
sf::FloatRect bounds{ { 0.f, 0.f }, { 1500.f, 1000.f } }; // arbitrary (must > view size + tile size)
//sf::FloatRect bounds{ { 0.f, 0.f }, { 625.f, 625.f } }; // doesn't fill window so shows how it works
sf::Texture texture;
if (!texture.loadFromFile("image.png"))
return EXIT_FAILURE;
texture.setRepeated(true);
sf::Sprite sprite(texture, sf::IntRect(bounds));
const sf::Vector2f viewStart{ bounds.left + bounds.width / 2.f, bounds.top + bounds.height / 2.f };
const sf::Vector2f spriteStart{ bounds.left, bounds.top };
//const sf::Vector2f moveViewAmount{ 0.2f, -0.3f };
const sf::Vector2f moveViewAmount{ 200.f, -300.f };
sf::Clock clock;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed || event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
window.close();
}
sf::Time dt{ clock.restart() };
view.move(moveViewAmount * dt.asSeconds());
const sf::Vector2f viewOffset(viewStart - view.getCenter());
const sf::Vector2f spriteOffset{ floor(viewOffset.x / texture.getSize().x) * texture.getSize().x, floor(viewOffset.y / texture.getSize().y) * texture.getSize().y };
sprite.setPosition(spriteStart - spriteOffset);
window.clear();
window.setView(view);
window.draw(sprite);
window.display();
}
}