I have a window in pygame set up like this:
screen = pygame.display.set_mode((WINDOWWIDTH, WINDOWHEIGHT),pygame.RESIZABLE)
As you can see, it is resizable, and that aspect is working perfectly, but if it is too small, then you can not see everything, and so I would like to set up a limit, of for example, you can not resize the screen to have a width os less then 600, or a height of less then 400, is there a way to do that in pygame?
Thank you!
You can use the pygame.VIDEORESIZE event to check the new windows size on a resize.
What you do is on the event, you check the new windows size values, correct them according to your limits and then recreate the screen object with those values.
Here is a basic script:
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640,480), HWSURFACE|DOUBLEBUF|RESIZABLE)
while True:
pygame.event.pump()
event = pygame.event.wait()
if event.type == QUIT: pygame.display.quit()
else if event.type == VIDEORESIZE:
width, height = event.size
if width < 600:
width = 600
if height < 400:
height = 400
screen = pygame.display.set_mode((width,height), HWSURFACE|DOUBLEBUF|RESIZABLE)
EDIT: Depending on how your game graphics are drawn, you may want to resize them according to the windows resize (haven't tested that, just going after this example: http://www.pygame.org/wiki/WindowResizing)
Related
I was wondering if anyone out there would be able to help me with my problem. Currently I want to display a pause screen everytime a certain key is pressed, which it does however the resulting screen is always either fully transparent or non-transparent and was wondering if there was any way that I would be able to adjust the following code in order to make that dream a reality.
Here's where the Pause Screen is called:
if event.key == pygame.K_p:
notPaused = False
#print("Obtained")
pause = Pause(self.pauseScreen)
while notPaused == False:
#print("Received")
notPaused = pause.processEvents()
print(str(notPaused))
pause.displayFrame(self.pauseScreen)
clock = pygame.time.Clock()
clock.tick(60)
And here's how the pause screen displays itself:
screen.fill(constants.BLACK)
font = pygame.font.SysFont("serif", 25)
for counter in range(1,5):
text = font.render(self.options[counter-1], True, constants.WHITE)
center_x = 150
center_y = (counter * 120) - (text.get_height() // 2) + (self.pointer.image.get_height() // 2)
screen.blit(text, [center_x, center_y])
self.active_sprite_list.draw(screen)
pygame.display.flip()
And for anyone wondering I sometimes try to sub out BLACK for ABLACK using the RGBA values of: (0,0,0,125)
Finally this is where the screen is initialized for the pause screen:
self.size = [constants.SCREEN_WIDTH, constants.SCREEN_HEIGHT]
self.pauseScreen = pygame.Surface(self.size,pygame.SRCALPHA,32)
Any and all help is appreciated.
You should build up your pause screen as a separate surface. This command: screen.fill(constants.BLACK) all but ensures you will never get 50% transparency (since everything that was on your screen before has been painted over with black).
Build a new surface for your pause screen, fill it black, add your text; then use something like my_pause_surface.set_alpha(128) to make that whole surface 50% transparent, then blit it on top of the rest of your game.
Here is some useful information in another question: Draw a transparent rectangle in pygame
UPDATED ISSUE
I have discovered the issue appears to be with the fact that I am using the FULLSCREEN display flag to create the window. I added a rectangle to be drawn in the top left of the scree (0, 0), but when I run the program, It is mostly off the screen. Then, when I Alt-Tab away and back, the rectangle is appropriately placed at 0,0 and the turret is off center.
So basically, when the program starts, the game screen is larger than my actual screen, but centered. Then after Alt-Tab, the game screen is lined up with 0,0 but since the game screen is larger than my screen, the turret looks off center, but is actually centered relative to the game.
So the real question is why does using the FULLSCREEN display flag make a screen larger than my computer screen?
ORIGINAL ISSUE
I am building a simple demonstration of a turret in the center of the screen which follows the location of the cursor as if to fire where it is. Everything works perfectly until I Alt-Tab away from the screen, and then Alt-Tab back. At this point to turret is now off center (down and to the right)
import pygame, math
pygame.init()
image_library = {}
screen_dimen = pygame.display.Info()
print("Screen Dimensions ", screen_dimen)
def get_image(name):
if name not in image_library:
image = pygame.image.load(name)
image_library[name] = image
else:
image = image_library[name]
return image
robot_turret_image = get_image('robot_turret.png')
screen = pygame.display.set_mode((0, 0), pygame.`FULLSCREEN`)
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEMOTION:
print(event.pos)
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
done = True
screen.fill((0, 0, 0))
pos = pygame.mouse.get_pos()
angle = 360 - math.atan2(pos[1] - (screen_dimen.current_h / 2),
pos[0] - (screen_dimen.current_w / 2)) * 180 / math.pi
rot_image = pygame.transform.rotate(robot_turret_image, angle)
rect = rot_image.get_rect(center=(screen_dimen.current_w / 2, screen_dimen.current_h / 2))
screen.blit(rot_image, rect)
color = (0, 128, 255)
pygame.draw.rect(screen, color, pygame.Rect(0, 0, 200, 200))
pygame.display.update()
clock.tick(60)
It seems that the center is now off. I have printed out the screen dimensions before and after the Alt-Tab and they are the same, so I can't figure out why the image moves. I believe I am missing something regarding state changes with Pygame, but can't figure out what. If it is relevant, I am on Windows 10.
Alright, I discovered a solution from gamedev.stackexchange
And I will re-hash it here. The issue was that Using the fullscreen tag was making a screen larger than my computer screen. The following code solves this
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
true_res = (ctypes.windll.user32.GetSystemMetrics(0), ctypes.windll.user32.GetSystemMetrics(1))
pygame.display.set_mode(true_res,pygame.FULLSCREEN)
It is important to note that this is potentially just a windows fix, but I do not have another system with which to test it on. But It works on Windows 10 with python 3.5.1 and pygame 1.9.2a0
i started learning pygame and i followed some tutorials to make simple hello world project and it works but when i do it my self trying to display my image on the window nothing happen!
this is my code
__author__ = 'mohammed'
import sys
import pygame
import color
# -----------setup------------------------
pygame.init() # start pygame
screensize = (800, 600) # variable that we will use to declare screen size
screen = pygame.display.set_mode(screensize) # set the screen size
pad = pygame.image.load('2.png')
x = 100
y = 100
# -----------setup------------------------
# -------------------main loop------------
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
screen.blit(pad, (x, y))
screen.fill(red)
pygame.display.update()
i am importing my file that contain colors and their rgb :
red = (255, 0, 0)
It looks like you're filling the screen after the image is drawn, covering the image. Try switching the order of the rows:
screen.blit(pad, (x, y))
and
screen.fill(red)
UPDATED ISSUE
I have discovered the issue appears to be with the fact that I am using the FULLSCREEN display flag to create the window. I added a rectangle to be drawn in the top left of the scree (0, 0), but when I run the program, It is mostly off the screen. Then, when I Alt-Tab away and back, the rectangle is appropriately placed at 0,0 and the turret is off center.
So basically, when the program starts, the game screen is larger than my actual screen, but centered. Then after Alt-Tab, the game screen is lined up with 0,0 but since the game screen is larger than my screen, the turret looks off center, but is actually centered relative to the game.
So the real question is why does using the FULLSCREEN display flag make a screen larger than my computer screen?
ORIGINAL ISSUE
I am building a simple demonstration of a turret in the center of the screen which follows the location of the cursor as if to fire where it is. Everything works perfectly until I Alt-Tab away from the screen, and then Alt-Tab back. At this point to turret is now off center (down and to the right)
import pygame, math
pygame.init()
image_library = {}
screen_dimen = pygame.display.Info()
print("Screen Dimensions ", screen_dimen)
def get_image(name):
if name not in image_library:
image = pygame.image.load(name)
image_library[name] = image
else:
image = image_library[name]
return image
robot_turret_image = get_image('robot_turret.png')
screen = pygame.display.set_mode((0, 0), pygame.`FULLSCREEN`)
done = False
clock = pygame.time.Clock()
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEMOTION:
print(event.pos)
if event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE:
done = True
screen.fill((0, 0, 0))
pos = pygame.mouse.get_pos()
angle = 360 - math.atan2(pos[1] - (screen_dimen.current_h / 2),
pos[0] - (screen_dimen.current_w / 2)) * 180 / math.pi
rot_image = pygame.transform.rotate(robot_turret_image, angle)
rect = rot_image.get_rect(center=(screen_dimen.current_w / 2, screen_dimen.current_h / 2))
screen.blit(rot_image, rect)
color = (0, 128, 255)
pygame.draw.rect(screen, color, pygame.Rect(0, 0, 200, 200))
pygame.display.update()
clock.tick(60)
It seems that the center is now off. I have printed out the screen dimensions before and after the Alt-Tab and they are the same, so I can't figure out why the image moves. I believe I am missing something regarding state changes with Pygame, but can't figure out what. If it is relevant, I am on Windows 10.
Alright, I discovered a solution from gamedev.stackexchange
And I will re-hash it here. The issue was that Using the fullscreen tag was making a screen larger than my computer screen. The following code solves this
import ctypes
ctypes.windll.user32.SetProcessDPIAware()
true_res = (ctypes.windll.user32.GetSystemMetrics(0), ctypes.windll.user32.GetSystemMetrics(1))
pygame.display.set_mode(true_res,pygame.FULLSCREEN)
It is important to note that this is potentially just a windows fix, but I do not have another system with which to test it on. But It works on Windows 10 with python 3.5.1 and pygame 1.9.2a0
If I set a pygame window to resizable and then click and drag on the border of the window the window will get larger but nothing blit onto the surface will get larger with it. (Which is understandable) How would I make it so that when I resize a window all blit objects resize with it and fill the window properly?
For example: Say I have a window of 200 x 200 and I blit a button at window_width/2 and window_height/2. The button would be in the center of the window at 100 x 100. Now if I resize the window to 300 x 300 the button stays at 100 x 100 instead of 150 x 150.
I tried messing around with pygame.Surface.get_width ect, but had no luck.
Basically I'm trying to resize a program's window and have all blit images stay proportionate.
Don't draw on the screen directly, but on another surface. Then scale that other surface to size of the screen and blit it on the screen.
Here's a simple example:
import pygame
from pygame.locals import *
def main():
pygame.init()
screen = pygame.display.set_mode((200, 200),HWSURFACE|DOUBLEBUF|RESIZABLE)
fake_screen = screen.copy()
pic = pygame.surface.Surface((50, 50))
pic.fill((255, 100, 200))
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.display.quit()
elif event.type == VIDEORESIZE:
screen = pygame.display.set_mode(event.size, HWSURFACE|DOUBLEBUF|RESIZABLE)
fake_screen.fill('black')
fake_screen.blit(pic, (100, 100))
screen.blit(pygame.transform.scale(fake_screen, screen.get_rect().size), (0, 0))
pygame.display.flip()
main()
so without the gui initialization (pygame init, and setmode comands ) in the section where you have existing pygame event get()(which your only allowed one time (or just put in ''for inkey in pygame.event.get(VIDEORESIZE):''(
if you want to be redundant))(note you can only use ''for inkey in pygame.event.get(VIDEORESIZE):'' one time per loop because it is really a stack that unstacks when you read the event list so you should really use ''for inkey in pygame.event.get():'' snd put all your key recognission statements after this one occurrance of ''for inkey in pygame.event.get():'':
for inkey in pygame.event.get(VIDEORESIZE)
if inkey.type == pygame.VIDEORESIZE:
winwidth,winhight = inkey.size # or event.w, event.h
Window1copy = Window1.copy()# make copy of existing window
Window1=pygame.display.set_mode((winwidth,winhight),pygame.RESIZABLE)
Window1.blit(Window1copy, (0, 0))
pygame.display.update()
Recently with pygame2.0 You can use the SCALED flag