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

Author Topic: Widescreen/Standard How to detect and keep proper sprite scale?  (Read 8365 times)

0 Members and 1 Guest are viewing this topic.

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Hello all! :D

When my program launches, it detects the screen resolution, and full screens to that resolution. The only problem I have with this is the following:

1, If I used big graphics "for making the game on a big resolution" and they have a small screen, the images will look huge "at least I think they will".

2, If I make my images for lets say, 1920 - 1080 and someone changes the resolution to a standard, like 800 - 600. Then the sprites width will be resized more than its height causing deformities in the images.

So I'm not really sure how to handle these senarios and am looking for guidence/ideas that may work to hopefully, make it that I won't have to create a new image set for the whole game, for every possible resolution. "Because at this point it seems like that may be required." -_-'' So I figured I should worry about this before incorperating a menu screen or the rest of the game.

Anyways, I look foreward to hearing from you!

~Flash619

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10818
    • View Profile
    • development blog
    • Email
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #1 on: July 22, 2012, 11:03:41 pm »
Everything is on you to make work proberly. ;)

If you don't update the view of the window when the window gets resized every sprite will appeare to have resized too, when in fact the properties of the sf::View have been changed thus making the sprites look bigger or smaller.
You can easily prevent this by reacting to the Resize event with something like the following code:
        sf::Vector2f size = static_cast<sf::Vector2f>(mWindow.getSize());

        // Minimum size
        if(size.x < 800)
                size.x = 800;
        if(size.y < 600)
                size.y = 600;

        // Apply possible size changes
        mWindow.setSize(static_cast<sf::Vector2u>(size));
        sf::View GUIView(sf::FloatRect(0.f, 0.f, size.x, size.y));
        mWindow.setView(GUIView);
This even guarantees that they can't resize the window to a smaller size than 800x600. If you have an option menu for changing the resolution this won't be necessary and you could go with:
mWindow.setView(GUIView(sf::FloatRect(0.f, 0.f, mWindow.getSize().x, mWindow.getSize().y)));

Now this will set everything to the same size, thus the content won't actually change you'll just see more or less of the whole scene. This may not be the wanted effect.
If you want the sprites to actually get enlarged but keeping the screen ratio you can do this by forcing one side to always match the other in the wanted ratio (as I force to a minimal size) and not changing the view to keep the scaling.

As a side note: If the view doesn't match the window 1:1 you can use window.convertCoords() to match the mouse position with the view position.

If you have trouble understand the view you should take a look at my tutorial: Using sf::View
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #2 on: July 23, 2012, 12:11:58 am »
Everything is on you to make work proberly. ;)

If you don't update the view of the window when the window gets resized every sprite will appeare to have resized too, when in fact the properties of the sf::View have been changed thus making the sprites look bigger or smaller.
You can easily prevent this by reacting to the Resize event with something like the following code:
        sf::Vector2f size = static_cast<sf::Vector2f>(mWindow.getSize());

        // Minimum size
        if(size.x < 800)
                size.x = 800;
        if(size.y < 600)
                size.y = 600;

        // Apply possible size changes
        mWindow.setSize(static_cast<sf::Vector2u>(size));
        sf::View GUIView(sf::FloatRect(0.f, 0.f, size.x, size.y));
        mWindow.setView(GUIView);
This even guarantees that they can't resize the window to a smaller size than 800x600. If you have an option menu for changing the resolution this won't be necessary and you could go with:
mWindow.setView(GUIView(sf::FloatRect(0.f, 0.f, mWindow.getSize().x, mWindow.getSize().y)));

Now this will set everything to the same size, thus the content won't actually change you'll just see more or less of the whole scene. This may not be the wanted effect.
If you want the sprites to actually get enlarged but keeping the screen ratio you can do this by forcing one side to always match the other in the wanted ratio (as I force to a minimal size) and not changing the view to keep the scaling.

As a side note: If the view doesn't match the window 1:1 you can use window.convertCoords() to match the mouse position with the view position.

If you have trouble understand the view you should take a look at my tutorial: Using sf::View

Oh I also forgot, how do you handle x/y positions on the window then?

I would rather have the window, not be able to be resized by the mouse courser and rather have it be an options menu only option. Is there a way to disable manual resize?

Quote
If you want the sprites to actually get enlarged but keeping the screen ratio you can do this by forcing one side to always match the other in the wanted ratio (as I force to a minimal size) and not changing the view to keep the scaling.

o.O'' That confused me a bit...

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10818
    • View Profile
    • development blog
    • Email
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #3 on: July 23, 2012, 12:18:50 am »
Oh I also forgot, how do you handle x/y positions on the window then?
x/y position of what? :o

If you mean the mouse, then there's the sf::Mouse::getPosition()...

I would rather have the window, not be able to be resized by the mouse courser and rather have it be an options menu only option. Is there a way to disable manual resize?
You haven't read the window tutorial, haven't you? ::)

o.O'' That confused me a bit...
Yeah it's a bit tricky and I'm not sure if it's worth explaining since it may not be what you want exactly (this implies the questions: What do you want exactly? ;)).

Also I still recommend to read the view tutorial because you need to know what's going on when dealing with diffrent resolutions etc. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #4 on: July 23, 2012, 01:46:28 am »
Oh I also forgot, how do you handle x/y positions on the window then?
x/y position of what? :o

If you mean the mouse, then there's the sf::Mouse::getPosition()...

I would rather have the window, not be able to be resized by the mouse courser and rather have it be an options menu only option. Is there a way to disable manual resize?
You haven't read the window tutorial, haven't you? ::)

o.O'' That confused me a bit...
Yeah it's a bit tricky and I'm not sure if it's worth explaining since it may not be what you want exactly (this implies the questions: What do you want exactly? ;)).

Also I still recommend to read the view tutorial because you need to know what's going on when dealing with diffrent resolutions etc. ;)

X/Y Positions of the sprites on the screen. I figure that 1920 by 1080 may have more x/y cordinates for positioning items, in compairison with 800/600. Its a lot less pixels.  ::)

I did read the window tutorial, though, I was only able to see how to enable window resizing.... I never saw anything that said anything about it having a title bar/close/minimize option, but still having no resize option. Currently the setting that is by default, is "sf::Style::Fullscreen" If that helps. But if someone wanted to run it in wondowed mode, I'm not sure on how to create the code for disabling the resize. I know that I have to figure out how to do it,  :P Thats obvious, but I don't know what code does what if you know what I mean, nor in the tutorial did I locate any style that had the discription "Disables window resizing." ::) If only it were that simple. xD

What do I want? I want it that I won't have to re create a image set for the at least 5 different groups of resolution. I would like it that it attempts to scale, but if it ends up throwing it out of proportion too badly, I may make it that instead it simply shows more area *preffered method* and just doesn't change the position of any sprites. "such as resizing them. "Not to mention I still will have to break some ground when it comes to using videos for animations in conjunction with sprites and getting the sizes properly setup. >_>"

Hope that helps. If I decide to go the long route, I may make different image sets, but that seems like a lot of added file size. :/
« Last Edit: July 23, 2012, 01:52:21 am by Flash619 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10818
    • View Profile
    • development blog
    • Email
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #5 on: July 23, 2012, 01:56:34 am »
X/Y Positions of the sprites on the screen. I figure that 1920 by 1080 may have more x/y cordinates for positioning items, in compairison with 800/600. Its a lot less pixels.  ::)
You still don't understand what the view does, right? :-\

Thats obvious, but I don't know what code does what if you know what I mean, nor in the tutorial did I locate any style that had the discription "Disables window resizing." ::) If only it were that simple. xD
If you don't add the resize style you won't be able to resize it, duh! :o ::)

What do I want? I want it that I won't have to re create a image set for the at least 5 different groups of resolution. I would like it that it attempts to scale, but if it ends up throwing it out of proportion too badly
Yeah that's what I've thought. You actually want the sprites to get automatically resized (your first post implied otherwise...) but want to keep the ratio.
So you first need to read the tutorial on the sf::View and maybe you'll understand it then on your own. If not I'll maybe take more of my freetime to explain it to you further. ;D

Hope that helps. If I decide to go the long route, I may make different image sets, but that seems like a lot of added file size. :/
Depending on the supported screen sizes this can still be a good root to go, since scaling up (or down) to a big size will lose a lot of the textures quality...

Another solution is to keep the size and just change the view's size so you'll get a black frame around the game (or you can decorate the black frame of course).
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #6 on: July 23, 2012, 02:03:19 am »
Another solution is to keep the size and just change the view's size so you'll get a black frame around the game (or you can decorate the black frame of course).

Well as I said, what would be really nice is, well, I'll just list what I'll probably shoot for quickly.

1, Atomatic changing sprites "yes I will make the bigger/smaller ones because after all, it seems a lot less tedious and probably would take less cpu than having to scale and resize a bunch of sprites... " "...Possibly have it that they do scale between, but bigger changes call for new images".... not sure yet... I'll have to think about it.

and 2, upon the window getting bigger, say, standard to widescreen, I would like to make the new two usable areas, usable instead of there being black bars, for instance, showing more map terrain or something like that. A usable map space, only instead of it being black, just increasing the render area. :) *hope I will find a way to do that.*

But yea, thats my plan.... I think.. xD

I'll just throw a call in the engine reload sequence that will automatically check the new resolution to a class that sets a flag to all other classes to properly load the correct sized images. :D
« Last Edit: July 23, 2012, 02:09:04 am by Flash619 »

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #7 on: July 23, 2012, 06:32:34 pm »
X/Y Positions of the sprites on the screen. I figure that 1920 by 1080 may have more x/y cordinates for positioning items, in compairison with 800/600. Its a lot less pixels.  ::)
You still don't understand what the view does, right? :-\

Thats obvious, but I don't know what code does what if you know what I mean, nor in the tutorial did I locate any style that had the discription "Disables window resizing." ::) If only it were that simple. xD
If you don't add the resize style you won't be able to resize it, duh! :o ::)

What do I want? I want it that I won't have to re create a image set for the at least 5 different groups of resolution. I would like it that it attempts to scale, but if it ends up throwing it out of proportion too badly
Yeah that's what I've thought. You actually want the sprites to get automatically resized (your first post implied otherwise...) but want to keep the ratio.
So you first need to read the tutorial on the sf::View and maybe you'll understand it then on your own. If not I'll maybe take more of my freetime to explain it to you further. ;D

Hope that helps. If I decide to go the long route, I may make different image sets, but that seems like a lot of added file size. :/
Depending on the supported screen sizes this can still be a good root to go, since scaling up (or down) to a big size will lose a lot of the textures quality...

Another solution is to keep the size and just change the view's size so you'll get a black frame around the game (or you can decorate the black frame of course).

So I read the sf::View tutorial today, and have a few questions...

1, there's no 3D interaction. Doesn't that make it impossible to display more rendering area without scaling it? Say for instance, not zooming or anything, but just displaying more rendering area or "view area" of the program?

2. "What you're now actually can set with setCenter is the where origin of the rendering coordinate system is put in the coordinate system of the view." ...So thats setting the center view point for the "camera" looking at the rendered sprites correct? Then in that case, any rotations would use this as the axis for the rotation?

3, "sf::View view(origin.x, origin.y, size.width, size.height);" Would that, say, if you set a larger size to match the change between standard/widescreen, be able to display more ground/menu area if the width variable is changed? Or would it just stretch it?

4, lastly, "Convert Cords" ...  Iwould like to know some more about it. I also, in it's description, am not sure what you refer to as "Point P" Say you had a rectangle for seeing if the user clicked a sprite. So you set the rectangle to the same size/position of that sprite. But then lets say the view changed, wouldn't that rectangle move with the sprite?

finally just a side question. I take it, it would not be possible, to use sf::view to rotate everything but NOT rotate certain sprites without a seperate viewport?

If any of that seems confusing, or you would like me to rephrase my questions, just ask.  ;)

I look foreward to hearing from you! :D
« Last Edit: July 23, 2012, 06:34:21 pm by Flash619 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10818
    • View Profile
    • development blog
    • Email
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #8 on: July 23, 2012, 07:13:34 pm »
1, there's no 3D interaction. Doesn't that make it impossible to display more rendering area without scaling it? Say for instance, not zooming or anything, but just displaying more rendering area or "view area" of the program?
See the answer for question number 3.

2. "What you're now actually can set with setCenter is the where origin of the rendering coordinate system is put in the coordinate system of the view." ...So thats setting the center view point for the "camera" looking at the rendered sprites correct? Then in that case, any rotations would use this as the axis for the rotation?
Yes every view rotation will happen around the view center point.

3, "sf::View view(origin.x, origin.y, size.width, size.height);" Would that, say, if you set a larger size to match the change between standard/widescreen, be able to display more ground/menu area if the width variable is changed? Or would it just stretch it?
Yes. Imagine the view as some kind of a window to the coordinate system the sprite lives in. When you make the size larger then you can see more of the content of the coordinate system, if you make it smaller you see less of it.
Next to that you can now use the viewport to match all you can see through that window (view) onto another card/wall (render target i.e. render window) that can have a diffrent size than the window (view) but still keeping the same amount of things you can see through that window (view). Now if the viewport and the size do not match things will get strechted which can be a wanted effect but can also be an unwanted.

4, lastly, "Convert Cords" ...  Iwould like to know some more about it. I also, in it's description, am not sure what you refer to as "Point P" Say you had a rectangle for seeing if the user clicked a sprite. So you set the rectangle to the same size/position of that sprite. But then lets say the view changed, wouldn't that rectangle move with the sprite?
Yeah that paraggraph got a bit shortened, because I only got to know convertCoords() a bit before I wanted to publish the tutorial and had to put it somehow in there.
It just converts a pixel on the render target (i.e. window) to the underlying coordinate system.
Yes the contains() function only works for aligned axis, if you rotate the view or the sprite you can't use that collision detection... (Maybe I should point that out.)


finally just a side question. I take it, it would not be possible, to use sf::view to rotate everything but NOT rotate certain sprites without a seperate viewport?
Yes and no. You can rotate the whole view and then counter rotate the sprites you don't want to get rotate, but this could also lead to some unwanted sideeffects because of the problems with floats.
In the end I guess it's more of a design question. If your sprites are always located normally then you should use a second view but if they are actually part of all the others but actuall counter rotate then you should also counter rotate them.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #9 on: July 23, 2012, 07:30:21 pm »
Yes. Imagine the view as some kind of a window to the coordinate system the sprite lives in. When you make the size larger then you can see more of the content of the coordinate system, if you make it smaller you see less of it.
Next to that you can now use the viewport to match all you can see through that window (view) onto another card/wall (render target i.e. render window) that can have a diffrent size than the window (view) but still keeping the same amount of things you can see through that window (view). Now if the viewport and the size do not match things will get strechted which can be a wanted effect but can also be an unwanted.
But *just making sure* Say I change the veiw size while the program is running, would that throw off everythings cordinates? How does it handle the cord's for the new view area?


Yeah that paraggraph got a bit shortened, because I only got to know convertCoords() a bit before I wanted to publish the tutorial and had to put it somehow in there.
It just converts a pixel on the render target (i.e. window) to the underlying coordinate system.
Yes the contains() function only works for aligned axis, if you rotate the view or the sprite you can't use that collision detection... (Maybe I should point that out.)

So from what you're saying. It would be a bit difficult to perfect. ...Collision detection???

So with sf::view, you would be able to have two viewports, but have them display different data?

mateandmetal

  • Full Member
  • ***
  • Posts: 171
  • The bird is the word
    • View Profile
    • my blog
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #10 on: July 23, 2012, 09:54:16 pm »
You can let the user select the resolution he/she wants in your game settings screen. Then you can check if the resolution selected is widescreen, and load the ws images, if it´s not, load the "fullscreen?" ones. It´s very simple:

float ratio = (float) mode.width / mode.height;

bool isWidescreen = ratio < 1.4f ? false : true;
 


For "fullscreen" (4:3 and 5:4) modes ratio is around 1,333...
- Mate (beverage) addict
- Heavy metal addict _lml
- SFML 2 addict
- My first (and free) game: BichingISH!

Flash619

  • Full Member
  • ***
  • Posts: 142
    • View Profile
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #11 on: July 23, 2012, 10:23:03 pm »
You can let the user select the resolution he/she wants in your game settings screen. Then you can check if the resolution selected is widescreen, and load the ws images, if it´s not, load the "fullscreen?" ones. It´s very simple:

float ratio = (float) mode.width / mode.height;

bool isWidescreen = ratio < 1.4f ? false : true;
 


For "fullscreen" (4:3 and 5:4) modes ratio is around 1,333...

In your code, what doe "mode" represent? The render window? or....

I am planning on implamenting something like this tho. Its nice to see an example ^_^ Thanks for that.

I'll probably end up creating a seperate class for being a image/sprite handler that will automatically return sprites/images as a reference and get the correct image based off of these variables for simplicity. :)
« Last Edit: July 23, 2012, 10:25:55 pm by Flash619 »

mateandmetal

  • Full Member
  • ***
  • Posts: 171
  • The bird is the word
    • View Profile
    • my blog
Re: Widescreen/Standard How to detect and keep proper sprite scale?
« Reply #12 on: July 24, 2012, 08:28:03 pm »
In your code, what doe "mode" represent? The render window? or....

Your game window resolution


I'll probably end up creating a seperate class for being a image/sprite handler that will automatically return sprites/images as a reference and get the correct image based off of these variables for simplicity. :)


Ok, but you have to load more resources (memory wasted)
- Mate (beverage) addict
- Heavy metal addict _lml
- SFML 2 addict
- My first (and free) game: BichingISH!