Hello, I am a new SFML and C++ programmer (but I've coded others) btw.
I am trying to get my game window to stay 16:9 whenever it's resized by scaling a 160 x 90 image and resizing the window to that sprite's scale.
Currently, it just.. well, I don't know how exactly to explain it, but the image is not scaling to the window's width.
Here's the code only necessary to share
int lastW = 1600; //window size at startup
int lastH = 900;
bool showDevTool1 = true;
float ratioW = 16.0f / 9.0f;
float ratioH = 9.0f / 16.0f;
std::string RatioHandles = "Images/Debug/Aspect_ratio_handles.png";
//Render window
int main() {
sf::RenderWindow
window(sf::VideoMode(lastW, lastH), "Gaem");
//16:9 ratio handles
sf::Texture RHtexture;
if (!RHtexture.loadFromFile(RatioHandles)) {
return -1; // Exit if loading fails
};
sf::Sprite devTool1;
devTool1.setTexture(RHtexture);
//Keep window open
while (window.isOpen()) {
sf::Event event;
//Close button closes window
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close();
//Can only resize as 16:9 ratio
else if (event.type == sf::Event::Resized) {
window.draw(devTool1);
//if width resized, do this
if (lastW != event.size.width) {
std::cout << event.size.width;
std::cout << "---";
std::cout << RHtexture.getSize().x;
std::cout << "---";
devTool1.setScale(
event.size.width / RHtexture.getSize().x / 10,
lastH / RHtexture.getSize().y / 10);
window.setSize(sf::Vector2u(RHtexture.getSize().x * event.size.width, event.size.height));
lastW = event.size.width;
break;
}
I think that manipulating the window's size should always be considered to be the last resort.
It is not very user friendly at all. It becomes a pain for users that want to place windows in specific places, for example.
The letter box view idea - as shown in the link above - is probably the best solution to this: the user gets the window they want and the program gets the ratio it wants and also can use the size of the window.
Additionally, this can be extended to use the window fully for user interface tools while still keeping the "sprite" at its own ratio (of course, the sprite could represent an entire game display).
With that said, you can use the viewport and view size from the letterbox code to resize the window, if you absolutely must resize the window.
In addition, in the code you have shown, you have a ratio for both width and height. However, these are the ratios when compared to the other so both should never be used; one of them should be 1. Not that those constants are being used...
Also, you shouldn't need a sprite to resize the window. You could, for example, just resize the height of the window based on its width:
constexpr float ratioH{ 9.f / 16.f };
const unsigned int windowWidth{ window.getSize().x };
window.setSize({ windowSize.x, static_cast<unsigned int>(windowSize.x * ratioH) });