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.
Related
so i'm doing the states of my game right now :
import pygame
import sys
screen=pygame.display.set_mode((1200,700))
play_image=pygame.Surface((100,200))
play_image.fill('red')
play_rect=play_image.get_rect(topleft=(200,200))
retry_image=pygame.Surface((100,200))
retry_image.fill('red')
retry_rect=retry_image.get_rect(topleft=(200,200))
game_over=False
menustatus=True
while menustatus:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
pygame.font.quit()
sys.exit()
mouse_pos=pygame.mouse.get_pos()
mousecheck=pygame.mouse.get_pressed()
if play_rect.collidepoint(mouse_pos) and mousecheck[0]:
game_over=True
menustatus=False
screen.blit(play_image,play_rect)
pygame.display.update()
while game_over:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
pygame.font.quit()
sys.exit()
mouse_pos=pygame.mouse.get_pos()
mousecheck=pygame.mouse.get_pressed()
if retry_rect.collidepoint(mouse_pos) and mousecheck[0]:
menustatus=True
game_over=False
screen.blit(retry_image,retry_rect)
pygame.display.update()
problem is, when i click the red rectangle, which is a placeholder for my play button to head into the gameover screen, it crashes instead of showing me a game over screen
I've written a function state_machine() which decides what is happening and what to do next, but is uses states to 'jump' from one thing to another:
import pygame
import sys
screen=pygame.display.set_mode((1200,700))
play_image=pygame.Surface((100,200))
play_image.fill('red')
play_rect=play_image.get_rect(topleft=(200,200))
retry_image=pygame.Surface((100,200))
retry_image.fill('red')
retry_rect=retry_image.get_rect(topleft=(200,200))
def state_machine(state):
if state == "menu_status":
if play_rect.collidepoint(mouse_pos) and mousecheck[0]: #checks if player clicks a button to play
state = "game_over"
elif state == "game_over":
if retry_rect.collidepoint(mouse_pos) and mousecheck[0]: #checks if player clicks a button to retry
state = "game_active"
elif state == "game_active":
if player.rect.y>screen_height: #checks if player dies
state = "game_over"
return state
game_state = "menu_status"
while True:
for event in pygame.event.get():
if event.type==pygame.QUIT:
pygame.quit()
pygame.font.quit()
sys.exit()
mouse_pos=pygame.mouse.get_pos()
mousecheck=pygame.mouse.get_pressed()
game_state = state_machine(game_state)
screen.blit(play_image,play_rect)
pygame.display.update()
I've not run this code because I'm not sure I've captured everything from your code.
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()
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
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)
I'm trying to play and stop a music in my main page.
It's kind of weird.
From my code,
if the user press "m", suppose, the music should be off.
However, the music didn't off. It continue
UnboundLocalError: local variable 'music_playing' referenced before assignment
Can someone help me with my code?
pickUpSound = pygame.mixer.music.load('test.mp3')
pygame.mixer.music.play(-1)
music_playing = True
def mainMenu():
main = pygame.image.load('menu.jpg')
screen.blit(main,(0,0))
while True:
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == KEYDOWN:
if event.key == ord('m'):
if music_playing:
pygame.mixer.music.stop()
else:
pygame.mixer.music.play(-1)
music_playing = not music_playing
As it is written, event.type should be simultaneously equal to KEYDOWN and pygame.K_KP_ENTERat the same time. The second should be event.key instead of event.type.
if event.key == pygame.K_KP_ENTER:
EDIT
There seems to be something wrong with the "keypad enter" key, I commented the problematic line (maybe try with another key, for example, I used K_a, and was able to start/stop by pressing "a")
import pygame
def mainMenu():
pygame.display.init()
pygame.display.set_mode([128,128])
screen = pygame.display.get_surface()
#
pygame.mixer.init()
pickUpSound = pygame.mixer.music.load('test.mp3')
pygame.mixer.music.play(-1)
music_playing = True
#
main = pygame.image.load('menu.jpg')
screen.blit(main,(0,0))
while True:
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
#if event.key == pygame.K_KP_ENTER:
if music_playing:
pygame.mixer.music.stop()
print "stopping"
else:
pygame.mixer.music.play(-1)
print "playing"
music_playing = not music_playing
mainMenu()
n.b. When running this code, I see the messages "playing" and "stopping" each time I press any key.
With if event.key == pygame.K_a: the music should start/stop by pressing "a".