python pygame pause function - python

I am beginner and have a problem with my code. Here you can see a short excerpt of my code.
It's a simple snake game I created but I was trying to add a pause. I got it but when I start the pause I am not able to close it.
Possibly there is a basic mistake in my code so I couldn't advance. I hope you can help me.
Thank you in advance!
def checkquit(e):
running = True
pause = False
for ev in e:
if ev.type == pygame.QUIT:
exit(0)
running = True
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
quit(0)
running = True
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_p:
pause = False
while pause:
#running = False
pause = True
red = (255,0,0)
screen = pygame.display.set_mode((800,500))
screen.fill((0,0,0))
my_font = pygame.font.SysFont("monospace", 50)
my_font_two = pygame.font.SysFont("monospace", 10)
text1 = myfont.render("Pause!", 100, red)
text2 = myfont.render("Please restart the game", 100, red)
screen.blit(text2, (10, 200))
screen.blit(text1, (230, 100))
pygame.display.update()
for ev in e:
if ev.type == pygame.QUIT:
pause = False
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
pause = False
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_p:
pause = True

The pause screen is displayed in a separate application loop. You've to get the events in that loop, too. Note, in your code, the content of e never changes in the "pause" loop:
def checkquit(e):
global running
running = True
pause = False
for ev in e:
if ev.type == pygame.QUIT:
exit(0)
running = True
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
quit(0)
running = True
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_p:
pause = True
while pause:
# [...]
# get the new events
e = pygame.event.get()
# handle the events in the loop
for ev in e:
if ev.type == pygame.QUIT:
pause = False
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
pause = False
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_p:
pause = True
runnung seems to be a variable in global namespace. You've to use the global statement to change its state.
Furthermore it is superfluous to recreate the window surface in the "pause" loop.
screen = pygame.display.set_mode((800,500))
I recommend to change the game process. Use 1 application loop. e.g.:
myfont=pygame.font.SysFont("monospace",50)
myfonttwo=pygame.font.SysFont("monospace",10)
text1=myfont.render("Pause!",100,red)
text2=myfont.render("Please restart the game",100,red)
def checkquit(e):
global running, pause
for ev in e:
if ev.type == pygame.QUIT:
exit(0)
running = True
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
if pause:
pause = False
else:
quit(0)
running = True
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_p:
pause = not pause
running, pause = True, False
while running:
events = pygame.event.get()
checkquit(events)
screen.fill((0,0,0))
if pause:
# draw pause screen
screen.blit(text2,(10,200))
screen.blit(text1,(230,100))
else:
# draw game
# [...]
pygame.display.update()

I editet my code to this one:
def checkquit(e):
running = True
pause = False
for ev in e:
if ev.type == pygame.QUIT:
exit(0)
running = False
pause = False
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_ESCAPE:
quit(0)
running = False
pause = False
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_p:
pause = True
running = False
while pause:
pause = True
red = (255,0,0)
screen = pygame.display.set_mode((800,800))
screen.fill((0,0,0))
myfont=pygame.font.SysFont("monospace",50)
myfonttwo=pygame.font.SysFont("monospace",10)
myfonttwo=pygame.font.SysFont("monospace",10)
text1=myfont.render("Pause!",100,red)
text2=myfont.render("Please resume your game!",100,red)
text3=myfont.render("Game starts in 10 seconds!",100,red)
screen.blit(text2,(50,200))
screen.blit(text1,(300,100))
screen.blit(text3,(0,300))
pygame.display.update()
pygame.time.delay(4500)
if ev.type == pygame.KEYDOWN and ev.key == pygame.K_p:
pause = False
And it works very good! Thanks for your advices!

Related

Pygame project, screen doesn't update in one function, but it works within two other functions

My pygame project consists of several parts, including global map and towns. I use one Game class to contain necessary objects. All game is shown on one screen and works properly with global map and town (in_city function), it changes the screen and shows necessary information, but when I call another function (buy), it doesn't update screen.
def buy(self):
while self.running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.KEYDOWN:
return
self.screen.fill('BLACK')
pygame.display.update()
pygame.display.flip()
def in_city(self):
while self.running:
stop = False
for event in pygame.event.get():
if event.type == pygame.QUIT:
self.running = False
if event.type == pygame.MOUSEMOTION:
all_sprites.update(pygame.mouse.get_pos())
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_pos = pygame.mouse.get_pos()
button_right.click(mouse_pos)
button_left.click(mouse_pos)
button_next.click(mouse_pos)
button_prev.click(mouse_pos)
if button_close.on_button(mouse_pos):
stop = True
if event.type == pygame.KEYDOWN:
self.buy()
if stop:
self.player.route = [(0, 0)]
self.player.next_move(self.maps)
self.camera.update(self.player)
return
screen.fill('WHITE')
city.render(screen)
current_text = city.enemies[city.current_enemy]
window.show(screen, current_text.get_text())
print(current_text.goods)
all_sprites.draw(screen)
pygame.display.update()
pygame.display.flip()`
Never run game loops recursively. Use the one application loop to draw the scene depending on states. You should never jump to another application loop in an event. The event should only change a state that is used to draw the scene. e.g.:
game_state = 'A'
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
game_state = 'B'
screen.fill('WHITE')
if game_state == 'A':
# draw scene A
elif game_state == 'B':
# draw scene B
pygame.display.flip()

My pause statement is not working for pygame loop

My collide_rect function is not working as I expect to be. The problem is when press the key 'r', it should be able to reset everything and continue the game. But when I actually press the key 'r', it does not change anything when I add in the pause statement. I want to have the game pause when two of the sprites I have(ball, obstacle) collide. After the user inputs the letter 'r', it should go back to running and reset position for both sprites. The error I am getting is when I press the key 'r', it does not change anything on the surface.
This is my while loop:
paused = False
def display_text(text):
font = pygame.freetype.Font('helvetica.ttc', 32)
text_attributed = font.render_to(gameDisplay, (300,300), text, black)
while not crashed:
time = pygame.time.get_ticks()
obstacle.change_x()
for event in pygame.event.get():
if event.type == pygame.QUIT:
crashed = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_UP:
ball.jump_true()
if event.key == pygame.K_SPACE:
ball.jump_true()
if event.key == pygame.K_r:
paused = not paused
if ball.collide == True:
gameDisplay.fill(white)
display_text('You Lost! type "R" to restart')
paused = True
if paused == True:
ball.reset_position()
obstacle.reset_position()
pygame.display.flip()
clock.tick(20)
else:
ball.jump()
ball.test_collision(obstacle)
gameDisplay.fill(white)
ball.update()
obstacle.update()
pygame.display.flip()
clock.tick(60)
pygame.quit()
sys.exit()
Don't overcomplicate things. You don't need multiple event loops. Use 1 main loop, 1 event loop and a state which indicates if the game is paused. e.g.:
paused = False
run = True
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r
# Toggle pause
paused = not paused
if paused:
# "pause" mode
# [...]
else
# "run" mode
# [...]
# update display etc.
# [...]

Append keyboard input to variable in python

I want variable text = [] to append the keyboard input, and then print it.
import pygame
pygame.init()
screen = pygame.display.set_mode([600, 400])
keepGoing = True
def get_text ():
keepText = True
while keepText:
text = [] # I want to add input here
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
keys = pygame.key.name(event.key)
text.append(keys)
print (text)
if event.key == pygame.K_ESCAPE:
keepText = False
while keepGoing:
for event in pygame.event.get():
if event.type == pygame.QUIT:
keepGoing = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
get_text ()
pygame.display.update()
pygame.quit()
How can I do this?
I think this question is what you're looking for. You'll want something like
while keepText:
text = []
text.append(raw_input('Input something from the keyboard: '))
In your question the indenting looks problematic though, and your while loop will never end.
If a pygame.KEYDOWN event occurs, you can just add its .unicode attribute to a string or append it to a list.
import pygame as pg
def main():
screen = pg.display.set_mode((640, 480))
clock = pg.time.Clock()
text = ''
done = False
while not done:
for event in pg.event.get():
if event.type == pg.QUIT:
done = True
elif event.type == pg.KEYDOWN:
text += event.unicode
print(text)
screen.fill((30, 30, 30))
pg.display.flip()
clock.tick(30)
if __name__ == '__main__':
pg.init()
main()
pg.quit()

Pygame not restoring from pause

I'm trying to pause my game by pressing the 'p' key, but after it pauses it does not unpause when p is pressed again. Here are the relevant segments of my code, I'd like to know how to fix this and/or if there are better alternative methods of implementing a game pause.
pause = False
while True:
if not pause:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#game code
keys = pygame.key.get_pressed()
#if key up
elif keys[pygame.K_p]:
pause = True #appears to work correctly, screen freezes and
#prints "PAUSED" every tick.
#more game code
pygame.display.update()
fpsClock.tick(FPS)
else:
print("PAUSED")
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.type == pygame.K_p:
pause = False
pygame.display.update()
fpsClock.tick(FPS)
The code below does the trick.
I have added in if not pause: ... else: section also a handler for a keypress because without it there will be no chance to come out of the pause (the part if not pause won't never ever be run without this keypress check if once paused).
import pygame
pygame.init() # start PyGame (necessary because 'import pygame' doesn't start PyGame)
colorWhite = (255, 255, 255) # RGB color for later use in PyGame commands (valueRed=255, valueGreen=255, valueBlue=255)
colorWhite = (255, 255, 255) # RGB color for later use in PyGame commands (valueRed=255, valueGreen=255, valueBlue=255)
winDisplay = pygame.display.set_mode((1024, 768)) # set PyGame window size to 1024x768 pixel
pygame.display.set_caption("Minimal PyGame Test Script")
winDisplay.fill(colorWhite)
fpsClock = pygame.time.Clock()
FPS = 15
pause = False
pauseCounter = 0
while True:
if not pause:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_p:
pause = not pause
#game code
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
#more game code
pygame.display.update()
fpsClock.tick(FPS)
else:
pauseCounter += 1
print(pauseCounter, "PAUSED")
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN and event.key == pygame.K_p:
pause = not pause
#more game code
pygame.display.update()
fpsClock.tick(FPS)

Why does Pygame Movie Rewind Only on Event Input

I'm working on a small script in Python 2.7.9 and Pygame that would be a small display for our IT department. The idea is that there are several toggle switches that indicate our current status (in, out, etc) , some information about our program at the school, and play a short video that repeats with images of the IT staff etc. I have an older version of Pygame compiled that still allows for pygame.movie to function.
All of the parts of the script work, but when it gets to the end of the .mpg, the movie will not replay until there is an EVENT, like switching our status or moving the mouse. I have tried to define a variable with movie.get_time and call to rewind at a certain time, but the movie will not rewind (currently commented out) . Is there a way to play the movie on repeat without requiring an event, or maybe I could spoof an event after a certain length of time (note that the documentation for pygame.movie is outdated, the loops function does not work) ?
Thank you for the help!
import pygame, sys, os, time, random
from pygame.locals import *
pygame.init()
windowSurface = pygame.display.set_mode((0,0), pygame.FULLSCREEN)
pygame.display.set_caption("DA IT Welcome Sign")
pygame.font.get_default_font()
bg = pygame.image.load('da.jpg')
in_img = pygame.image.load('in.png')
out_img = pygame.image.load('out.png')
etc_img = pygame.image.load('etc.png')
present = in_img
done = False
img = 1
clock = pygame.time.Clock()
movie = pygame.movie.Movie('wallace.mpg')
movie_screen = pygame.Surface(movie.get_size()).convert()
playing = movie.get_busy()
movie.set_display(movie_screen)
length = movie.get_length()
currenttime = movie.get_time()
movie.play()
while not done:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
done = True
if event.type == pygame.QUIT:
movie.stop()
done = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_1:
img = 1
if event.type == pygame.KEYDOWN and event.key == pygame.K_2:
img = 2
if event.type == pygame.KEYDOWN and event.key == pygame.K_3:
img = 3
if event.type == pygame.KEYDOWN and event.key == K_w:
pygame.display.set_mode((800, 600))
if event.type == pygame.KEYDOWN and event.key == K_f:
pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
if img == 1:
present = in_img
if img == 2:
present = out_img
if img == 3:
present = etc_img
if not(movie.get_busy()):
movie.rewind()
movie.play()
#movie.get_time()
#if currenttime == 25.0:
# movie.stop()
# movie.rewind()
# movie.play()
windowSurface.blit(bg, (0, 0))
windowSurface.blit(movie_screen,(550,175))
windowSurface.blit(present, (0,0))
pygame.display.flip()
You need to take the code for replaying the movie out of the for loop that gets current events. Do this for that code and any other code you want to happen continuously without waiting for an event by moving the code 4 spaces to the left.
Like so:
while not done:
for event in pygame.event.get(): #gets most recent event, only executes code below when there is an event
if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
done = True
if event.type == pygame.QUIT:
movie.stop()
done = True
if event.type == pygame.KEYDOWN and event.key == pygame.K_1:
img = 1
if event.type == pygame.KEYDOWN and event.key == pygame.K_2:
img = 2
if event.type == pygame.KEYDOWN and event.key == pygame.K_3:
img = 3
if event.type == pygame.KEYDOWN and event.key == K_w:
pygame.display.set_mode((800, 600))
if event.type == pygame.KEYDOWN and event.key == K_f:
pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
#code below is out of the event for loop and thus executes whenever the while loop runs through
if img == 1:
present = in_img
if img == 2:
present = out_img
if img == 3:
present = etc_img
if not(movie.get_busy()):
movie.rewind()
movie.play()
#movie.get_time()
#if currenttime == 25.0:
# movie.stop()
# movie.rewind()
# movie.play()
windowSurface.blit(bg, (0, 0))
windowSurface.blit(movie_screen,(550,175))
windowSurface.blit(present, (0,0))
pygame.display.flip()
I have run into this problem too while trying to do things with pygame, it seems to be a common error.

Categories