Doing something after a period of time: Pygame - python

I wanted to do something after a period of time. On stack overflow I found a question that helps solve that, (Link) but when I run the program the code works, however it goes away after a millisecond. Whereas I want it to stay there after the amount of time I want it to wait. In this case for a test run I am blitting some text onto the screen. Here is the code:
import pygame
# Importing the modules module.
pygame.init()
# Initializes Pygame
SCREEN_WIDTH = 800
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((800, 600))
# Sets the screen to pygame looks and not normal python looks.
pygame.display.set_caption("Test Run")
# Changes the title
# Heading
headingfont = pygame.font.Font('Bouncy-PERSONAL_USE_ONLY.otf', 45)
headingX = 230
headingY = 10
class Other():
def show_heading():
Heading = headingfont.render("Health Run!", True, (255, 255, 255))
screen.blit(Heading, (headingX, headingY))
pygame.time.set_timer(pygame.USEREVENT, 100)
running = True
while running:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.USEREVENT:
Other.show_heading()
#Update Display
pygame.display.update()

If you want to draw the text permanently, you need to draw it in the application loop. Set a Boolean variable "draw_text" when the timer event occurs. Draw the text depending on draw_text in the application loop:
draw_text = False
running = True
while running:
screen.fill((0,0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.USEREVENT:
draw_text = True
if draw_text:
Other.show_heading()
#Update Display
pygame.display.update()
For more information about timers and timer events, see Spawning multiple instances of the same object concurrently in python, How can I show explosion image when collision happens? or Adding a particle effect to my clicker game and many more.

Related

Keep getting an error about pygame not being initialised

I keep getting an error about system not being initialised. The error is about the pygame.display.update()
Where is this meant to go?
import pygame #IMPORTS THE PYGAME CLASSES, METHODS AND ATTRIBUTES
from pygame.locals import * #IMPORTING ALL PYGAME MODULES
pygame.init() #INITIALISING PYGAME
WIDTH, HEIGHT = 1000, 600
WINDOW = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption("On The Run")
blue = 146,244,255 #BACKGROUND COLOUR
width = 80
height = 60
x = 200 #X-POSITION OF THE CHARACTER
y = 100 #Y-POSITION OF THE CHARACTER
player1 = pygame.image.load('assets/characterMove3.jpg') #DISPLAYING THE IMAGE ONTO THE SCREEN
player1 = pygame.transform.scale(player1,(width,height)) #SCALING THE IMAGE TO SUITABLE DIMENSIONS
WINDOW.blit(player1,(x,y))
def game_loop(): #WHERE THE WINDOW IS CREATED
run = True
while run:
WINDOW.fill(blue)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False #WE WILL QUIT THE GAME AS THE VARIABLE run IS NOW FALSE
pygame.quit() #IT WON'T SHOW THE MOST RECENT THING I DREW UNLESS I MANUALLY UPDATE IT
pygame.display.update()
game_loop()
The problem is that pygame.quit() is called in the application loop. pygame.quit() deinitializes all Pygame modules and crashes all subsequent Pygame API calls. pygame.quit() must be the very last Pygame API call. Call pygame.quit() after the application loop:
def game_loop(): #WHERE THE WINDOW IS CREATED
run = True
while run:
WINDOW.fill(blue)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
#pygame.quit() <-- DELETE
pygame.display.update()
pygame.quit() # <-- INSERT
game_loop()

Pygame window opening and closing immediately

So when I set
while not game_over = False
, my window opens properly, but the text doesn't show. Whereas if I set it to True, the text shows but window closes immediately.
Here's the code:
***#Write a Python program to create a simple math quiz.
#Importing libraries
import pygame
import sys
import math
from pygame.locals import *
#Initialising fonts
pygame.init()
pygame.font.init()
#Assigning variables
WIDTH = 600
HEIGHT = 600
#Other important things
background_color = (127,255,0)
screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
pygame.display.set_caption("Math Game")
screen.fill(background_color)
pygame.display.flip()
font = pygame.font.Font("freesansbold.ttf", 40)
textX=10
textY=10
def show_text(x,y):
text=font.render("Math Game", True, (0,0,0))
screen.blit(text,(x,y))
"""
#Adding the Calculator bit
x = input("Enter Your First Nummber To Add: ")
y = input("Enter Your Second Number To Add: ")
z = str(int(x)+int(y))
print(z)
"""
#Game loop
game_over = True
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
show_text(textX, textY)
pygame.display.update()***
It is a matter of Indentation. show_text and pygame.display.update() must be called in the application loop instead of after the application loop.
Additionally you should clear the display in the application loop.
game_over = False
while not game_over:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# INDENTATION
#-->|
screen.fill(background_color)
show_text(textX, textY)
pygame.display.update()
The typical PyGame application loop has to:
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()
limit the frames per second to limit CPU usage with pygame.time.Clock.tick

Import loop only works twice, gives pygame.error Display surface quit

I am in a beginner python class and we are working on our final projects. For my game however I wanted to be able to restart the game within itself. I did this by using imports to launch a new script to then re-run my game. However whenever I try to do it more than once my window breaks, or the code does not import the next file. My game is kinda long so I've created a very short program to give an example of my issue.
(This being the file yin.py)
import pygame
BLACK = (0, 0, 0)
pygame.init()
SIZE = [300, 300]
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
import yang
done = True
screen.fill(BLACK)
pygame.display.flip()
clock.tick(30)
pygame.quit()
(and this file yang.py)
import pygame
WHITE = (255, 255, 255)
pygame.init()
SIZE = [300, 300]
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.MOUSEBUTTONDOWN:
import yin
done = True
screen.fill(WHITE)
pygame.display.flip()
clock.tick(30)
pygame.quit()
I've tried doing multiple things but so far I have gotten nowhere, it still is giving me display not initialized even though I have 'pygame.init()'. My teacher isn't responding to my emails and I have an encroaching deadline. Any help will be appreciated. :p
The "import" statement only imports once. If the name already exists, it doesn't import again. You should put your code into a function. Then, you can call the function as many times as you want.

How do you switch between multiple backgrounds in pygame?

I was practicing using the pygame package in python by making a graphics oriented game and in my game, I want to switch between multiple backgrounds as the user progresses through it. For the example I am posting, the first background will be a black screen with 5 statements on it and my second background will be a room. However, I am unable to figure this out because whenever I try to run the code, the game window doesn't show anything. I can post my code for the while loop below for further clarification.
while running:
screen.fill((0, 0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
first_line()
second_line()
third_line_1()
third_line_2()
fourth_line()
fifth_line()
sleep(10)
screen.blit(background_room, (0, 0))
pygame.display.update()
The way I would probably do it is something like
import pygame
from pygame.locals import *
class Backround:
FIVE_STATEMENTS = 0
ROOM = 1
viewport_size = (800, 600)
def main():
pygame.init()
screen = pygame.display.set_mode(viewport_size)
backround_room = pygame.Surface(viewport_size)
# load the image...
backround_statements = pygame.Surface(viewport_size)
backround_statements.fill((0, 0, 0))
# blit the five statements onto here
backround_to_render = Backround.FIVE_STATEMENTS
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if backround_to_render == Backround.FIVE_STATEMENTS:
# if the statements ever change, probably want to fill() and re-blit them on
screen.blit(backround_statements, (0,0))
elif backround_to_render == Backround.ROOM:
screen.blit(backround_room, (0,0))
else:
print("Oh no!!!!!!!")
pygame.display.flip()
if __name__ == "__main__":
main()

Pygame wait for screen to update

I just started with pygame, and I am just trying to move points across my screen. The problem is that it happens way to fast and my pygame screen freezes (Not Responding) while the loop runs and then only shows the last iterations position of dots.
I am thinking the updating happens to fast.
When I include pygame.event.wait() then as I give an input the loop progresses and I can follow live in the window how the dots are moving across the screen. However, I would like to have it that they move across the screen without an input required.
This is my main loop:
def run(self):
self.food_spread()
self.spawn_animal()
for k in range(20000):
print(k)
for member in self.zoo:
self.move(member)
self.screen.fill(black)
for i in range(self.food_locations.shape[0]):
pygame.draw.rect(self.screen, white, (self.food_locations[i,1], self.food_locations[i,2],1,1))
for member in self.zoo:
pygame.draw.circle(self.screen, green,(member.location[0], member.location[1]), 2,1)
pygame.display.update()
pygame.event.wait()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
You have an application loop, use if. Use pygame.time.Clock() to control the framerate . The application loop has to
control the framerate (clock.tick(60))
handel the events and move the objects
clear the display
draw the scene
update the display
e.g:
class App:
def __init__(self):
# [...]
self.clock = pygame.time.Clock()
def run(self):
self.food_spread()
self.spawn_animal()
run = True
while run:
# control the framerate
self.clock.tick(60) # 60 FPS
# handel the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
# move the objects
for member in self.zoo:
self.move(member)
# clear the display
self.screen.fill(black)
# draw the scene
for i in range(self.food_locations.shape[0]):
pygame.draw.rect(self.screen, white, (self.food_locations[i,1], self.food_locations[i,2],1,1))
for member in self.zoo:
pygame.draw.circle(self.screen, green,(member.location[0], member.location[1]), 2,1)
# update the display
pygame.display.update()

Categories

Resources