Search code examples
pythonpygamefullscreen

How to avoid automatic resolution adjustment by pygame.FULLSCREEN?


I am using pygame to create an application that needs a square screen, 800x800. It works fine when it's windowed i.e. when I simply do:

screen_width = 800
screen_height = 800
screen = pygame.display.set_mode((screen_width, screen_height))

or

flags = NOFRAME
screen = pygame.display.set_mode((screen_width, screen_height), flags)

But when I use the fullscreen flag, my game window gets stretched to a widescreen resolution, making it non-square and also stretched to fit in fullscreen. What I think it's doing is it's automatically picking the closest resolution from the list of supported resolutions:

print(pygame.display.list_modes())
[(1920, 1080), (1920, 1080), (1920, 1080), (1920, 1080), (1920, 1080), (1920, 1080), (1680, 1050), (1680, 1050), (1680, 1050), (1600, 900), (1600, 900), (1600, 900), (1440, 900), (1440, 900), (1440, 900), (1440, 576), (1440, 576), (1440, 576), (1440, 576), (1440, 480), (1440, 480), (1440, 480), (1440, 480), (1440, 480), (1400, 1050), (1400, 1050), (1400, 1050), (1366, 768), (1366, 768), (1366, 768), (1360, 768), (1360, 768), (1360, 768), (1280, 1024), (1280, 1024), (1280, 1024), (1280, 1024), (1280, 960), (1280, 960), (1280, 960), (1280, 800), (1280, 800), (1280, 800), (1280, 768), (1280, 768), (1280, 768), (1280, 720), (1280, 720), (1280, 720), (1280, 600), (1280, 600), (1280, 600), (1152, 864), (1152, 864), (1152, 864), (1152, 864), (1024, 768), (1024, 768), (1024, 768), (1024, 768), (800, 600), (800, 600), (800, 600), (800, 600), (720, 576), (720, 576), (720, 576), (720, 480), (720, 480), (720, 480), (640, 480), (640, 480), (640, 480), (640, 480), (640, 400), (640, 400), (640, 400), (512, 384), (512, 384), (512, 384), (400, 300), (400, 300), (400, 300), (320, 240), (320, 240), (320, 240), (320, 200), (320, 200), (320, 200)]

But what I'd like it to do is for the window to remain unstretched i.e. remain in the same size as it is as using the pygame.NOFRAME flag or no flag, and to remain square (1:1 aspect ratio). I need it to be fullscreen, so the areas outside the 800x800 window can just be black areas.

I've looked around but I can't find a way to avoid this automatic adjustment that pygame does when going fullscreen. I'd appreciate any help.


Solution

  • In fullscreen mode, you do not need to use NOFRAME, because this flag just removes the top bar, which is not visible in fullscreen mode.

    You have several options when using fullscreen:

    1. Scale the window to make it occupy the entire screen, leaving black areas in order to keep the window ratio. It looks like this:
    screen = pygame.display.set_mode((800,800), FULLSCREEN|SCALED)
    


    1. Leave black areas around the window. Simply use the FULLSCREEN flag alone.

    In this situation, depending on your platform, your entire screen can either be resized (second image), or not be changed; in this case you will have black borders around the window (first image).

    I think that the platform that you are using prefers to adapt your screen resolution, to prevent from having black borders around, resulting in stretching the PyGame window (second image). If it is the case, then prefer the first solution, as it also prevents from several notifications or problems coming from the strange resolution change.

    Sometimes your system will always remove the black borders, especially in PyGame 2.0.x. In this case, if you still want the black borders, you can use this code to add them back.

    screen = pygame.display.set_mode((800, 800), FULLSCREEN)
    

    or


    1. You can also use this code to define a PyGame window whose size is your screen resolution:
    size = pygame.display.Info()
    screen = pygame.display.set_mode((size.current_w, size.current_h), FULLSCREEN)