pygame-community / pygame-ce

🐍🎮 pygame - Community Edition is a FOSS Python library for multimedia applications (like games). Built on top of the excellent SDL library.
https://pyga.me
814 stars 127 forks source link

Allowing to adjust the scaling factor with pygame.SCALED (3575) #1762

Open GalacticEmperor1 opened 1 year ago

GalacticEmperor1 commented 1 year ago

Issue №3575 opened by karat-1 at 2022-11-18 13:27:59

Description

The performance when using the SCALED flag is really good especially when not wanting to use pygame._sdl2

The only downside is that we can not adjust the resolution, it will always go to the biggest possible resolution.

I do believe it would be a lot more useful if we could at least change the scaling factor via another flag (e.g. instead of scaling up to 1920x1080 it would only scale up to 1280x720).


Comments

gresm commented 10 months ago

Maybe also some way to limit the window size (minimal, maximal, only specified proportions, etc...).

bigwhoopgames commented 9 months ago

This would be fantastic.

gresm commented 9 months ago

Just FYI to anyone running into this problem, you can actually achieve this without too much trouble using a couple functions from pygame._sdl2. In particular, you can create a HIDDEN | SCALED display using set_mode, grab the window using _sdl2.Window.from_display_module(), set its size to the exact dimensions you want (in screen-space), and then show() the window. Then you'll have a SCALED window with whatever initial scale factor you want.

Here's an example:

import pygame
import pygame._sdl2 as sdl2

pygame.init()

WIDTH, HEIGHT = (256, 128)
flags = pygame.SCALED
flags |= pygame.RESIZABLE  # optional

# create the display in "hidden" mode, because it isn't properly sized yet
pygame.display.set_mode((WIDTH, HEIGHT), flags | pygame.HIDDEN)

# choose the initial scale factor for the window
initial_scale_factor = 3  # <-- adjustable
window = sdl2.Window.from_display_module()
window.size = (WIDTH * initial_scale_factor, HEIGHT * initial_scale_factor)
window.position = sdl2.WINDOWPOS_CENTERED
window.show()

# bonus: specify the color of the out-of-bounds area in RESIZABLE mode (it's black by default)
OUTER_FILL_COLOR = "plum4"
renderer = sdl2.Renderer.from_window(window)
renderer.draw_color = pygame.Color(OUTER_FILL_COLOR)

clock = pygame.time.Clock()

while True:
    for e in pygame.event.get():
        if e.type == pygame.QUIT:
            raise SystemExit
    screen = pygame.display.get_surface()
    screen.fill("black")

    t = pygame.time.get_ticks() / 1000
    pygame.draw.circle(screen, "gray40", ((30 * t) % WIDTH, (20 * t) % HEIGHT), 16)
    pygame.draw.circle(screen, "gray50", ((-20 * t) % WIDTH, (30 * t) % HEIGHT), 24)
    pygame.draw.circle(screen, "gray60", ((100 + 50 * t) % WIDTH, (30 - 10 * t) % HEIGHT), 32)

    pygame.display.flip()
    clock.tick(60)

Originally posted by @davidpendergast in https://github.com/pygame/pygame/issues/3575#issuecomment-1436060895