Pygame start menu working, but not Pause menu - python

I'm trying to integrate a "pause" menu and "main" menu in pygame, along with a screen that will show during the game. My code first loads the intro, or main menu, which works fine, and then handles a button click to call the main game loop function. The problem arises when, within that loop, I try to call the function for the pause menu. I use the same loops to do this so I'm not sure why one works and the other doesn't. Below I've added code snippets for reference.
The main menu (which is called first in the program):
def intro_screen():
intro = True
while intro:
# Event listeners
for event in pygame.event.get():
main_window.fill(tan)
...
I also have other buttons etc. which are unimportant, but to get out of the intro, a mouse event sets intro to false and calls the function game_loop:
# Handle the click event
if click[0] == 1:
intro = False
game_loop()
The game_loop function has a similar while loop:
def game_loop():
playing = True
paused = False
while playing:
# This is the main loop
# Load in the play screens...
main_window.fill(white)
play_screen = PlayScreen(main_window)
And buttons etc...
But when I set playing to False and paused to True, which calls the pause_screen() function, it doesn't pull up any new screen. It just stays on the game menu as if no event was received.
for event in pygame.event.get():
if event.type == pygame.QUIT:
playing = False
# Listen for the escape key and bring up the pause menu
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
playing = False
paused = True
pygame.display.update()
while paused:
pause_menu()
For reference, these are all contained in functions. The last line of my code simply calls intro_screen(), which works fine.
I can provide the rest of the code if that would be helpful. The only thing I could think of is that the mouse event works and the keydown event doesn't, but my syntax looks to be correct from what I can tell.

Looks like your while loop for the pause menu is out of the game loop. Try this:
def game_loop():
playing = True
paused = False
while playing:
# This is the main loop
# Load in the play screens...
main_window.fill(white)
play_screen = PlayScreen(main_window)
for event in pygame.event.get():
if event.type == pygame.QUIT:
playing = False
# Listen for the escape key and bring up the pause menu
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
playing = False
paused = True
pygame.display.update()
while paused:
pause_menu()

Why don't you create a separate function for your pause menu? This will be easier as you can then call it properly.
For example:
pause = True
while pause:
# Event listeners
for event in pygame.event.get():
main_window.fill(tan)```

Related

bug in loading scenes with different background

I am trying to add a pause menu in my game SpaceInvaders with the last frame of the game in the background but when I load the pause scene my game does not show the game in the background
the background game looks like this
the first time I load pause it shows this
and then whenever i load pause it behaves normally like this
my game has 3 files :
1)game file
2)pause file
3)init file (that connects above two)
Game file
import pygame
from __init__ import __INIT__
pygame.display.set_caption("Endless")
pygame.init()
screen=pygame.display.set_mode((1920/2,1080/2),pygame.RESIZABLE)
def menu():
running=True
while running:
screen.blit(pygame.image.load("docs/bg.png"),(0,0))
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
__INIT__("pause")
pygame.display.update()
menu()
Pause file
import pygame
from __init__ import __INIT__
pygame.display.set_caption("Pause")
pygame.init()
screen=pygame.display.set_mode((1920/2,1080/2),pygame.RESIZABLE)
def PAUSE():
running=True
while running:
for event in pygame.event.get():
if event.type==pygame.QUIT:
running=False
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
__INIT__("menu")
if event.key == pygame.K_h:
from __init__ import hello
hello()
screen.blit(pygame.image.load("docs/D_effect.png"),(0,0))
pygame.display.update()
PAUSE()
init file
def __INIT__(a):
if a=="pause":
from pause import PAUSE
PAUSE()
if a=="menu":
from endless import menu
menu()
I don't know what is causing this issue because it only does it one time I am a beginner it might be a silly mistake I am sorry if that happens
in any case, if u find it difficult to understand my problem please run the endless file in Space_invaders/Space_invaders/endless.py
provided here
https://drive.google.com/file/d/1FUhGNdXp4CgYcr9PAfey-6ElZhVYMKem/view?usp=sharing
The problem is recursion. menu calls PAUSE, PAUSE calls menu:
menu
|
-> PAUSE
|
-> menu
|
-> PAUSE
|
...
You don't need the extra application loop for PAUSE at all. Just add use game_state variable. e.g.:
import pygame
pygame.display.set_caption("Endless")
pygame.init()
screen=pygame.display.set_mode((1920/2,1080/2),pygame.RESIZABLE)
def menu():
bg = pygame.image.load("docs/bg.png")
bg_pause = pygame.image.load("docs/D_effect.png")
game_state = 'running'
while game_state != 'quit':
if game_state == 'pause':
screen.blit(bg_pause, (0,0))
else:
screen.blit(bg, (0,0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_state = 'quit'
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
if game_state == 'running':
game_state = 'pause'
else:
game_state = 'running'
if game_state == 'running':
# draw game scene
# [...]
pass
pygame.display.update()
pygame.quit()
quit()
menu()
Do not load the background images in every frame. This causes lagging. pygame.image.load is a very time consuming process, the image file has to be loaded from the volume and decoded. Load the images before the application loop and use them in the loop.

Image Closing when Moving Mouse

I'm trying to make a menu show up when you press a button. When you press the button, it appears. However, when I move my cursor, the menu disappears.
if event.type == pygame.MOUSEBUTTONUP:
if self.ui.menuUI.get_rect(topright = (1850, 0)).collidepoint(pygame.mouse.get_pos()):
self.ui.show_menu()
Here's the show_menu()
def show_menu(self):
self.display_surface.blit(self.menuUII,self.MenuUII_rect)
Thanks for helping!
You must draw the image in the application loop. Set a state when the button is clicked. And draw the image depending on the state:
Constructor:
self.show_ui = False
Event handling:
# event loop
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.MOUSEBUTTONUP:
if self.ui.menuUI.get_rect(topright = (1850, 0)).collidepoint(pygame.mouse.get_pos()):
self.show_ui = True
when drawing the scene
if self.show_ui:
self.ui.show_menu()

Pygame application doesn't close out the first time

I am building a small game in pygame and I wanted a function to exit out. However it takes multiple clicks to exit and it is not consistent either. Also the windows exit function is restarting the program, too Here is the part of the code that deals with exiting
if isKill:
pygame.mixer.music.stop()
gameover = myfont.render("Press R to Respawn", False, (255, 255, 255))
rect = gameover.get_rect()
rect.center = screen.get_rect().center
screen.blit(gameover, rect)
if event.type == KEYDOWN:
if event.key == K_r:
gameloop()
and
for event in pygame.event.get():
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
running = False
*gameloop() is the whole script
Instead of event.type, you can use the pygame builtin event QUIT
Refer the following code
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
#Can use pygame.quit() in place of running=False if the above line doesn't work.
This while loop is the starting of gameloop. The contents of the gameloop should be inside it.
Don't call the gameloop() function inside the while loop
Perhaps use sys.exit to stop the program.
Try:
import sys
import pygame
while 1:
#code
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
In your game loop, you should always keep the loop running at one level. In your code, the respawn actually freezes the current level and reruns the game at a lower level. This is why several quit commands are required to exit the game.
When the player respawns, reset the game variables, then continue the game loop.
Update your code similar to this:
if isKill: # game is over
pygame.mixer.music.stop()
gameover = myfont.render("Press R to Respawn", False, (255, 255, 255))
rect = gameover.get_rect()
rect.center = screen.get_rect().center
screen.blit(gameover, rect)
if event.type == KEYDOWN:
if event.key == K_r:
#gameloop() # remove this
dospawn() # initialize\reset game variables here (can use same function at game start)
isKill = False # start new game
continue # skip rest of game process

Stop multiple keyboard entries in Pygame

I have some python code that uses a pygame window to establish which key is being pressed. When a key is pressed, the code heads off and does things before coming back to see what the next key pressed might be.
The problem I have is that if the user presses a key repeatedly, even while the 'code heads off and does things', pygame seems to remember what has been pressed rather than waiting for the next keypress. What I want is for the code to ignore any keypresses while the 'go and do stuff' is done then once that's finished, get the next keypress. Hope this makes sense!
import pygame
import time
pygame.init()
screen = pygame.display.set_mode((450,282))
screen.fill((0,0,0))
pygame.display.flip()
clock = pygame.time.Clock()
done = False
def go_and_do_things():
print("doing things")
time.sleep(2)
print("things done")
# Loop as long as done == False
while not done:
for event in pygame.event.get(): # User did something
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)
time.sleep(4)
pygame.quit()
You could use pygame.event.clear. As written below, it will discard any keypresses during go_and_do_things().
while not done:
for event in pygame.event.get(): # User did something
# Any key down
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
pygame.event.clear(eventtype=[pygame.KEYDOWN,
pygame.KEYUP)
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)
This is a fairly simple problem, you just need to add another
event.type for keyup. You also need to add a variable to make it stop
running which I will label as stopV if event.type == pygame.KEYUP:
stopV = True This should let you instantly stop it when you want to. edit because I want to reword this:
Re-doing this to make it more clear.
import pygame
import time
pygame.init()
screen = pygame.display.set_mode((450,282))
screen.fill((0,0,0))
pygame.display.flip()
clock = pygame.time.Clock()
done = False
unClick = False
def go_and_do_things():
if unClick == False
print("hello")
# do anything you want in the function here
else
return
while not done:
for event in pygame.event.get(): # User did something
# Any key down
if event.type == pygame.KEYDOWN:
keypressedcode = event.key # This is the ASCII code
print("keypressedcode is " + str(keypressedcode))
go_and_do_things()
if event.type == pygame.KEYUP:
unClick == True
elif event.type == pygame.QUIT: # If user clicked close
done = True # Flag that we are done so we exit this loop
clock.tick(60)

Need help getting scroll up event

I'm creating a program in Python using Pygame and I can't find a working method to detect when I scroll up.
I'm trying to recreate a popular video called "Interstellar Mouse"
https://www.youtube.com/watch?v=aANF2OOVX40
I'm trying to get it to play the same music when you scroll (to do the same thing without having to edit it in).
I've been able to get this to work with keypresses by doing something like this:
keys = pygame.key.get_pressed()
if keys[pygame.K_KEYNAME]:
pygame.mixer.music.unpause()
Just using keys seems to work fine but I need to use the mouse wheel.
This is the main loop:
run = True
while run:
#quit game after pressing the close button
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
#exit game by pressing ESC
if keys[pygame.K_ESCAPE]:
run = False
#scroll to activate
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
pygame.mixer.music.unpause()
else:
pygame.music.pause()
#update background
win.blit(bg, (width / 4, height / 4))
pygame.display.update()
pygame.quit()
The results are very inconsistent. Sometimes if I scroll really fast it will start playing after about a second but never stop. Sometimes it just doesn't play at all.
This part here:
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4:
pygame.mixer.music.unpause()
else:
pygame.music.pause()
Every time you have event.type == pygame.MOUSEBUTTONDOWN you are either pausing or unpausing the music. Mouse clicks and scroll downs will pause your music. I would change this to a specific pause option, say if event.button == 2 instead of your else for better control.

Categories

Resources