Python + Pygame; screen.fill() crashing window - python

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()

Related

pygame screen.fill command has undefined error

It looks like in pygame, screen command, like in screen.fill() is not in pygame. How do I set the background color?
Here is the code if needed:
pygame.display.set_mode([800, 600])
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
screen.fill((0, 0, 0))
pygame.display.update()
screen is not a built-in variable. It seems that in your case screen should be the pygame.Surface object associated with the display. This pygame.Surface is returned when the Pygame window is created with pygame.display.set_mode():
screen = pygame.display.set_mode([800, 600])
The other option is to get the display Surface with pygame.display.get_surface()
screen = pygame.display.get_surface()
screen.fill((0, 0, 0))

I am trying to insert a sprite image into pygame window and it wont pop up

(i followed a yt tut so idk) my code: idk if i put code in wrong place
import pygame
white = (255,255,255)
black = (0,0,0)
orange = (255,165,0)
player_sprite = pygame.image.load("will smith.png") .convert_alpha
pygame.init()
display = pygame.display.set_mode((850,850))
pygame.display.set_caption('Conners Game')
exit = False
while not exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit = True
print(event)
display.fill(white)
pygame.display.update()
pygame.quit()
quit()
not really sure why it does this, im new to python so idk
There are multiple things that needs to fixed. First of all to you actually need to blit the image on the screen.
while not exit:
for event in pygame.event.get():
#...[block of code]
display.fill(white)
display.blit(player_sprite, (100,100)) # BLIT IMAGE TO SCREEN
.convert_alpha() is a method and you need to call it after you initialize pygame and set the video mode.
You can read more about convert_alpha() here
pygame.init()
display = pygame.display.set_mode((850,850))
pygame.display.set_caption('Conners Game')
#converting it after init and setting game mode
player_sprite = pygame.image.load("will smith.png").convert_alpha()
Here's the final working code
import pygame
white = (255,255,255)
black = (0,0,0)
orange = (255,165,0)
pygame.init()
display = pygame.display.set_mode((850,850))
pygame.display.set_caption('Conners Game')
player_sprite = pygame.image.load("will smith.png").convert_alpha()
exit = False
while not exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit = True
# print(event)
display.fill(white)
display.blit(player_sprite, (100,100))
pygame.display.update()
pygame.quit()
quit()
You have to blit the image in the application loop, after clearing the display and before updating the display:
display.blit(player_sprite, (100, 100))
convert_alpha is function. You missed the parentheses
player_sprite = pygame.image.load("will smith.png").convert_alpha
player_sprite = pygame.image.load("will smith.png").convert_alpha()
Also, you cannot call a pygame function before you initialize pygame. pygame.init() should be the very first pygame function called.
Complete example:
import pygame
white = (255,255,255)
black = (0,0,0)
orange = (255,165,0)
pygame.init()
display = pygame.display.set_mode((850,850))
pygame.display.set_caption('Conners Game')
player_sprite = pygame.image.load("will smith.png").convert_alpha()
exit = False
while not exit:
for event in pygame.event.get():
if event.type == pygame.QUIT:
exit = True
print(event)
display.fill(white)
display.blit(player_sprite, (100, 100))
pygame.display.update()
pygame.quit()
quit()
The typical PyGame application loop has to:
limit the frames per second to limit CPU usage with pygame.time.Clock.tick
handle the events by calling either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by calling either pygame.display.update() or pygame.display.flip()

Rectangle not being drawn [duplicate]

This question already has answers here:
Why is my PyGame application not running at all?
(2 answers)
Closed 1 year ago.
When running this code:
import pygame,time
GREEN = (30, 156, 38)
WHITE = (255,255,255)
pygame.init()
screen = pygame.display.set_mode((640, 480))
screen.fill(WHITE)
pygame.draw.rect(screen, GREEN, (0,0,100,100))
time.sleep(3)
Pygame shows a black screen for 3 seconds, but doesn't draw a rectangle.
I am using Atom using script package to run code
You have to implement an application loop. The typical PyGame application loop has to:
handle the events by either pygame.event.pump() or pygame.event.get().
update the game states and positions of objects dependent on the input events and time (respectively frames)
clear the entire display or draw the background
draw the entire scene (blit all the objects)
update the display by either pygame.display.update() or pygame.display.flip()
limit frames per second to limit CPU usage
import pygame
GREEN = (30, 156, 38)
WHITE = (255,255,255)
pygame.init()
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock()
# applicaition loop
run = True
while run:
# limit frames per second
clock.tick(60)
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# clear display
screen.fill(WHITE)
# draw objects
pygame.draw.rect(screen, GREEN, (0, 0, 100, 100))
# update display
pygame.display.flip()
pygame.quit()
exit()
Note, you must do the event handling. See pygame.event.get() respectively pygame.event.pump():
For each frame of your game, you will need to make some sort of call to the event queue. This ensures your program can internally interact with the rest of the operating system.
Update the screen with:
pygame.display.update()
at the end of your code you have posted.
You have to update the screen like that:
pygame.display.flip()
to render what you just drew.
Your code should look like this:
import pygame
import time
pygame.init()
GREEN = (30, 156, 38)
WHITE = (255,255,255)
screen = pygame.display.set_mode((640, 480))
# draw on screen
screen.fill(WHITE)
pygame.draw.rect(screen, GREEN, (0,0,100,100))
# show that to the user
pygame.display.flip()
time.sleep(3)
Off-topic: You should also get the events to allow the user to close the window:
import pygame
from pygame.locals import QUIT
import time
pygame.init()
GREEN = (30, 156, 38)
WHITE = (255, 255, 255)
screen = pygame.display.set_mode((640, 480))
clock = pygame.time.Clock() # to slow down the code to a given FPS
# draw on screen
screen.fill(WHITE)
pygame.draw.rect(screen, GREEN, (0, 0, 100, 100))
# show that to the user
pygame.display.flip()
start_counter = time.time()
while time.time() - start_counter < 3: # wait for 3 seconds to elapse
for event in pygame.event.get(): # get the events
if event.type == QUIT: # if the user clicks "X"
exit() # quit pygame and exit the program
clock.tick(10) # limit to 10 FPS
# (no animation, you don't have to have a great framerate)
Note that you must put all of this into a game loop if you want to repeat it like a classic game.

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.

Categories