Im trying to make a pause screen function but the images shutter and appear with a good delay. Any
ideas Heres my code:
PauseLogo = pg.image.load('Stop.png')
Pause = pg.image.load('Pause.png')
#------------------------------------------
while running:
clock.tick(FPS)
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
paused = not paused
if paused == True:
clock.tick(27)
screen.blit(PauseLogo, (0,0))
screen.blit(Pause, (400, 330))
if not paused:
all_sprites.update()
screen.fill(DARKGRAY)
all_sprites.draw(screen)
Draw different scenes dependent on the state of paused:
while running:
clock.tick(FPS)
for event in pg.event.get():
if event.type == pg.QUIT:
running = False
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
paused = not paused
if paused == True:
screen.blit(PauseLogo, (0,0))
screen.blit(Pause, (400, 330))
else:
all_sprites.update()
screen.fill(DARKGRAY)
all_sprites.draw(screen)
pygame.display.update()
Note, pygame.time.Clock.tick() measures the time since the last call of this function and delays the application. If you call it twice in the application, the application is delayed twice.
Related
I ran into a bug with my timer. When I pause my game I noticed that my timer doesn't pause a long with the game. Example: if I pause the game when the timer is at 26 seconds remaining, and unpause the game about ten seconds later, the timer will say 16 seconds left instead of counting down from 26 like I want it to. If I pause the game for 30 seconds the timer still runs down to 0 instead of the timer pausing along with the game. How can I fix this?
code where my game runs:
#game runs here
run = True
paused = False
while run:
for event in pygame.event.get():
if event.type == pygame.USEREVENT:
counter -= 1
text = str(counter).rjust(3) if counter > 0 else 'GAME OVER!'
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
#check if key is down
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
run = False
if event.key == pygame.K_a:
player.movingLeft = True
if event.key == pygame.K_d:
player.movingRight = True
if event.key == pygame.K_SPACE:
player.shoot()
shoot = True
#check if key is up
if event.type == pygame.KEYUP:
if event.key == pygame.K_a:
player.movingLeft = False
if event.key == pygame.K_d:
player.movingRight = False
if paused:
continue
#draw street
screen.blit(bg, [0, 0])
#draw timer
screen.blit(timer_font.render(text, True, (0,0,0)), (800, 10))
#update groups
bullet_group.update()
bullet_group.draw(screen)
debris_group.update()
debris_group.draw(screen)
#draw car
player.draw()
player.move()
player.collision(debris_group)
player.stats()
#update all sprites
all_sprites.update()
all_sprites.draw(screen)
#update the display
pygame.display.update()
pygame.display.flip()
clock.tick(FPS)
pygame.quit()
The timer event can be stopped by passing 0 to the time argument of pygame.time.set_timer.
Stop and restart the timer event when you toggle the pause state:
run = True
paused = False
while run:
for event in pygame.event.get():
if event.type == pygame.USEREVENT:
counter -= 1
text = str(counter).rjust(3) if counter > 0 else 'GAME OVER!'
if event.type == pygame.QUIT:
run = False
#pause game
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_p:
paused = not paused
if pause:
pygame.time.set_timer(pygame.USEREVENT, 0) # stop timer
else:
pygame.time.set_timer(pygame.USEREVENT, 1000) # 1 second interval
# [...]
I want to close the game after was pressed the esc button. how can I do? And where should I place it?
I also found some problems that I can't solve, so if you solve them for me I would be happy
This is the code:
#Import Libraries
import pygame
import random
#PyGame Initialization
pygame.init()
#Images Variables
background = pygame.image.load('images/sfondo.png')
bird = pygame.image.load('images/uccello.png')
base = pygame.image.load('images/base.png')
gameover = pygame.image.load('images/gameover.png')
tube1 = pygame.image.load('images/tubo.png')
tube2 = pygame.transform.flip(tube1, False, True)
#Display Create
display = pygame.display.set_mode((288,512))
FPS = 60
#Define Functions
def draw_object():
display.blit(background, (0,0))
display.blit(bird, (birdx, birdy))
def display_update():
pygame.display.update()
pygame.time.Clock().tick(FPS)
def animations():
global birdx, birdy, bird_vely
birdx, birdy = 60, 150
bird_vely = 0
#Move Control
animations()
while True:
bird_vely += 1
birdy += bird_vely
for event in pygame.event.get():
if ( event.type == pygame.KEYDOWN
and event.key == pygame.K_UP):
bird_vely = -10
if event.type == pygame.QUIT:
pygame.quit()
draw_object()
display_update()
Well you do so by implementing below code snippet in your code:
running = True
while running:
# other code
event = pygame.event.wait ()
if event.type == pygame.QUIT:
running = False # Be interpreter friendly
pygame.quit()
Make sure that you call pygame.quit() before you exit your main function
You can also reference this thread
Pygame escape key to exit
You must terminate the application loop when the QUIT event occurs. You have implmented the QUIT event, but you don't terminate the loop. Add a variabel run = True and set run = False when the event occurs.
To terminate the game when ESC is pressed you have to implement the KEYDOWN event. Set run = False when the KEDOWN event occurs and event.key == pgame.K_ESC:
run = True
while run:
bird_vely += 1
birdy += bird_vely
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
elif event.type == pygame.KEYDOWN:
if event.key == pgame.K_ESC:
run = False
elif event.key == pygame.K_UP:
bird_vely = -10
draw_object()
display_update()
pygame.quit()
exit()
So I created a Python game Tetris based on Youtube tutorial:
https://www.youtube.com/watch?v=zfvxp7PgQ6c&t=2075s
But the pygame.error: display Surface quit occurs.
I have tried to add "break", "sys.exit()", "QUIT" after the pygame.quit but does not work.
Does anyone know how to solve it? Here is the code: (You can skip to the def main_menu)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run == False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
current_piece.x -= 1
if not (valid_space(current_piece, grid)):
current_piece.x += 1
if event.key == pygame.K_RIGHT:
current_piece.x += 1
if not (valid_space(current_piece, grid)):
current_piece.x -= 1
if event.key == pygame.K_DOWN:
current_piece.y += 1
if not (valid_space(current_piece, grid)):
current_piece.y -= 1
if event.key == pygame.K_UP:
current_piece.rotation += current_piece.rotation + 1 % len(current_piece.shape)
if not (valid_space(current_piece, grid)):
current_piece.rotation -= 1
shape_pos = convert_shape_format(current_piece)
for i in range(len(shape_pos)):
x, y = shape_pos[i]
if y > -1:
grid[y][x] = current_piece.color
if change_piece:
for pos in shape_pos:
p = (pos[0], pos[1])
locked_positions[p] = current_piece.color
current_piece = next_piece
next_piece = get_shape()
change_piece = False
score += clear_rows(grid, locked_positions) * 10
draw_window(win, grid, score, last_score)
draw_next_shape(next_piece, win)
pygame.display.update()
if check_lost(locked_positions):
draw_text_middle(win, "You Lost!", 80, (255,255,255))
pygame.display.update()
pygame.time.delay(1500)
run = False
update_score(score)
def main_menu(win):
run = True
while run:
win.fill((0,0,0))
draw_text_middle(win, 'Press any key to play', 60, (255,255,255))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.display.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
main(win)
pygame.display.QUIT()
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')
main_menu(win)
Updated code:
def main_menu(win):
run = True
while run:
win.fill((0,0,0))
draw_text_middle(win, 'Press any key to play', 60, (255,255,255))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
main(win)
pygame.quit()
win = pygame.display.set_mode((s_width, s_height))
pygame.display.set_caption('Tetris')
main_menu(win)
In your main_menu loop you are telling it to loop while local boolean run == True. This is okay, but you should as people mentioned in the comments do a pygame.quit() and optionally quit() (closes the window) instead of the pygame.display.quit() and sys.exit() that you have right now.
The second problem occurs if you start the game by going into the main loop. I assume that the main loop runs your events function shown at the top?
Depending on how you have written the code, the boolean run in the event function is
local. This means that it will not change the value of the run you are using in your
main loop (nor change it in the main_menu loop). I would suggest to transfer into OOP and create a self.run boolean instead,
or else you need to make the boolean run global.
And you should in the event function write this instead of what you have now at the
top:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
quit()
Hope this helps!
while g.running:
for event in pygame.event.get():
if event == pygame.QUIT:
g.running = False
g.run(Player_1)
quit()
when I run this loop it completely skips the for loop or just does it once and is too fast for me to be able to run and it just goes on to run. How do I make the loop work fine?
https://github.com/maartenww/100daysOfCode_projectOne << for the full code.
Also, what g.run basically does is just update the game. So it draws and or moves all the sprites, draws the text unto the screen and does some calculations
class Game:
def __init__(self):
self.running = True
def run(self, player_1):
self.border_col(player_1)
self.load_text(player_1)
self.update_game(player_1)
def update_game(self, player_1):
clock.tick(FPS)
gameDisplay.fill(black)
gameDisplay.blit(self.xcolon, (0, 0))
gameDisplay.blit(self.actual_x, (25, 0))
gameDisplay.blit(self.ycolon, (0, 30))
gameDisplay.blit(self.actual_y, (25, 30))
gameDisplay.blit(self.acolon, (0, 60))
gameDisplay.blit(self.actual_a, (25, 60))
gameDisplay.blit(self.vcolon, (0, 90))
gameDisplay.blit(self.actual_v, (25, 90))
all_sprites.draw(gameDisplay)
Player.move_player(player_1)
Player.update_player(player_1)
pygame.display.update()
I looked into your repo, and the revelant code is this, in player.py:
def move_player(self):
for event in pygame.event.get():
# Player movement
if (event.type == pygame.KEYDOWN):
if (event.key == pygame.K_d):
self.player_acc = PLAYER_ACC
if (event.key == pygame.K_a):
self.player_acc = -PLAYER_ACC
if (event.type == pygame.KEYUP):
if (event.key == pygame.K_d):
self.player_acc = 0
if (event.key == pygame.K_a):
self.player_acc = 0
Think about what happens in your main loop:
while g.running:
for event in pygame.event.get():
if (event.type == pygame.QUIT):
g.running = False
g.run(Player_1)
You get all events from the event queue, clearing it, and check for QUIT.
Then you call g.run, which will call self.update_game, which will call Player.move_player, which will again get all events from the event queue and clear it.
So when the QUIT event is in the event queue at the moment pygame.event.get() is called inside Player.move_player, it is practically lost, since you don't handle it in this for loop. When pygame.event.get() is then called again in main, the QUIT event is no longer in the queue (because calling event.get clears the queue).
Basically, you should call 'event.get' only once per main loop iteration (the same is true for pygame.display.flip/pygame.display.update).
Maybe change the loop in main to something like this:
while g.running:
for event in pygame.event.get():
g.handle(event, Player_1)
g.run(Player_1)
add this to Game:
def handle(self, event, player_1):
if event.type == pygame.QUIT:
self.running = False
else:
player_1.handle(event)
and this to Player:
def handle(self, event):
# Player movement
if (event.type == pygame.KEYDOWN):
if (event.key == pygame.K_d):
self.player_acc = PLAYER_ACC
if (event.key == pygame.K_a):
self.player_acc = -PLAYER_ACC
if (event.type == pygame.KEYUP):
if (event.key == pygame.K_d):
self.player_acc = 0
if (event.key == pygame.K_a):
self.player_acc = 0
and remove Player.move_player
I expect the loop does run, but you've hit a case of type mismatch not being reported.
for event in pygame.event.get():
if event == pygame.QUIT:
event will be a pygame.event.Event object. The QUIT value you're checking against is a value that might appear in the event.type attribute. Since no event is the integer value QUIT, all events are being ignored. You might want to add an else clause to diagnose which events are received but not handled.
Can someone PLEASE tell me what I'm doing wrong. I can't get my stupid program to close. It has a spinning circle(windows) and it doesn't close upon quit or keypress on the space bar.
def visualize(self):
pygame.init()
main_surface = pygame.display.set_mode((1024, 768))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
break
pygame.display.flip()
pygame.quit()
I'm not sure if the inside of my program matters much, but if it does, I'll add it. I would REALLY appreciate your help!
The break will just exit the innermost loop, which is the for loop. You should have a condition variable for your while loop
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
break
pygame.display.flip()