Pygame closes despite while loop - python

When I run pygame the window opens for a fraction of a second and then immediately closes. I followed multiple tutorials and followed them word for word but the problem still continues.
import pygame
pygame.init()
(width, height) = (300, 300)
window = pygame.display.set_mode((width,height))
run = True
while run:
window.fill(255,255,200)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
The window doesn't fill either so it feels like the while loop never runs in the first place.

The argument of fill needs to be a tuple with 3 components, instead of 3 separate arguments:
window.fill(255,255,200)
window.fill( (255, 255, 200) )

Related

Pygame window is not showing up

I have python 3.10.5 and Pygame 2.1.2. I dont know whats happening, but my window is not showing up. i have tried changing the code a bit, but nothing seems to be working.
import pygame
WIDTH, HEIGHT = 900, 500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
def main():
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if __name__ == '__main__':
main()
I tried out your initial code and found some bits missing as noted in the comments. I did not see any reference to what color would be used for filling your screen along with the missing "display.flip(). Keeping the spirit of your initial code as much intact as possible, following is a code snippet that does present a white game window.
import pygame
pygame.init()
WIDTH, HEIGHT = 900, 500
WIN = pygame.display.set_mode((WIDTH, HEIGHT))
def main():
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
WIN.fill((255, 255, 255)) # Added this
pygame.display.flip() # And this
pygame.quit()
if __name__ == '__main__':
main()
You might also want to check out the following link for other tips Pygame Primer.

pygame.error: video system not initialize, using Repl.it

I get this error when I try to run my pygame code pygame.error: video system not initialized. I'm using Repl.it and am attempting to create an aiming game which can track accuracy and in which you only have 3 lives.
import pygame
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False # Here we exit the Loop and execute what after
pygame.quit()
# Play Surface
width = 1080
height = 720
playSurface = pygame.display.set_mode((width, height))
pygame.display.set_caption('Aim Practice')
# Colors
red = pygame.Color(0, 0, 0)
blue = pygame.Color(255, 255, 255)
Image of most of the code
https://repl.it/join/dppwnpin-isa__paz (You can view the full code here!)
The issue is that you event loop is running before anything is initialised. As #zenofpython says in his answer, the calls to prepare the window must come before the main event loop.
Your main event loop is first, and nothing is setup to run.
Just moving the code around will fix it:
import pygame
# FIRST, HANDLE ALL THE INITIALISATION OF PYGAME, FONTS, MIXER etc.
# Play Surface
width = 1080
height = 720
playSurface = pygame.display.set_mode((width, height))
pygame.display.set_caption('Aim Practice')
# Colors
red = pygame.Color(0, 0, 0)
blue = pygame.Color(255, 255, 255)
# ... AND THE REST
# MAIN LOOP
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False # Here we exit the Loop and execute what after
playSurface.fill( blue ) # fill the screen
pygame.display.flip() # flush all the drawing operations to the window
fpsController.tick_busy_loop(60) # clamp the max-FPS
pygame.quit()
You should use pygame.display.set_mode before running your event loop. pygame.event.get won't work if you haven't created a window.

Display disappears when i try to resize it [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.

Python + Pygame; screen.fill() crashing window

Whenever I try to include "screen.fill(insert value here)" to my pygame code, the window instantly crashes. I can comment it out and my code works just fine. I'm really not sure why.
I've tried moving the line around, using other people's code in part - no luck.
import pygame
pygame.init()
win = pygame.display.set_mode((1000, 800))
pygame.display.set_caption("Tetris")
img=pygame.image.load("C:\\Users\\Charlotte\\Desktop\\tetris_grid.png")
win.blit(img,(450, 150))
running = True
while running:
screen.fill(0, 0, 0)
pygame.display.update()
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
When I run the code with that line in it, the window opens and then it instantly closes.
If you are trying to fill the screen with black, the color must be passed as a tuple:
win.fill((0, 0, 0))
Also, you never assign screen, maybe you intended to use win?
The doc for Surface.fill.
The color parameter to fill() has to be either a single grayscale value or a tuple of 3 RGB or 4 RGBA components. So it has to be either:
win.fill(0)
or
win.fill((0, 0, 0))
Further you've to blit() the image in the main loop. To continuously draw the scene in the main application loop, you've to:
handle the events
clear the window
draw the scene (blit the image)
update the display
Furthermore I recommend to use tick() of pygame.time.Clock rather than pygame.time.delay() tpo control the frames per second.
import pygame
pygame.init()
win = pygame.display.set_mode((1000, 800))
pygame.display.set_caption("Tetris")
clock = pygame.time.Clock()
img=pygame.image.load("C:\\Users\\Charlotte\\Desktop\\tetris_grid.png")
running = True
while running:
clock.tick(60)
# handle the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# clear the display
win.fill(0)
# draw the scene
win.blit(img,(450, 150))
# update the display
pygame.display.update()
pygame.quit()

pygame display resize automatically

To resize the display, I would write code like this:
pygame.display.set_mode((1000, 500), pygame.RESIZABLE)
But I don't like the display frame, so I decided to reject it:
pygame.display.set_mode((1000, 500), pygame.NOFRAME, pygame.RESIZABLE)
And the problem is start here, I wanna resize the display automatically as pressing a key, or clicking a button inside the pygame window, but I cannot resize my pygame display, automatically.
I did try some code like this(parts of codes):
resize_y = 0 # Don't resize when the program start
console = pygame.display.set_mode((370, 500+resize_y), pygame.NOFRAME, pygame.RESIZABLE) # Expands by resize_y
def main():
main = True
while main:
for event in pygame.event.get(): #skip quit code
if event.type == pygame.KEYDOWN and event.key == pygame.K_d:
resize_y += 100 #Add resize_y
console.fill((255, 255, 255)) # Fill background with white
pygame.display.update()
main() # call main
There was no Error message, didn't work, and of course I expected extenting display when I press D.
How can I fix?
First of all, all flags have to be passed to set_mode with the single the flags argument. In your code, you pass RESIZABLE as the depth argument. Use or to set multiple flags.
Second, you write:
To resize the display, I would write code like this: pygame.display.set_mode((1000, 500), pygame.RESIZABLE)
but you don't actually call pygame.display.set_mode after changing resize_y.
You're code should look more like this:
import pygame
def main():
resize_y = 0 # Don't resize when the program start
console = pygame.display.set_mode((370, 500+resize_y), pygame.NOFRAME or pygame.RESIZEABLE) # Expands by resize_y
running = True
while running:
for event in pygame.event.get(): #skip quit code
if event.type == pygame.QUIT:
return
if event.type == pygame.KEYDOWN and event.key == pygame.K_d:
resize_y += 100 #Add resize_y
console = pygame.display.set_mode((370, 500+resize_y), pygame.NOFRAME or pygame.RESIZEABLE)
console.fill((255, 255, 255)) # Fill background with white
pygame.display.update()
main() # call main
But note that the RESIZABLE flag is basically useless in combination with the NOFRAME flag. If you want to change the size of the window within your code, you don't need RESIZABLE and can savely remove it. Use it only when the user should be able to resize the window.

Categories