pygame-How to replace an image with an other one - python

I have this sort of code:
width = 100
height = 50
gameDisplay.blit(button, (width, height))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
# replace the button's image with another
Is there any function or something that would let me replace the image with another?

You cannot 'replace' anything you've drawn. What you do is that you draw new images over the existing ones. Usually, you clear the screen and redraw your images every loop. Here's pseudo-code illustrating what a typical game loop looks like. I'll use screen as variable name instead of gameDisplay, because gameDisplay goes against PEP-8 naming convention.
while True:
handle_time() # Make sure your programs run at constant FPS.
handle_events() # Handle user interactions.
handle_game_logic() # Use the time and interactions to update game objects and such.
screen.fill(background_color) # Clear the screen / Fill the screen with a background color.
screen.blit(image, rect) # Blit an image on some destination. Usually you blit more than one image using pygame.sprite.Group.
pygame.display.update() # Or 'pygame.display.flip()'.
For your code you probably should do something like this:
rect = pygame.Rect((x_position, y_position), (button_width, button_height))
while True:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
button = new_button # Both should be a pygame.Surface.
gameDisplay.fill(background_color, rect) # Clear the screen.
gameDisplay.blit(button, rect)
pygame.display.update()
If you only want to update the area where your image is you could pass rect inside the update method, pygame.display.update(rect).

To show changes on screen use pygame.display.update().
Your code should look like this
width = 100
height = 50
gameDisplay.blit(button, (width, height))
while True:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONUP and event.button == 1:
gameDisplay.blit(new_button, (width, height))
pygame.display.update()

Related

surface doesn't disappear at the next frame

I'm pretty new to Python and programming in general.
I'm trying to draw a square (200px by 200px) on the screen when the user clicks on the screen.
I tried to create a surface and a rect around the surface ( when the user clicks on the screen) and then using the rect, placed the surface on the screen using the blit method.
for the x and y of the rect I used mouse position.
So, this in my head should have changed the position of the square whenever a user clicks somewhere else on the screen but it rather creates a new square every time.
so I have a couple of questions:
If the way I'm implementing this is wrong, then how can I implement this feature?
Shouldn't the square change place as Pygame draws it every frame?
Thank you :)
pygame.init()
# --- Column --------------- #
col_num = 8
col_size = 120
# --- Screen --------------- #
screen = pygame.display.set_mode((col_num * col_size, col_num * col_size))
screen.fill((255, 255, 255))
draw_board()
# --- Clock ---------------- #
clock = pygame.time.Clock()
white_player = Player()
# --- test surface --------- #
surface = pygame.Surface((200, 200))
surface.fill((255, 255, 255))
# --- Main Loop ------------ #
check = False
while True:
white_player.draw_piece()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit(), sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
check = True
a_rect = surface.get_rect(center=pygame.mouse.get_pos())
print('here!')
if check:
screen.blit(surface, a_rect)
pygame.display.update()
clock.tick(60)
Output:
Even trying with a simple surface and a screen it doesn't work.
It adds another surface to the screen with the new x.
import pygame as pg
import sys
pg.init()
screen = pg.display.set_mode((400, 400))
clock = pg.time.Clock()
surface = pg.Surface((200, 200))
surface.fill((255, 255, 255))
xpos = 50
while True:
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit(), sys.exit()
xpos += 1
screen.blit(surface, (xpos, 100))
pg.display.flip()
clock.tick(60)
Oh, I just realized I forgot to fill the screen before each frame. fixed

Pygame window resizing isn't working correctly [duplicate]

I am trying to allow resizing for this app, I put the RESIZABLE flag, but when I try to resize, it messes up! Try my code.
It is a grid program, when the window resizes I want the grid to also resize/shrink.
import pygame,math
from pygame.locals import *
# Define some colors
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
# This sets the width and height of each grid location
width=50
height=20
size=[500,500]
# This sets the margin between each cell
margin=1
# Initialize pygame
pygame.init()
# Set the height and width of the screen
screen=pygame.display.set_mode(size,RESIZABLE)
# Set title of screen
pygame.display.set_caption("My Game")
#Loop until the user clicks the close button.
done=False
# Used to manage how fast the screen updates
clock=pygame.time.Clock()
# -------- Main Program Loop -----------
while done==False:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
if event.type == pygame.MOUSEBUTTONDOWN:
height+=10
# Set the screen background
screen.fill(black)
# Draw the grid
for row in range(int(math.ceil(size[1]/height))+1):
for column in range(int(math.ceil(size[0]/width))+1):
color = white
pygame.draw.rect(screen,color,[(margin+width)*column+margin,(margin+height)*row+margin,width,height])
# Limit to 20 frames per second
clock.tick(20)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit ()
Please tell me whats wrong, thanks.
The answer for this problem (allow the Pygame window and the surface inside it to resize) is simply to recreate the resizable window with an updated size, when the user changes its dimensions (done on pygame.VIDEORESIZE events).
>>> import pygame
>>> help(pygame.display.set_mode)
Help on built-in function set_mode in module pygame.display:
set_mode(...)
set_mode(size=(0, 0), flags=0, depth=0, display=0, vsync=0) -> Surface
Initialize a window or screen for display
>>>
This removes all previous content on the window surface, so below
there's a process to continue with the current window content.
Some example code:
import pygame, sys
pygame.init()
# Create the window, saving it to a variable.
surface = pygame.display.set_mode((350, 250), pygame.RESIZABLE)
pygame.display.set_caption("Example resizable window")
while True:
surface.fill((255,255,255))
# Draw a red rectangle that resizes with the window.
pygame.draw.rect(surface, (200,0,0), (surface.get_width()/3,
surface.get_height()/3, surface.get_width()/3,
surface.get_height()/3))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
if event.type == pygame.VIDEORESIZE:
# There's some code to add back window content here.
surface = pygame.display.set_mode((event.w, event.h),
pygame.RESIZABLE)
How to continue with the current window content:
Here's some steps to add back the previous window content:
make a second variable, set to the value of the old window surface variable.
create the new window, storing it as the old variable.
draw the second surface onto the first one (old variable) - use the blit function.
use this variable and delete the new variable (optional, use del) to not use extra memory.
Some example code for the above steps (replaces pygame.VIDEORESIZE event if statement):
if event.type == pygame.VIDEORESIZE:
old_surface_saved = surface
surface = pygame.display.set_mode((event.w, event.h),
pygame.RESIZABLE)
# On the next line, if only part of the window
# needs to be copied, there's some other options.
surface.blit(old_surface_saved, (0,0))
del old_surface_saved
You are not updating your width, height, or size when the window changes.
From the docs: http://www.pygame.org/docs/ref/display.html
If the display is set with the pygame.RESIZABLE flag,
pygame.VIDEORESIZE events will be sent when the user adjusts the
window dimensions.
You can get the new size, w, h from the event VIDEORESIZE http://www.pygame.org/docs/ref/event.html
A simple Hello World window that is resizable, plus I was playing around with classes.
Broken down into two files, one for defining the colour constants.
import pygame, sys
from pygame.locals import *
from colors import *
# Data Definition
class helloWorld:
'''Create a resizable hello world window'''
def __init__(self):
pygame.init()
self.width = 300
self.height = 300
DISPLAYSURF = pygame.display.set_mode((self.width,self.height), RESIZABLE)
DISPLAYSURF.fill(WHITE)
def run(self):
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == VIDEORESIZE:
self.CreateWindow(event.w,event.h)
pygame.display.update()
def CreateWindow(self,width,height):
'''Updates the window width and height '''
pygame.display.set_caption("Press ESC to quit")
DISPLAYSURF = pygame.display.set_mode((width,height),RESIZABLE)
DISPLAYSURF.fill(WHITE)
if __name__ == '__main__':
helloWorld().run()
colors.py:
BLACK = (0, 0,0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
BLUE = (0,0,255)
GREEN = (0,255,0)
A simple way to do which I found was the following code snippet
# Imports
from vars import *
from pygame.locals import *
# Main init
pygame.init()
# Basic vars
run = True
s_width = 1000
s_height = 600
# Making display screen. Don't forget the last tag!
screen = pygame.display.set_mode((s_width, s_height), RESIZABLE)
# Main loop
while run:
# event detection
for event in pygame.event.get():
if event.type == QUIT:
run = False
# The part which matters for our purposes
if event.type == WINDOWRESIZED:
s_width, s_height = screen.get_width(), screen.get_height()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
run = False
# Test line to see if the window resizing works properly
pygame.draw.line(screen, (255, 255, 255), (int(0.3*s_width), int(0.25*s_height)), (int(0.8*s_width), int(0.25*s_height)))
# Final flip
pygame.display.flip()
# Quit
pygame.quit()
What this does is allows the pygame window to be resized. But since you often have the placing and sizes of a lot of elements/sprites depending on the s_width and s_height, it also detects when the window size is changed and adjusts the dimensions accordingly.
First, You don't detect the new window size before redrawing the screen.
Add the get_size() method at line 45 and it works:
#--------------------------------------------------------------
# Draw the grid
size = pygame.display.get_surface().get_size() // size update
for row in range(int(math.ceil(size[1]/height))+1):
#---------------------------------------------------------
Then you work with a fixed cell size (50, 20) and fill as many cells as possible. If You want to GROW/SHRINK the cells when resizing the window, You will have to define the NUMBER of cells per line/row, then calculate the cell size, then draw them.

Pygame, move a square on the screen, but can not erase the previous movements

This is my first post in StackOverflow, hope you guys can help a newbie programmer. It's Pygame Python simple ask.
I am trying to move a square on the screen, but can not erase the previous movements.
import pygame
pygame.init()
screen = pygame.display.set_mode((400,300))
pygame.display.set_caption("shield hacking")
JogoAtivo = True
GAME_BEGIN = False
# Speed in pixels per frame
x_speed = 0
y_speed = 0
cordX = 10
cordY = 100
def desenha():
quadrado = pygame.Rect(cordX, cordY ,50, 52)
pygame.draw.rect(screen, (255, 0, 0), quadrado)
pygame.display.flip()
while JogoAtivo:
for evento in pygame.event.get():
print(evento);
#verifica se o evento que veio eh para fechar a janela
if evento.type == pygame.QUIT:
JogoAtivo = False
pygame.quit();
if evento.type == pygame.KEYDOWN:
if evento.key == pygame.K_SPACE:
print('GAME BEGIN')
desenha()
GAME_BEGIN = True;
if evento.key == pygame.K_LEFT and GAME_BEGIN:
speedX=-3
cordX+=speedX
desenha()
if evento.key == pygame.K_RIGHT and GAME_BEGIN:
speedX=3
cordX+=speedX
desenha()
You have to draw over the previous image. Easiest is to fill the screen with a background color in the beginning of the game loop, like so:
screen.fill((0, 0, 0))
I am doing something similar and I hope this helps
import pygame
clock=pygame.time.Clock() #the frames per second BIF in pygame
pygame.init()
FPS=30
display_width=800
display_height=600
white=(255,255,255)
black=(0,0,0)
block_size=10
gameExit=False
lead_x = display_width / 2
lead_y = display_height / 2
lead_x_change = 0 # 0 beacuse we will not be changing the position in the beginning
lead_y_change = 0
gameDisplay=pygame.display.set_mode((display_width,display_height))
while not gameExit: #game loop
for event in pygame.event.get(): #event handling BIF in pygame EVENT LOOP
#print(event) # prints out the position of the mouse and the buttons pressed when in game window
if event.type== pygame.QUIT: #if the user presses the [x] in game window, it quits the window
gameExit=True
if event.key == pygame.K_LEFT:
lead_x_change = -block_size #block size is number of pixels moved in one loop
lead_y_change=0
elif event.key==pygame.K_RIGHT:
lead_x_change= block_size
lead_y_change=0
elif event.key==pygame.K_UP:
lead_y_change= -block_size
lead_x_change=0
elif event.key==pygame.K_DOWN:
lead_y_change= block_size
lead_x_change=0
lead_y+=lead_y_change
lead_x+=lead_x_change
gameDisplay.fill(white) #fills the display surface object, backgroud color is the parameter filled in
pygame.draw.rect(gameDisplay,black,[lead_x,lead_y,block_size,block_size])
pygame.display.update() #after done with all the action,update the surface
clock.tick(FPS) #runs the game at 30FPS
pygame.quit()
quit()
You also can draw everything from a previous surface, before the square was in place, then draw the square on it always in a different place.
Then draw the new surface to screen each time.
But not really good strategy, it can be slow and/or induce flickering.
For instance:
# Draw anything to the display surface named screen, then do:
# By display surface I mean the surface returned by pygame.display.set_mode()
orig = screen.copy()
# Sometimes it will not be filled with a image from screen that you have drawn before, so you draw
# all to orig surface
# Then you make a surface that will be shown on the screen and do:
s = pygame.surface.Surface()
s.blit(orig, 0, 0)
# Then you draw the rectangle or whatever on s, and then:
screen.blit(s, 0, 0)
pygame.display.flip()
# and you keep orig as a starting point for every move
If you have many movable objects on the screen simultaneously this is good, or if you are refreshing restricted areas only, else redraw over the last image as suggested in other answer.
If you go about drawing directly to the display surface flicker will be bigger and sometimes, especially when display is hardware accelerated you will have problems. On non desktop devices like mobile phones especially. Drawing over and adding new usually works fine directly on display surface and would be the correct approach to your problem.
I know I sound contradictive, but some stuff you simply must see for yourself. Get experience by experimenting.

Python Pygame won't quit

The code colors a pixel one by one and essentially prints a picture. I can't get it to quit though if I press the X to close or if I press Esc. I've put all the pg.event.get() code outside the main while loop, inside the main while loop, inside the secondary for loop, inside the tertiary for loop. I've ran it using IDLE and Spyder and same issue, no matter where I put it, I can't get it to quit. How can I get it to work????
loop = True
while loop:
#Event Management for exiting the screen
for event in pg.event.get():
keys = pg.key.get_pressed()
if event.type == pg.QUIT:
loop = False
elif keys[pg.K_ESCAPE]:
loop = False
pg.event.pump()
#Setup pixel transformation loop
for i in range(0,463):
for u in range (0,600):
screen.set_at((u,i),reddat[u,i]-greendat[u,i]-bluedat[u,i])
pg.display.flip()
loop = False
You're doing the whole pixel transformation without checking for events. Here's your flow in pseudo code:
loop until break:
check events
loop through pixels
transform pixels
break
Instead, you should ditch the while loop, make check_for_quit a function and then put that function nested in your transformation loop.
def check_for_quit():
"""Event Management for exiting the screen"""
for event in pg.event.get():
keys = pg.key.get_pressed()
if event.type == pg.QUIT:
return True
elif keys[pg.K_ESCAPE]:
return True
pg.event.pump()
return False
def draw():
"""Setup pixel transformation loop"""
for i in range(0,463):
for u in range (0,600):
if check_for_quit():
return
screen.set_at((u,i),reddat[u,i]-greendat[u,i]-bluedat[u,i])
pg.display.flip()
Instead of using a while loop you can have check_for_quit return True or False to indicate whether or not to quit, and then you can test that in each loop and return to exit the loop early when it's over.
Note I don't work with pygame, so while this should work it might not be the best solution for running code while trying to check for events.
During the pixel transformation loop you are not running the anything to detect events. You were on the right track about moving the loops about.
if you shift the event checking code into the pixel transformation loop you can poll events while generating the pixels
Example:
for i in range(0,463):
for u in range (0,600):
screen.set_at((u,i),reddat[u,i]-greendat[u,i]-bluedat[u,i])
for event in pg.event.get():
if event.type == pg.QUIT:
break
elif event.type == py.KEYDOWN:
if event.key == py.K_SPACE:
break
pg.display.flip()
This removes the need for a while loop aswell.
Thank you all for your help, I did move the event loops into the for loop reorganised them by seperating the key event as below. This worked for me. Regarding the image, the goal of this was to display the image pixel by pixel soo that's why I blitted each loop. Anyway,Appreciate your comments. Next time I think a quit function would be very useful so will set one of them up.
Here's what worked for me
for u in range (0,600):
for i in range(0,463):
screen.set_at((i,u),(reddat[u,i],greendat[u,i],bluedat[u,i]))
pg.display.flip()
#Event Management for exiting the screen
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
keys = pg.key.get_pressed()
if keys[pg.K_ESCAPE]:
pg.quit()
pg.event.pump()
First, your event loop looks weird. I think you should use either for event in pg.event.get(): or keys = pg.key.get_pressed() but not both.
I'm not sure if you just want to create a background surface or a build-up effect. Also, you should've explained what the variables reddat, etc. are.
If you just want a background image you only need to create a surface before the main loop, blit the pixels onto the surface and then blit it on the screen in the main loop.
Elif you want the build-up, you could use a generator to get the pixels and then use itertools.islice to get chunks of it. Here's an example of the build-up:
import sys
import pygame as pg
from itertools import islice
def generate_pixels(width, height):
"""Generate pixel coords for the build-up effect."""
for i in range(height):
for u in range(width):
yield i, u
def main():
clock = pg.time.Clock()
width, height = (640, 480)
screen = pg.display.set_mode((width, height))
pixels = generate_pixels(width, height)
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
done = True
# Change the second arg of islice to adjust the speed.
for i, u in islice(pixels, 2000):
screen.set_at((u, i), (i % 256, u % 256, (i + u) % 256))
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()
Edit: There's a simpler way to create a build-up effect: You can pass an area argument to the blit method of surfaces. So we can create the final image beforehand (or load one) and then just increase the percentage of the image that we want to blit on the display surface.
import sys
import pygame as pg
def main():
clock = pg.time.Clock()
width, height = (640, 480)
screen = pg.display.set_mode((width, height))
# Create the final image beforehand.
image = pg.Surface((width, height))
for i in range(height):
for u in range(width):
image.set_at((u, i), (i % 256, u % 256, (i + u) % 256))
image_percent = 0
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
if event.type == pg.KEYDOWN:
if event.key == pg.K_ESCAPE:
done = True
screen.fill((90, 10, 200))
# Increase the displayed portion of the image.
if image_percent < 100:
image_percent += .5
# The third argument is the area of the surface on which we'll
# blit the image.
screen.blit(image, (0, 0), (0, 0, width/100*image_percent, height))
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()
sys.exit()

Allowing resizing window pyGame

I am trying to allow resizing for this app, I put the RESIZABLE flag, but when I try to resize, it messes up! Try my code.
It is a grid program, when the window resizes I want the grid to also resize/shrink.
import pygame,math
from pygame.locals import *
# Define some colors
black = ( 0, 0, 0)
white = ( 255, 255, 255)
green = ( 0, 255, 0)
red = ( 255, 0, 0)
# This sets the width and height of each grid location
width=50
height=20
size=[500,500]
# This sets the margin between each cell
margin=1
# Initialize pygame
pygame.init()
# Set the height and width of the screen
screen=pygame.display.set_mode(size,RESIZABLE)
# Set title of screen
pygame.display.set_caption("My Game")
#Loop until the user clicks the close button.
done=False
# Used to manage how fast the screen updates
clock=pygame.time.Clock()
# -------- Main Program Loop -----------
while done==False:
for event in pygame.event.get(): # User did something
if event.type == pygame.QUIT: # If user clicked close
done=True # Flag that we are done so we exit this loop
if event.type == pygame.MOUSEBUTTONDOWN:
height+=10
# Set the screen background
screen.fill(black)
# Draw the grid
for row in range(int(math.ceil(size[1]/height))+1):
for column in range(int(math.ceil(size[0]/width))+1):
color = white
pygame.draw.rect(screen,color,[(margin+width)*column+margin,(margin+height)*row+margin,width,height])
# Limit to 20 frames per second
clock.tick(20)
# Go ahead and update the screen with what we've drawn.
pygame.display.flip()
# Be IDLE friendly. If you forget this line, the program will 'hang'
# on exit.
pygame.quit ()
Please tell me whats wrong, thanks.
The answer for this problem (allow the Pygame window and the surface inside it to resize) is simply to recreate the resizable window with an updated size, when the user changes its dimensions (done on pygame.VIDEORESIZE events).
>>> import pygame
>>> help(pygame.display.set_mode)
Help on built-in function set_mode in module pygame.display:
set_mode(...)
set_mode(size=(0, 0), flags=0, depth=0, display=0, vsync=0) -> Surface
Initialize a window or screen for display
>>>
This removes all previous content on the window surface, so below
there's a process to continue with the current window content.
Some example code:
import pygame, sys
pygame.init()
# Create the window, saving it to a variable.
surface = pygame.display.set_mode((350, 250), pygame.RESIZABLE)
pygame.display.set_caption("Example resizable window")
while True:
surface.fill((255,255,255))
# Draw a red rectangle that resizes with the window.
pygame.draw.rect(surface, (200,0,0), (surface.get_width()/3,
surface.get_height()/3, surface.get_width()/3,
surface.get_height()/3))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
pygame.quit()
sys.exit()
if event.type == pygame.VIDEORESIZE:
# There's some code to add back window content here.
surface = pygame.display.set_mode((event.w, event.h),
pygame.RESIZABLE)
How to continue with the current window content:
Here's some steps to add back the previous window content:
make a second variable, set to the value of the old window surface variable.
create the new window, storing it as the old variable.
draw the second surface onto the first one (old variable) - use the blit function.
use this variable and delete the new variable (optional, use del) to not use extra memory.
Some example code for the above steps (replaces pygame.VIDEORESIZE event if statement):
if event.type == pygame.VIDEORESIZE:
old_surface_saved = surface
surface = pygame.display.set_mode((event.w, event.h),
pygame.RESIZABLE)
# On the next line, if only part of the window
# needs to be copied, there's some other options.
surface.blit(old_surface_saved, (0,0))
del old_surface_saved
You are not updating your width, height, or size when the window changes.
From the docs: http://www.pygame.org/docs/ref/display.html
If the display is set with the pygame.RESIZABLE flag,
pygame.VIDEORESIZE events will be sent when the user adjusts the
window dimensions.
You can get the new size, w, h from the event VIDEORESIZE http://www.pygame.org/docs/ref/event.html
A simple Hello World window that is resizable, plus I was playing around with classes.
Broken down into two files, one for defining the colour constants.
import pygame, sys
from pygame.locals import *
from colors import *
# Data Definition
class helloWorld:
'''Create a resizable hello world window'''
def __init__(self):
pygame.init()
self.width = 300
self.height = 300
DISPLAYSURF = pygame.display.set_mode((self.width,self.height), RESIZABLE)
DISPLAYSURF.fill(WHITE)
def run(self):
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == VIDEORESIZE:
self.CreateWindow(event.w,event.h)
pygame.display.update()
def CreateWindow(self,width,height):
'''Updates the window width and height '''
pygame.display.set_caption("Press ESC to quit")
DISPLAYSURF = pygame.display.set_mode((width,height),RESIZABLE)
DISPLAYSURF.fill(WHITE)
if __name__ == '__main__':
helloWorld().run()
colors.py:
BLACK = (0, 0,0)
WHITE = (255, 255, 255)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
BLUE = (0,0,255)
GREEN = (0,255,0)
A simple way to do which I found was the following code snippet
# Imports
from vars import *
from pygame.locals import *
# Main init
pygame.init()
# Basic vars
run = True
s_width = 1000
s_height = 600
# Making display screen. Don't forget the last tag!
screen = pygame.display.set_mode((s_width, s_height), RESIZABLE)
# Main loop
while run:
# event detection
for event in pygame.event.get():
if event.type == QUIT:
run = False
# The part which matters for our purposes
if event.type == WINDOWRESIZED:
s_width, s_height = screen.get_width(), screen.get_height()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
run = False
# Test line to see if the window resizing works properly
pygame.draw.line(screen, (255, 255, 255), (int(0.3*s_width), int(0.25*s_height)), (int(0.8*s_width), int(0.25*s_height)))
# Final flip
pygame.display.flip()
# Quit
pygame.quit()
What this does is allows the pygame window to be resized. But since you often have the placing and sizes of a lot of elements/sprites depending on the s_width and s_height, it also detects when the window size is changed and adjusts the dimensions accordingly.
First, You don't detect the new window size before redrawing the screen.
Add the get_size() method at line 45 and it works:
#--------------------------------------------------------------
# Draw the grid
size = pygame.display.get_surface().get_size() // size update
for row in range(int(math.ceil(size[1]/height))+1):
#---------------------------------------------------------
Then you work with a fixed cell size (50, 20) and fill as many cells as possible. If You want to GROW/SHRINK the cells when resizing the window, You will have to define the NUMBER of cells per line/row, then calculate the cell size, then draw them.

Categories

Resources