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.
# [...]
Related
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()
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!
I'm a beginner in python and I am trying to learn the features of pygame in order to make a simple game. I want to move an image using the wasd keys, but it's not working. Please help.
I'm using python (3.7.0) on windows 10.
The following is the code:
import pygame
from pygame.locals import *
pygame.init()
pygame.display.init()
keys = [False, False, False, False]
screen=pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
background=pygame.Surface(screen.get_size())
background.fill((255,255,255))
playerpos=[100,100]
player=pygame.image.load("Copper.png")
while 1:
pygame.display.init()
screen.fill(0)
screen.blit(background,(0,0))
screen.blit(player,playerpos)
for event in pygame.event.get():
pygame.display.init()
pygame.display.flip()
if event.type == pygame.KEYDOWN:
if event.key==pygame.K_RETURN:
pygame.display.quit()
pygame.display.flip()
# 8 - loop through events
for event in pygame.event.get():
# 9 - check if event is X button
if event.type==pygame.QUIT:
# 10 - quit the game
pygame.quit()
exit(0)
if event.type == pygame.KEYDOWN:
if event.key==K_w:
keys[0]=True
elif event.key==K_a:
keys[1]=True
elif event.key==K_s:
keys[2]=True
elif event.key==K_d:
keys[3]=True
if event.type == pygame.KEYUP:
if event.key==pygame.K_w:
keys[0]=False
elif event.key==pygame.K_a:
keys[1]=False
elif event.key==pygame.K_s:
keys[2]=False
elif event.key==pygame.K_d:
keys[3]=False
# 9 - Move player
if keys[0]:
playerpos[1]-=500
elif keys[2]:
playerpos[1]+=500
if keys[1]:
playerpos[0]-=500
elif keys[3]:
playerpos[0]+=500
I expect the image "Copper.png" to move when I press w,a,s,d but the image does not move. The image does refresh everytime I press w,a,s,d but does not move.
Get rid of the multiple even handling loops. Use a single loop to handle all the events.
Further it is sufficient to init the display once (pygame.display.init())
Create a variable speed, which defines the number of pixels, the position of the image changes by each step
First evaluate the pygame.QUIT event and stop running the main loop when the event happens:
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
Then handle the other events like the pygame.KEYDOWN and pygame.KEYUP.
For a continuously movement, the manipulation of the player position has to be done outside the event loop. If it would be don in the loop, the the position of the player would only change if en event occurs. Note use a small "speed" (speed = 1), else the player would rapidly moved out of the window.
for event in pygame.event.get():
# event handling
if keys[0]:
playerpos[1]-=speed
elif keys[2]:
playerpos[1]+=speed
if keys[1]:
playerpos[0]-=speed
elif keys[3]:
playerpos[0]+=speed
Do the drawing of the scene at the end of main loop:
speed = 1
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key==pygame.K_RETURN:
done = True
for i in range(4):
if event.key == (K_w, K_a, K_s, K_d)[i]:
keys[i]=True
elif event.type == pygame.KEYUP:
for i in range(4):
if event.key == (K_w, K_a, K_s, K_d)[i]:
keys[i]=False
if keys[0]:
playerpos[1]-=speed
elif keys[2]:
playerpos[1]+=speed
if keys[1]:
playerpos[0]-=speed
elif keys[3]:
playerpos[0]+=speed
screen.fill(0)
screen.blit(background,(0,0))
screen.blit(player,playerpos)
pygame.display.flip()
Note, alternatively you can use pygame.key.get_pressed() to get all states of of all keyboard buttons at once. So you don't need to evaluate the key events separately:
speed = 1
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RETURN:
done = True
allKeys = pygame.key.get_pressed()
playerpos[0] += -speed if allKeys[K_a] else speed if allKeys[K_d] else 0
playerpos[1] += -speed if allKeys[K_w] else speed if allKeys[K_s] else 0
screen.fill(0)
screen.blit(background,(0,0))
screen.blit(player,playerpos)
pygame.display.flip()
I'm creating my first Python game ever, and I tried to do pause/unpause game function. I have created a global pause variable which is set to false by declaration. But when i press press button assigned to my pause function the programs gives me this error:
local variable 'pause' referenced before assignment
Here's paused() function assignment to a button:
if event.key == pygame.K_p:
pause = True
paused()
And here's my paused() function:
def paused():
while pause:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
pause = False
pygame.display.update()
clock.tick(15)
#gameDisplay.fill(white) `
pause is a local variable of your main, so sending it to the function is necessarry. Also, there were some identation errors. Here is the fixed version:
if event.key == pygame.K_p:
pause = True
paused(pause)
def paused(pause):
while pause:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_m:
pause = False
pygame.display.update()
clock.tick(15)
#gameDisplay.fill(white) `
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)