[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Fixed aspect ratio scaling



Casey,

Can you paste that into the pygame cookbook - it's a pretty nice bit of code :)

Phil

Casey Duncan <casey@xxxxxxxxxxx> wrote:
On May 31, 2007, at 1:03 AM, John Eriksson wrote:

> Hi,
>
> Does anyone know about a good solution on the stretching problem when
> running in fullscreen mode on a widescreen monitor?
>
> For windows users having an nvidia driver it's possible to set "Fixed
> aspect ratio scaling" as an option for the display causing the
> widescreen to have black borders at the sides.
>
> But are there any platform independent solutions to this?
>
> I guess it might be possible to solve this using code, creating a
> correct sized display and then blitt the game screen to it's centered.
>
> But this (I guess) can cause some performance loss. And I don't
> know if
> it's even possible to detect the best screen resolution to use.
> As far as I know there are no way to determine the current screen
> resolution (to calculate the monitors aspect ratio) of the system?

Is the problem that your game expects a fixed-resolution and
therefore a fixed aspect ratio? Regardless if your game demands a
fixed aspect ratio then on some monitors you must either letter-box
the screen or stretch everything to fit. You seem to be hinting at
doing the latter, but that causes undesireable distortion (i.e.,
circles become ovals, etc).

Here is my suggested solution to this problem:

- Make your game resolution independent. That is, distances in the
game are independent of pixel size.

- Make either the horizontal or vertical screen distance fixed,
perhaps matching it to the "ideal" screen size (e.g., 1280 or 1600)

- At game startup let pygame pick the resolution by default or allow
it to be overridden by user preference. Figure out the scale by
dividing the fixed screen distance by the actual screen resolution.
Then scale all of your graphics accordingly. If you are using sprite
images, rotozoom works excellent (just zoom everything at load-time)
and is very fast.

You get several benefits from this:

- You can pretty easily implement a zoom in/out feature by varying
the fixed screen distance.

- Users can select lower resolutions to trade quality for performance
or vice versa. Some resolutions may be letterboxed, but the user can
decide if this is objectionable, many times it isn't.

To get at the screen resolution use the surface object returned from
pygame.display.set_mode(), call get_rect() on it to figure out the
screen res.

Here is some code I wrote to select the screen res from four user
resolution settings: max, high, med and low. It is intended to pick
sizes that fit the aspect ratio of the screen in fullscreen mode,
where possible. It also favors portrait orientation (for those of us
with pivoting monitors).

screen_sizes = {
'max': ((0, 100000), (1280, 1024)),
'high': ((650, 800), (1024, 768)),
'med': ((500, 649), (800, 600)),
'low': ((400, 499), (640, 480))
}
(min_height, max_height), window_size = screen_sizes[resolution]
if fullscreen:
modes = pygame.display.list_modes()
# Choose the first mode with a height in the desired range
for mode in modes:
if min_height <= mode[1] <= max_height and mode[0] > mode[1]:
break
else:
mode = modes[0]
print "Could not find ideal display mode, using", mode
screen = pygame.display.set_mode(mode, FULLSCREEN)
else:
screen = pygame.display.set_mode(window_size)
screen_rect = screen.get_rect()

hth,

-Casey




Shape Yahoo! in your own image. Join our Network Research Panel today!