Pygame waiting the user to keypress a key - python-3.x

I am searching a method, where the program stops and waiting for a spesific key to be pressed by the user. May I can implement this one with a while loop? I need the best algorithm, if there exist a build-in function of waiting, to avoid the loop.
I found several information on the official website of pygame, but nothing help.
Here is a testing algorithms but won't work:
key = "f"
while key != "K_f":
key = pygame.key.get_pressed()
if key[Keys.K_f]:
do something...

If you are waiting for a key to be pressed you can use the event.wait() function. This is useful, because it does not require a-lot of processing.
import pygame
from pygame.locals import *
pygame.event.clear()
while True:
event = pygame.event.wait()
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key = K_f:
do something...
Note that event.wait() waits for events to appear in the event cache, the event cache should be cleared first.
pygame.event documentation

You could do it with a while loop and an event queue:
from pygame.locals import *
def wait():
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN and event.key == K_f:
return

Related

How do you break out of while loop by pressing a gamepad button (User Input)

I am using pygame just so that I can use the xbox controller on my script. My goal is to press a button to start a repeating task, and then be able to press another button to break out of the repeating task. I should then be able to press the original button to resume the task.
Before I even post the code, I know the crux of my problem is this part here: (something wrong with my indentation but the code works).
while True:
schedule.run_pending()
time.sleep(1)
How do I break out of this while loop so that I can use the next button JOYHATMOTION: Basically I would be using JOYHATMOTION to pause the job function.
Here is the code. It prints "Hello World" every five seconds for 200 seconds.
import schedule
from datetime import datetime, timedelta, time
import time
import sys
import pygame
from pygame.locals import *
pygame.init()
def job():
print('Hello World')
pygame.joystick.init()
joysticks = [pygame.joystick.Joystick(i) for i in range(pygame.joystick.get_count())]
for joystick in joysticks:
print(joystick.get_name())
while True:
for event in pygame.event.get():
if event.type == JOYBUTTONDOWN:
print(event)
if event.button == 8:
schedule.every(5).seconds.until(timedelta(seconds=200)).do(job)
while True:
schedule.run_pending()
time.sleep(1)
if event.type == JOYHATMOTION:
if event.value[0] == 1:
print(event)
if event.value[0] == -1:
print(event)
if event.type == QUIT:
pygame.quit()
sys.exit()
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
pygame.quit()
sys.exit()
I have tried:
while True:
if event.type == JOYHATMOTION:
if event.value[0] == 1:
break
else:
schedule.run_pending()
time.sleep(1)
but this dosent seem to work. Thank You in advance.
Never try to control the application with a loop inside the application loop. Use the application loop. The application loop is continuously executed. Use a game_state variable that indicates the current state of the application. Execute the code in the application depending on the state of the variable.
With this approach, you can easily change the state back when another key is pressed.
game_state = ""
run = True
while run:
for event in pygame.event.get():
if event.type == QUIT:
run = False
if event.type == KEYDOWN:
if event.key == K_ESCAPE:
run = False
if event.type == JOYBUTTONDOWN:
print(event)
if event.button == 8:
if game_state == "schedule":
game_state = "" # schedule off
else:
game_state = "schedule" # schedule on
schedule.every(5).seconds.until(timedelta(seconds=200)).do(job)
if event.type == JOYHATMOTION:
if event.value[0] == 1:
print(event)
if event.value[0] == -1:
print(event)
if game_state == "schedule":
schedule.run_pending()
# [...]
pygame.quit()
sys.exit()

Can't import any pygame functions (E1101)

When I run the following code, a white screen appears and then quickly disappears. I installed pygame on the VSCode terminal with pip3 (I am on mac) and now that I finally got it to import pygame, I get multiple errors for every function called such as "clock" or "pygame.KEYDOWN". They say "Module 'pygame' has no 'KEYDOWN' member" [E1101]. I also get an error with the "init" member.
I've seen other posts that tell me to copy and paste something into the json settings, but when I tried that I got even more errors.
#Game
#By Robert Smith
#Initialize python
import pygame
pygame.init()
#Set the screen
screen = pygame.display.set_mode((640, 480))
background = pygame.Surface(screen.get_size())
background.fill((255,255,255))
background = background.convert()
screen.blit(background, (0 , 0))
#Make the window exitable
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop == False #close the window
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
mainloop = False
#Set the framerate
milliseconds = clock.tick(60)#DO NOT GO FASTER THAN THIS FRAMERATE
Try this:
keys = pygame.key.get_pressed()
for event in pygame.event.get():
if event.type == pygame.QUIT:
mainloop == False #close the window
elif event.type == keys[pygame.K_DOWN]:
if event.key == keys[pygame.K_ESCAPE]:
mainloop = False
And this:
milliseconds = pygame.time.Clock.tick(60)

Quit function is not working in pygame

I want the system to exit when I click the "x" on the window of pygame. I want to be able to call the quit_game function whenever I need to. So if the user does quit, it actually quits. I have tried sys exit and pygame.quit(), but I haven't been able to successfully implement those. Right now I just have the quit function built into the intro screen. I am using python 3.4.3. Here is the code.
import math
import random
import time
import pygame
import sys
import glob
pygame.init()
move=0
FPS=60
blue=(0,0,255)
white=(255,255,255)
black=(0,0,0)
green=(0,155,0)
display_width=800
display_height=600
gamedisplay=pygame.display.set_mode((display_width,display_height))
pygame.display.set_caption('Stacker')
clock=pygame.time.Clock()
speed=2
smallfont=pygame.font.SysFont("Arial",int(display_width/32))
mediumfont=pygame.font.SysFont("Arial",int(display_width/16))
largefont=pygame.font.SysFont("Arial",int(display_width/10))
gamedisplay.fill(green)
block=display_height/12
pygame.display.update()
def quit_game():
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
quit()
def intro_screen():
welcome_message = mediumfont.render(str("Welcome to Stacker!!!"), True,black)
gamedisplay.blit(welcome_message,(display_width/4,display_height/40))
how_to_play_1=smallfont.render(str("Your goal is to get to the major prize bar"),True,black)
gamedisplay.blit(how_to_play_1,(display_width/3.619909502,display_height/2))
how_to_play=smallfont.render(str("Press the space bar to stop the shape"),True,black)
gamedisplay.blit(how_to_play,(display_width/3.48583878,display_height/(12/7)))
quit_game()
pygame.display.update()
def middle_block():
pygame.draw.rect(gamedisplay, blue,(display_width/(32/15),display_height-block,block,block))
pygame.display.update()
def left_block():
pygame.draw.rect(gamedisplay, blue,(display_width/(32/13),display_height-block,block,block))
pygame.display.update()
def right_block():
pygame.draw.rect(gamedisplay, blue,(display_width/(32/17),display_height-block,block,block))
pygame.display.update()
def major_screen():
major_message = mediumfont.render(str("Major Prize Here!"), True,black)
gamedisplay.blit(major_message,(display_width/(10/3),display_height/40))
pygame.display.update()
intro_screen()
pygame.time.delay(8000)
gamedisplay.fill(green)
major_screen()
pygame.draw.rect(gamedisplay, blue,(display_width-display_width,display_height/8,display_width,display_height/60))
pygame.draw.rect(gamedisplay, blue,(display_width-display_width,display_height/2.4,display_width,display_height/60))
middle_block()
left_block()
right_block()
pygame.display.update()
Your code has no main game-loop. You may thinks this:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
quit()
Is your game-loop. While that is almost correct, it is missing a key part. A while loop. Your telling Python to loop through every single event that Pygame is tracking. After it finishes looping through the events once, it stops. You want Python to continually loop through the Pygame events, until the window is closed. To do this create a variable to control your loop. Such as running = True or not_quit = True. Next wrap a while-loop around your for-loop using the control variable as your condition. Lastly, if the user closes the window, set your control variable to False.
running = True # our variable to control the loop.
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False # break the loop
pygame.quit()
sys.exit()
quit()
This should allow you to close your window. I should note however that none of the text/shapes your blitting/drawing to the screen will be visible unless inside your game-loop. So you may need to rethink your code a bit.

pygame detect which key is pressed

I'm working on a scoreboard in a game I am creating and I know how to check if a key is pressed, but is there a way to check WHICH key is pressed, make a varibale that key and then add it to a string?
EDIT: Ok, incase I was unclear: I know that I can check if buttons like h or t can be pressed, but I want a way to just instantly press a button and add that to a string, and I don't want to build an event function for every letter in the alphabet.
if event.type == pygame.KEYDOWN :
print(event.key)
You can transform the given number into ascii with :
pygame.key.name(event.key)
If you have registered a callback to detect when a key has been pressed, UNQUESTIONABLY the identity of the key will be included in the structure passed to the callback's service routine.
Whether that offers the "keyboard code" as well as the plain-Jane ASCII value of the key I cannot tell you.
If you want simple textinput (for example if the user should enter their name for the highscore), take a look at EzText library.
Generally speaking, you can check which key was pressed in two ways.
If you use the event queue, you can check the event.key against the pygame key codes:
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
print("spacebar was pressed")
if event.key == pygame.K_q:
done = True
pygame.quit()
All keycodes are listed in the documentation. This will fire one event for every keypress, regardless of how long a single key is being held down.
Alternatively, you can use state checking:
import pygame
pygame.init()
screen = pygame.display.set_mode((500, 500))
done = False
while not done:
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
state = pygame.key.get_pressed()
if state[pygame.K_SPACE]:
print("spacebar was pressed")
if state[pygame.K_q]:
done = True
pygame.quit()
Notice that this will fire many events if the key is being held down for longer. It may also miss key presses if the key is being pressed and released at a time when your program is busy doing something other than checking for key presses.
A bit late, but I think this is it:
import pygame
pygame.init()
# set screen size
screen = pygame.display.set_mode((100, 100))
# set loop flag
done = False
while not done:
# check events
for event in pygame.event.get():
# end if X was pressed
if event.type == pygame.QUIT:
done = True
# check if event was a key being pressed down
if event.type == pygame.KEYDOWN:
# end if Esc was pressed
if event.key == pygame.K_ESCAPE:
done = True
# unicode returns the char
print(event.scancode, event.key, event.unicode)
# be IDLE friendly
pygame.quit()
What you need is this:
if event.type == pygame.KEYDOWN:
print(event.key, event.unicode)
event.key show the code of an character that are pressed
event.unicode show the character that are preseed
Result would be this:
event.key: 97, event.unicode: a
event.key: 98, event.unicode: b
event.key: 99, event.unicode: c
event.key: 100, event.unicode: d
event.key: 101, event.unicode: e
event.key: 102, event.unicode: f

How to use keyboard in pygame?

I tried the simple script below, but I get no response. Maybe I don't understand what pygame is capable of doing. I simply want to assign a certain function to a certain key. Like if I press the letter 'h' I want "Bye" to print on the screen or if I press 'g' then play a certain song. And so on and so on...
import pygame
from pygame.locals import *
pygame.init()
print K_h #It prints 104
while True:
for event in pygame.event.get():
if event.type==KEYDOWN:
if event.key==K_h:
print "Bye" #Nothing is printed when I press h key
import pygame
from pygame.locals import *
pygame.init()
screen = pygame.display.set_mode((640,480))
clock = pygame.time.Clock()
while True:
clock.tick(30)
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
if event.type == KEYDOWN:
if event.key == K_h:
print "bye"
for what ever reason for me atleast it seems the event command wouldn't work with out the use of a screen even if it has no purpose this will get you the results you want.

Resources