How to restart my program with a button press 'r'? - python

Okay I've created Space Invaders in Python 3.7.4 and Pygame 1.9.6. I've got everything working no bugs or anything. I've even got the paused button to work great. It's just when the screen puts up 'GAME OVER' text to signify you lost. I would like to pop up a window to ask play again after the text goes away. But I just don't know where to begin at. I've looked at How do I restart a program based on user input? for help, but I couldn't understand where to implement it at or where to look at. This was my first real project/game I created in Pygame.
Code:
paused = False
running = True
while running:
# RGB = Red, Green, Blue
screen.fill((0, 0, 0))
# Background Image
screen.blit(background, (0, 0))
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_p: # Pausing
paused = True
if event.key == pygame.K_u: # Unpausing
paused = False
if not paused:
'''The rest of the code, with the movement key presses, etc.'''
Since everything above the 'while running loop' is constantly being loaded or for data retrieval like the images the coordinates for where the images should be, the background music, etc. So I wanted it to be like the pausing/unpausing part of the code when I press down on say 'r'. I want to replay the program without exiting it. So I would be very grateful for help by people. Thank you all.

You have to create function or methods in object to reset data and use it before every game. You can use external while-loop for this.
# executed only once
pygame.init()
screen = ...
# .. load data ...
player = ...
enemy = ...
gameing = True
while gameing:
# reset data before every game
player.reset()
enemy.reset()
score = 0
paused = False
running = True
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: # exit game
running = False
gameing = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r: # restart game (but don't exit)
running = False
#gameing = True
if event.key == pygame.K_x: # exit game and program
running = False
gameing = False
if game_over: # restart game (but don't exit)
running = False
#gameing = True
You can also organize it as #Starbuck5 mentioned in commen - but then you should use running to exit program but not to exit game on game over
def reset():
global score, paused, running
player.reset()
enemy.reset()
score = 0
paused = False
running = True
# executed only once
pygame.init()
screen = ...
# .. load data ...
player = ...
enemy = ...
# (re)set data before first game
reset()
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: # exit game
running = False
gameing = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r: # restart game (but don't exit)
#running = False # DON'T DO THIS
reset()
if event.key == pygame.K_x: # exit game and program
running = False
if game_over: # restart game (but don't exit)
#running = False # DON'T DO THIS
reset()
This need use global for every variable which you have to reset so it can be more useful when you have code in classes and you can use self. instead of global

Related

how should i be binding spacebar to serve my purpose?

I've been trying to figure how to set up pause and unpause function on my game that allows me to use space to pause and then unpause as well. I've been struggling mostly because I'm so new to coding. I feel like I'm not understanding the true and false or rather the binds.
The code is as follows:
import random
from tkinter import *
def paused(window):
PAUSED = False
while True:
pause(window)
canvas.create_text(canvas.winfo_width() / 2, canvas.winfo_height() / 2, font=('consolas', 70), text="PAUSED", fill="white", tag='paused')
window.keys.bind("<space>", paused)
if not paused:
paused = False
window.update()
I am assuming you are using pygame. In pygame, you can listen to pygame.event and check if the space bar has been clicked.
PAUSED = False
while True:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
PAUSED = not PAUSED # inverts PAUSED
if not PAUSED:
draw() # update
clock.tick(60)
Otherwise, you can use the keyboard module.

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.
# [...]

Pygame nested while loop: [Errno 10054] An existing connection was forcibly closed by the remote host

I am using pygame with pyscripter and pyopengl, and am trying to put a while loop inside the main while loop, but as soon as the game enters the inner loop, it repeats the loop forever and I can't get out
running = True
while running:
keys=pygame.key.get_pressed()
## do game stuff
if keys[K_l]:
a=True
while a:
keys2=pygame.key.get_pressed()
## do something
print a
if keys2[K_p]:
a = False
break
for event in pygame.event.get():
if event.type == pygame.QUIT or keys[K_ESCAPE]:
running = False
pygame.quit()
sys.exit()
After pressing l, this continuously prints True even if I press p
How can I exit the inside loop?
You need to call pygame.event.pump() inside your inner while loop to ensures that your program can internally interact with the rest of the operating system.
# ....
while a:
pygame.event.pump()
keys2 = pygame.key.get_pressed()
# do something ...
An alternative would be to listen for pygame.KEYDOWN events on the event queue in your game loop:
running = True
l_KeyPressed = False
while running:
# get events from the queue
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN :
if event.key == pygame.K_SPACE:
running = False
if event.key == pygame.K_l:
# do something
l_KeyPressed = True
if event.key == pygame.K_p and lPressed:
l_KeyPressed = False
Hope this helps :)

Pause system in pygame [duplicate]

This question already has answers here:
Why is my pause system not working in Pygame?
(2 answers)
Closed 8 years ago.
hi there i've spent hours trying to make a toggle pause in pygame that you press space and it pauses then you press space again to un-pause and i'm having no luck would any one be able to help me please?
############### 2nd attempt #############
global timedelay
timedelay = pygame.time.wait (0)
pause = 0
if event.type == KEYUP:
if event.key == K_p and pause == 0:
timedelay = pygame.time.wait (9999)
pause = 1
if event.key == K_p and pause == 0:
timedelay = pygame.time.wait (0)
pause = 0
timedelay
############### 1st attempt #############
if event.type == KEYDOWN:
pause = 0
if event.key == K_p and pause == 0:
while 1:
pause = 0
event = pygame.event.wait()
pause = 1
if event.type == KEYDOWN:
if event.key == K_p and pause == 0:
print "woo!"
pause = 0
break
Don't block your whole main loop from running, just skip the state change part of the loop. You still need to be able to respond to events or your app is "unresponsive". You also want to keep drawing as windows can be moved around and cover your game and the screen still needs to refresh. So:
game_over = False
paused = False
while not game_over:
# handle events
for event in pygame.event.get():
if event.type == KEYDOWN:
paused = False
if event.key == K_p:
paused = True
...
if not paused:
# handle game state change
# handle screen drawing
pygame.display.flip()

pygame mouse button down not working

I am making this multiple choice program, but I need the mouse event to only work after enter is pressed.
Here is my code:
for event in pygame.event.get(): # If user did something
if event.type == pygame.QUIT: # If user clicked close
done = True
elif event.type == pygame.KEYDOWN: # If user pressed a key
if event.key == pygame.K_RETURN: # If user pressed enter
# Makes the start screen go away
enter_pressed = True
# Increments question_number
question_number += 1
# Where I Draw the question screen
Then down below I have this:
for event in pygame.event.get(): # If user did something
if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
print("Derp")
Derp won't print when I press left mouse button.
However, when I have it indented like this:
for event in pygame.event.get(): # If user did something
if event.type == pygame.QUIT: # If user clicked close
done = True
elif event.type == pygame.KEYDOWN: # If user pressed a key
if event.key == pygame.K_RETURN: # If user pressed enter
# Makes the start screen go away
enter_pressed = True
# Increments question_number
question_number += 1
# Where I Draw the question screen
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
print("Derp")
Derp does print when I press left mouse button
You could use a boolean indicating wheter or not enter was pressed.
for event in pygame.event.get(): # If user did something
enter_pressed = False
if event.type == pygame.QUIT: # If user clicked close
done = True
elif event.type == pygame.KEYDOWN: # If user pressed a key
if event.key == pygame.K_RETURN: # If user pressed enter
# Makes the start screen go away
enter_pressed = True
# Increments question_number
question_number += 1
# Where I Draw the question screen
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1 and enter_pressed:
print("Derp")
I think that the problem is that you are iterating over all events, and inside that loop you are iterating over all events (again), and that causes some problems
It is hard to tell from what you said, but I have a couple of recommendations for you. First, make sure that the for loop with derp isn't in any if statements you don't want it to be in. Second, make sure you call pygame.event.get() once per game loop or the code will only give you events that happened between the two calls, which will not be all of them. If neither of these things work, try posting the whole code.

Categories