Pygame display.info giving wrong resolution size - python

I'm building a small game with pygame. I want the window of the game to be size of the monitors resolution. My computers screen's resolution is 1920x1080 and display.info says the window size is also 1920x1080 but when I run it, it creates a window roughly one and half times the size of my screen.
import pygame, sys
def main():
#set up pygame, main clock
pygame.init()
clock = pygame.time.Clock()
#creates an object with the computers display information
#current_h, current_w gives the monitors height and width
displayInfo = pygame.display.Info()
#set up the window
windowWidth = displayInfo.current_w
windowHeight = displayInfo.current_h
window = pygame.display.set_mode ((windowWidth, windowHeight), 0, 32)
pygame.display.set_caption('game')
#gameLoop
while True:
window.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#draw the window onto the screen
pygame.display.flip()
clock.tick(60)
main()

I've been having the same problem, and I managed to find the answer and posted it here. The answer I found is as follows:
I managed to find a commit on the Pygame BitBucket page here that explains the issue and gives an example on how to fix it.
What is happening is that some display environments can be configured to stretch windows so they don't look small on high PPI (Pixels Per Inch) displays. This stretching is what causes displays on larger resolutions to display larger than they actually are.
They provide an example code on the page I linked to showing how to fix this issue.
They fix the issue by importing ctypes and calling this:
ctypes.windll.user32.SetProcessDPIAware()
They also express that this is a Windows only solution and is available within base Python since Python 2.4. Before that it will need to be installed.
With that said, to make this work, put this bit of code anywhere before pygame.display.set_mode()
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
#
# # # Anywhere Before
#
pygame.display.set_mode(resolution)
I hope this helps you and anyone else who finds they have this same issue.

Related

Pygame Display Position While Running

I am making a pygame project, and have an issue where the window sets itself in the corner of the screen when I back out of full screen mode. Normally, this wouldn't be an issue but it hides the toolbar off screen, making it impossible to drag the screen around or resize it. I have found pygame.display.toggle_fullscreen() to be far to unreliable and breaks whenever I use it, so I made my own method of toggling fullscreen:
import pygame, tkinter
fullscr = False
scrw, srch = tkinter.Tk().winfo_screenwidth(), tkinter.Tk().winfo_screenheight()
while True:
for event in pygame.event.get():
if event.type == pygame.KEYUP:
if event.key == pygame.K_F11:
if fullscr:
screen = pygame.display.set_mode((scrw, scrh), pygame.RESIZABLE)
screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
else:
screen = pygame.display.set_mode((980, 720), pygame.RESIZABLE)
fullscr = not fullscr
For those curious, I set the window to fill the screen before setting it to fullscreen because the window will maintain its aspect ratio, breaking my game and causing weird glitches. I am already aware of os.environ['SDL_VIDEO_CENTERED'] = '1' as a way to center the screen, but this does not work after running pygame.init(). Are there any other ways I can change the windows position, or at least prevent it from hiding the toolbar off screen when toggling out of fullscreen?
This is a pygame 2 bug.
It's reported on github here: https://github.com/pygame/pygame/issues/2360,
and the author there realized that you can get around this for now by calling pygame.quit() and then reinitializing to have the SDL_VIDEO_CENTERED work.
Hopefully this will be fixed in pygame 2.0.2. I've written a patch for it at https://github.com/pygame/pygame/pull/2460

Why does my pygame window not fit in my 4k(3840x2160) monitor? scale of pygame window: (3000x1500)

So I was trying to make a game with python and pygame but I noticed that I couldn't make a high resolution display because when I tried to make a display with more pixels, the pygame window was too big for my 4k (3840x2160) monitor. I should note that my monitor is connected to an old Dell laptop with a resolution of (1366x768). But when I entered this: print(pygame.display.list_modes()) it told me that I could use resolutions up to 4k and not just up to the resolution of my laptop. After a lot of searching and trying I accepted the fact that my game will be low resolution and moved on. As I continued coding the game I wanted to have a pop-up window so I imported pyautogui and my pygame window suddenly became much smaller. BOOM problem solved. I increased the resolution and I had no problems, my game was now running at a very high resolution! I was very confused so I made a very simple pygame program so I could test this and it actually worked. This is low quality and can't fit in my screen:
import pygame
import sys
pygame.init()
screen = pygame.display.set_mode((3000, 1500))
font = pygame.font.Font('font.otf', 50)
while True:
screen.fill((255, 255, 255))
txt = font.render("hello", True, (0, 0, 0))
screen.blit(txt, (100, 100))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screenshot1
And this is high resolution and does fit in my screen:
import pygame
import sys
import pyautogui
pygame.init()
screen = pygame.display.set_mode((3000, 1500))
font = pygame.font.Font('font.otf', 50)
while True:
screen.fill((255, 255, 255))
txt = font.render("hello", True, (0, 0, 0))
screen.blit(txt, (100, 100))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screenshot2
I don't even need to use pyautogui!
Can someone explain this to me?
Thanks
After a bunch of source diving I believe I have found the solution: pyautogui imports pyscreeze for the functions center, grab, pixel, pixelMatchesColor, screenshot. On lines 63 to 71 of pyscreeze/__init__.py is the following:
if sys.platform == 'win32':
# On Windows, the monitor scaling can be set to something besides normal 100%.
# PyScreeze and Pillow needs to account for this to make accurate screenshots.
# TODO - How does macOS and Linux handle monitor scaling?
import ctypes
try:
ctypes.windll.user32.SetProcessDPIAware()
except AttributeError:
pass # Windows XP doesn't support monitor scaling, so just do nothing.
The above code calls SetProcessDPIAware, which is equivalent to the following:
System DPI aware. This window does not scale for DPI changes. It will query for the DPI once and use that value for the lifetime of the process. If the DPI changes, the process will not adjust to the new DPI value. It will be automatically scaled up or down by the system when the DPI changes from the system value.
If want to get the same effect without pyautogui you can just include the above call to SetProcessDPIAware in your code.

Screen not showing on Mac using pygame

I'm doing a tutorial for using pygame to make games, and I'm having a problem getting a screen to show up. Here is what I have so far:
import pygame
# Initialize the pygame
pygame.init()
# Create the screen, height = 800, width = 600
screen = pygame.display.set_mode((800, 600))
# Game Loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
I have pygame installed, and have no errors or warnings in PyCharm. When I run this (both in PyCharm and my terminal), I get no screen showing, and all that happens is the spaceship of the python runner is bouncing in my dock. When I run this exact code on my pc, it shows a black screen, which is the desired outcome.
Can anyone help, or am I doing something wrong?
Thank you for your assistance.
I have no problem running your code on a Mac. However, the window showing up is a grey one, not black.
In order to force the display of the window, you can add this after the screen creation:
pygame.display.update()
And to try to figure out the problem,you may want to add a text in the window bar, that may generate a message pointing to your problem.
pygame.display.set_caption("Hello world")

Force a fullscreen resolution that is not contained in display.list_modes()

I'm making a simulation for school and I'm trying to make pygame create a fullscreen display in my native resolution. However, I have a QHD screen (2560x1440), and it isn't working properly. As far as I can tell, pygame is rendering a screen at the correct resolution, but expanding it so it is scaled as if it were 1080p, so about 300-400 pixels are cut off around the edges. This causes, for example, a circle rendered at (200,200) to be completely invisible. After some research, I learned that this is because pygame doesn't officially support my resolution (it is not listed in pygame.display.list_modes()). Is there any way to force it to work? I would prefer if I could use my actual resolution instead of upscaled 1080p.
Here is the code that initializes the window:
import pygame
from pygame.locals import *
pygame.init()
w = pygame.display.Info().current_w
h = pygame.display.Info().current_h
S = pygame.display.set_mode((w,h), pygame.FULLSCREEN)
If you are using Windows, make sure in your display settings you have scaling set to 100%. This will make your text and everything smaller if you don't have it at that currently but I think Pygame windows get affected by this number for some reason.
See the below code snippet for making sure your window scales properly. Also see here.
import pygame
from ctypes import windll
def run():
# Force windows to ignore the display scaling value.
windll.user32.SetProcessDPIAware()
pygame.display.init()
# Make the screen the highest resolution that will fit the screen at 100% scaling.
screen = pygame.display.set_mode(pygame.display.list_modes()[0])
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
done = True
pygame.display.flip()
pygame.quit()
if __name__ == "__main__":
run()

Pygame borderless opening with some offset

When i try to open a borderless mode window it does start in the top right corner of the screen. It looks like this: http://puu.sh/ivB4y/304018da5e.jpg The code looks like this
if __name__ == "__main__":
import source.Game, pygame
pygame.mixer.pre_init(22050, 16, 2, 256)
pygame.font.init()
pygame.init()
screen = pygame.display.set_mode((1920, 1080), pygame.NOFRAME)
source.Game.Game().main(screen)
It might be worth noting that I'm running two monitors, but I've tried only running one and the problem still happens, and if I take the resolution down below native it still won't start in the top right of my screen.
Is there any way to fix such a problem?
EDIT:
I went this from the answers for anyone looking on this in the future.
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "0,0"
screen = pygame.display.set_mode((1920, 1080), pygame.NOFRAME)
along with all the other .init() statements and whatnot.
Looks like you want fullscreen:
screen = pygame.display.set_mode((1920, 1080), pygame.FULLSCREEN)
You might also want to turn on hardware acceleration adn double buffering using pygame.HWSURFACE | pygame.DOUBLEBUF if you are running fullscreen.
display.set_mode docs: https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode
If you actually want to keep the OS's bar on screen, then instead of going fullscreen, then ideally you would just maximize the window after creating it. However, the version of the SDL lib that Pygame is built on does not support a maximize operation (SDL 2 does). Apparently, you can control the position of the window by setting an environment variable before initializing the window (yuck), but you would still need to figure out the usable area of the desktop. Example:
import os
os.environ['SDL_VIDEO_WINDOW_POS'] = "0,0"
import pygame
pygame.init()
screen = pygame.display.set_mode((100,100))

Categories