How to create skip functionality pygame? [duplicate] - python

This question already has an answer here:
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed 2 years ago.
I'm trying to create a way in pygame for the player to skip the tutorial phase simply by pressing "escape". However, I can't seem to get it to work when using the following:
for event in pygame.event.get():
if event.type == pygame.K_ESCAPE:
brek2 = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
run2 = False
brek = True
if brek or brek2:
break
pygame.time.delay(1000)
if brek:
break
Here's the full loop of the tutorial phase if you need it:
while run2:
# intro sequence
pygame.event.pump()
fade(screen_width, screen_height, BLACK)
fade(screen_width, screen_height, WHITE)
techi = pygame.transform.scale(pygame.image.load("Techi-Joe.gif"), (75, 75))
bg = pygame.Surface((screen_width, screen_height))
bg.fill(WHITE)
win.blit(pygame.transform.scale(bg, (screen_width, screen_height)), (0, 0))
win.blit(techi, (100, 600))
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
run2 = False
pygame.time.delay(1000)
brek2 = False
presss = 1
brek = False
techi_bubble = pygame.transform.scale(pygame.image.load("techi_speech_bubble.png"), (700, 350))
techi_font = pygame.font.Font('Consolas.ttf', 25)
for a in range(len(techi_says)):
win.blit(pygame.transform.scale(bg, (screen_width, screen_height)), (0, 0))
win.blit(techi_bubble, (175, 300))
win.blit(techi, (100, 600))
writeLikeCode(techi_says[a], 235, 350, techi_font, 20)
for event in pygame.event.get():
if event.type == pygame.K_ESCAPE:
brek2 = True
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
run2 = False
brek = True
if brek or brek2:
break
pygame.time.delay(1000)
if brek:
break
Here's some addition code referenced as function writeLikeCode:
techi_says = ["Hello, User!", "My name is Techi-Joe.", "I'm a programmer,", "and this is my first game:",
"Dunk the Chief!", "in Dunk the Chief,", "your main objective", "is to dunk any US president", "you choose",
"in a cold tub of water!", "yay!"]
# writeLikeCode function
def writeLikeCode(string, xpos, ypos, font, fontsize):
for x in range(len(string)):
lstring = split(string)
text = font.render(lstring[x], 1, GREEN)
win.blit(text, (xpos + (x * fontsize), ypos))
pygame.time.delay(50)
pygame.display.update()
and here's the split function:
def split(string):
return [char for char in string]

pygame.event.get() does not only get the events, It also removes the events from the event queue. If you call pygame.event.get() twice in a row, then the first call will retrieve the events, but the 2nd call returns an empty list.
for event in pygame.event.get(): # returns the list of events
# [...]
for event in pygame.event.get(): # returns empty list
# [...]
If the event occurs after between the 2 calls of pygame.event.get(), then the event will be received be the 2nd call. But that will be a rare case.
pygame.K_ESCAPE is not an event type (see pygame.event), it is a key see (pygame.key).
If you want to detect if the ESC was pressed, then you have to detect the KEYDOWN event and to evaluate if the .key attribute is K_ESCAPE. e.g:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
run2 = False
brek = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
brek2 = True

Related

Making a pause screen

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.

how do i make a window quit in pygame?

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()

Quit Algorithm pygame Not working properly [duplicate]

This question already has an answer here:
Faster version of 'pygame.event.get()'. Why are events being missed and why are the events delayed?
(1 answer)
Closed 2 years ago.
In this I want the program to close when they hit the quit button but if I enable my Check_Key_Press() function, the Close() function does not work however If I comment out the Check_Key_Press() function then it works again.
import pygame
pygame.init()
width, height = 500,500
win = pygame.display.set_mode((width, height))
pygame.display.set_caption("Tic Tac Toe(GUI)")
clock = pygame.time.Clock()
white = (255,255,255)
red = (255,0,0)
green = (0,255,0)
blue = (0,0,255)
Tile_dime = 59
Diff = (Tile_dime+1)/2
board_det = [['-',(width/2-3*Diff,height/2-3*Diff)],['-',(width/2-Diff,height/2-3*Diff)],['-',(width/2+Diff,height/2-3*Diff)],
['-',(width/2-3*Diff,height/2-Diff)],['-',(width/2-Diff,height/2-Diff)],['-',(width/2+Diff,height/2-Diff)],
['-',(width/2-3*Diff,height/2+Diff)],['-',(width/2-Diff,height/2+Diff)],['-',(width/2+Diff,height/2+Diff)]]
def draw_board():
for i in range(len(board_det)):
pygame.draw.rect(win, white, [board_det[i][1], (Tile_dime, Tile_dime)])
def Close():
global run
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
def Check_Key_Press():
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
pass
if event.key == pygame.K_LEFT:
pass
run = True
while run:
clock.tick(60)
draw_board()
Check_Key_Press()
Close()
pygame.display.update()
pygame.event.get() get all the messages and remove them from the queue. If pygame.event.get () is called in multiple event loops, only one loop receives the events, but never all loops receive all events. As a result, some events appear to be missed.
Get the events once and use them in multiple loops or pass the list or events to functions and methods where they are handled:
def Close(event_list):
global run
for event in event_list:
if event.type == pygame.QUIT:
run = False
def Check_Key_Press(event_list):
for event in event_list:
if event.type == pygame.KEYDOWN:
pass
if event.key == pygame.K_LEFT:
pass
run = True
while run:
clock.tick(60)
event_list = pygame.event.get()
draw_board()
Check_Key_Press(event_list)
Close(event_list)
pygame.display.update()

Why does my pygame show not responding after a few seconds?

Just to clarify, I have absolutely no idea what I'm doing, in fact I'm really not sure how I got this far. I wrote a bit of code to act as an auto clicker for a Minecraft farm (yes, I'm aware you can use much simpler methods). I've taken bits and pieces from various tutorials and have done some by myself. It is a bit of a mess. However, once the code runs and does the first click the pygame window shows not responding. I have no idea why. I would appreciate any advice and tips and it would be great if I could bet this problem fixed, thanks!
I think some of the code was messed up from me not knowing how to use this very well :(
import pygame
import keyboard
import time
import pyautogui
pygame.init()
def Click():
pyautogui.doubleClick(None, None, 1)
print('Click')
time.sleep(3)
def Img(x, y):
display_surface.blit(Piglin_Img, (x, y))
white = (255, 255, 255)
black = (0, 0, 0)
x = 280
y = 10
X = 400
Y = 100
Piglin_Img = pygame.image.load('Piglin.png')
pygame.display.set_icon(pygame.image.load("Icon.png"))
display_surface = pygame.display.set_mode((X, Y ))
pygame.display.set_caption('Gold Farm Auto Clicker')
font = pygame.font.Font('freesansbold.ttf', 20)
Start_Text = font.render('Press p to start...', True, black, white)
Run_Text = font.render('Running...', True, black, white)
Pause_Text = font.render('Paused', True, black, white)
Start_Text_pos = (10, 10)
Run_Text_pos = (10, 10)
Pause_Text_pos = (10, 10)
Continue_pos = (10, 40)
display_surface.fill(white)
display_surface.blit(Start_Text, Start_Text_pos)
Clicker = False
running = True
while running:
for event in pygame.event.get():
Img(x, y)
pygame.event.set_blocked(pygame.MOUSEMOTION)
pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
pygame.event.set_blocked(pygame.MOUSEBUTTONUP)
if event.type == pygame.QUIT or \
event.type == pygame.KEYDOWN and \
event.key == pygame.K_z:
running = False
if event.type == pygame.KEYDOWN and \
event.key == pygame.K_p:
print('started')
display_surface.fill(white)
display_surface.blit(Run_Text, Run_Text_pos)
Img(x, y)
pygame.display.update()
Clicker = True
while Clicker:
if event.type == pygame.KEYDOWN and \
event.key == pygame.K_x:
Clicker = False
display_surface.fill(white)
display_surface.blit(Start_Text, Continue_pos)
display_surface.blit(Pause_Text, Pause_Text_pos)
Img(x, y)
pygame.display.update()
Click()
if event.type == pygame.KEYDOWN and \
event.key == pygame.K_x:
Clicker = False
display_surface.fill(white)
display_surface.blit(Start_Text, Continue_pos)
display_surface.blit(Pause_Text, Pause_Text_pos)
Img(x, y)
pygame.display.update()
pygame.display.update()
pygame.quit()
It's blocking the event queue processing when Clicker becomes True. So once clicker starts looping, no user-input is handled as this loop never re-examines the queue for new events, and just continues to re-process the same (old) event result.
You probably need to merge the event handling in the while Clicker cause into the main event loop. Maybe with an if Clicker on those events:
pygame.event.set_blocked(pygame.MOUSEMOTION)
pygame.event.set_blocked(pygame.MOUSEBUTTONDOWN)
pygame.event.set_blocked(pygame.MOUSEBUTTONUP)
while running:
# handle events and user interaction
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN : # some key was pushed
if event.key == pygame.K_p:
print('started')
Clicker = True # start the clicker
elif event.key == pygame.K_x:
print('stopped')
Clicker = False # stop the clicker
elif event.key == pygame.K_z:
running = False # Allow exit here too
# Update the screen
if Clicker:
# Click mode
display_surface.fill(white)
display_surface.blit(Run_Text, Run_Text_pos)
else:
# NOT in Click Mode
display_surface.fill(white)
display_surface.blit(Start_Text, Continue_pos)
display_surface.blit(Pause_Text, Pause_Text_pos)
Img(x, y)
pygame.display.update()
Something close to that anyway. Without comments, it's not immediately clear what the intention of the code is, so it's hard to create an exacting solution.

Pygame error: pygame.error: display Surface quit

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!

Categories

Resources